๐ The Story
Several months ago I was searching for an open-source color picker component to use in my React project.
I spent a lot of time looking for a good package and noticed that the most popular React color picker, react-color
, is 140 KB (far larger than the entirety ofย react-dom
), is not tree-shakeable, is not accessible, does not support keyboard navigation, pulls in 11 dependencies, and is not as fast as it could be.
Despite this,ย react-color
ย is super popular and has 1,7 million downloads weekly. One of the largest reasons for this is there were no lighter alternatives aligned with modern requirements.
So we decided to create one. The primary goal was to create a modern color picker component that would be 10+ times lighter thanย react-color
.
Ryan Christian,ย Alex Taktarov, and I had been working hard since July to create the tiniest and fastest color picker for the React community.
๐ That's howย react-colorful
ย was born!
Demo:
https://omgovich.github.io/react-colorful
Docs:
https://github.com/omgovich/react-colorful
The current version ofย react-colorful
ย (v4.1) is 18 times lighter thanย react-color
. It's just 1,8 KB!
๐ How isย react-colorful
ย so small and fast?
1. No dependencies
While most of the popular pickers import entire color manipulation libraries that cost more than 10 KB,ย react-colorful
ย ships only a minimal amount of manually optimized color conversion algorithms.
For example,ย react-color
ย pulls in 11 dependencies includingย tinycolor2
ย that costs 14,4 KB and doesn't support tree-shaking at all.
We have spent a lot of time making react-colorful
dependency-free to ensure it is the lightest of the competition. Not to mention that this thoroughly reduces the surface for vulnerability issues to arise.
2. No classes
ES6 classes are good when you need to encapsulate something, but if you want to create a tiny JS library then class declarations will be one of your worst enemies. Current minifiers cannot minify ES6 class fields and member functions because they are not able to track the class when a method is called on an object.
That's why react-colorful
is built with functions, functional components, and hooks only.
It's also one of the reasons why our picker is so fast.
3. No polyfills and extra code transforms
We aim to support not only modern browsers but legacy ones as well. So we have Babel configured to make our code compatible even with IE11.
Writing a library using modern language features such as async/await
often trades end user experience for source developer experience. While these modern features may be nicer and more terse to write, they often result in much larger statements when transpiled for use in older browsers.
That's why our source code is so humble in terms of modern ECMAScript features. For example, we use Object.assign({}, color, { alpha })
instead of { ...color, alpha }
. While yes, the source uses the older and more verbose API, this results in the bundle size being ~150 bytes lighter due to the lack of the polyfill.
4. Manually optimized
We have installed size-limit and tried many, many different things to find the smallest (in terms of bundle size) variation for each part of the library.
It's pretty hard to put into words, so I just share an example with you:
We have a simple function that clamps a value between an upper and lower bound. That's the first version of this function:
export const clamp = (number, min = 0, max = 1) => {
return Math.min(Math.max(number, min), max);
};
But after a few experiments we have replaced it with:
export const clamp = (number, min = 0, max = 1) => {
return number > max ? max : number < min ? min : number;
};
Your eyes do not deceive you: we chose the option that is longer. Why? Because the minification makes the second code almost 2 times shorter. See:
Math.min(Math.max(n,i),a)
n>a?a:n<i?i:n
โค๏ธ Thanks for reading
react-colorful cares about size, performance, and accessibility. I hope that the React community shares our values and will find it useful for further projects.
It will help us a lot if you star the repo on GitHub or share the link to this article with your friends ๐
omgovich / react-colorful
๐จ A tiny (2,8 KB) color picker component for React and Preact apps
Features
- ๐ Small: Just 2,8 KB gzipped (13x lighter than react-color).
- ๐ณ Tree-shakeable: Only the parts you use will be imported into your app's bundle.
- ๐ Fast: Built with hooks and functional components only.
- ๐ก Bulletproof: Written in strict TypeScript and has 100% test coverage.
- ๐ Typed: Ships with types included
- ๐ Simple: The interface is straightforward and easy to use.
- ๐ซ Cross-browser: Works out-of-the-box for most browsers, regardless of version.
- ๐ฒ Mobile-friendly: Supports mobile devices and touch screens.
- ๐ฌ Accessible: Follows the WAI-ARIA guidelines to support users of assistive technologies.
- ๐จ No dependencies
Top comments (12)
Nice Vlad ๐
We are having a discussion about the future of our color Web Component picker and I really like how you managed to put everything in place.
It can be a source of inspiration for our discussion, so, thank you for the share and work!
If you're looking for a web components based solution you should definitely check vanilla-colorful. It has all the benefits of react-colorful. The only thing you need to be aware of is that vanilla-colorful doesn't support IE11 or Edge 12โ18.
Not looking for another solution currently and our project, but who knows in the future. Thx for pointing this out and again for the inspiration ๐
I am dreaming about writing code supporting donkey 11
Worth checking out github.com/web-padawan/vanilla-col...
twitter.com/serhiikulykov/status/1...
We also need some more features such as keeping an history of what users selected for colors in our editor and others stuffs, not to mention that we tend to try to be as much agnostic as possible but, that being said, definitely cool stuffs ๐
Thanks for pointing this out, if it is not for this project, it is worth to know what cool libs exist out there for another one ๐
Cool , I'll need it soon !
That's a good initiative and there are still many components that need that update too.
Thanks!
If you know any other "heavy" popular open-source component, let me know. I would be glad to work on a lightweight version of it.
github.com/daybrush/moveable
Sometimes it's a good solution because the native browser color pickers suck!
Great library. I definitely use it someday
Thanks! Glad you like it)