🎨 react-colorful — 1,8 KB color picker for React. Fast, dependency-free, customizable, and accessible
Tags: showdev, react, javascript, a11y
Published: 2020-10-13 08:27:09

## 📆 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](https://github.com/rschristian), [Alex Taktarov](https://github.com/molefrog), 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`](https://omgovich.github.io/react-colorful) was born!

**Demo:**
[https://omgovich.github.io/react-colorful](https://omgovich.github.io/react-colorful)

**Docs:**
[https://github.com/omgovich/react-colorful](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](https://github.com/ai/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:

```js
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:

```js
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:

```js
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 🙏

{% github omgovich/react-colorful %}