🎨 react-colorful — 1,8 KB color picker for React. Fast, dependency-free, customizable, and accessible
Vlad Shilov
Posted on October 13, 2020
📆 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.
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:
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 🙏