🎨 react-colorful — 1,8 KB color picker for React. Fast, dependency-free, customizable, and accessible

omgovich

Vlad Shilov

Posted on October 13, 2020

🎨 react-colorful — 1,8 KB color picker for React. Fast, dependency-free, customizable, and accessible

📆 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 ChristianAlex 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);
};
Enter fullscreen mode Exit fullscreen mode

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;
};
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

❤️ 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 🙏

GitHub logo omgovich / react-colorful

🎨 A tiny (2,8 KB) color picker component for React and Preact apps

react-colorful is a tiny 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

Live demos

Table of Contents





💖 💪 🙅 🚩
omgovich
Vlad Shilov

Posted on October 13, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related