react-colorful: three weights for one component, and two tag conventions in three releases
🎨 A tiny (2,8 KB) color picker component for React and Preact apps
At a glance
- What is it?
- A dependency-free colour picker for React and Preact whose whole pitch is measured weight, which makes the three different weights it quotes for itself unusually interesting. Its manifest is one patch ahead of its newest tag, the tags disagree about a prefix, the count of extra pickers does not match the table, and the package's exports map points at a file that only exists after a build step renames a copy.
- Who is it for?
- This is the picker to reach for when a colour input has to live inside a design system that already styles its own components, because the entire theming contract is a set of documented class names and there is no runtime theming layer to carry. Two things to know before you ship it.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 38 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 9, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Three weights are quoted for the same component
The pitch is weight, and the numbers are everywhere. The repository description says the picker is about two point eight kilobytes:
npm install react-colorfulThe feature list says just over three kilobytes gzipped, and twelve times lighter than the library it positions itself against. The package manifest's own description repeats the larger figure. And the build configuration enforces a budget per exported picker, with the first entry set at three point one five kilobytes and measured by importing one named export from the shared bundle. So there are three numbers in circulation and one of them is the one the build fails on. The measurement itself is the interesting part: every entry imports from the same file and differs only in which export it pulls, which is how one bundle can hold fourteen pickers and still be budgeted per picker.
The manifest is a patch ahead of the newest tag
The version in the package manifest is five point eight point one. The newest release tag is five point eight point, whose title describes it as shadow document support. So the published version and the released version are different numbers, and the repository publishes releases manually rather than deriving them from the manifest. The tags disagree among themselves too: two of the three newest carry a leading letter and one does not, which is enough to break a script that constructs a tag name. The release titles are more useful than the numbers, because each says what the release was for: one added shadow document support, one added the end-of-change callback, and one added support for a newer major version of the framework.
The end-of-change callback exists because the cheap one fires on every keypress
There are three props and two of them are callbacks, and the README is explicit about why both are needed. The change callback fires continuously, during dragging and on every key press. The end callback fires when the user is finished, on mouse up, touch end or key up. The paragraph introducing it gives the reason plainly: it is for undo, saving to a database, or any other expensive operation you do not want to run on every intermediate value. That is a small API decision with a large design consequence, because it means the component tracks gesture and keyboard boundaries itself rather than making every consumer write that logic.
Twelve extra pickers are promised and the table lists fourteen components
The colour model section opens by saying there are twelve additional picker components for different models, and the table underneath has fourteen rows. The models themselves are the interesting part, because they come in pairs of shape: three families, each with a plain version, an alpha version and two string versions, plus the hexadecimal picker with its own alpha variant. The value examples show that the string and object forms are genuinely interchangeable, so a consumer can accept whichever representation their state already holds. The counting slip does not affect anything, but it is the kind of thing that makes a reader doubt the rest of the numbers in the file.
Theming is a set of class names, not a set of props
There is no theming API, and the README does not pretend there is one. The documented approach is to write another stylesheet that overrides the defaults, using four documented class names: one for the container, one for the saturation area, one for the hue bar and one for the pointer. Every picker also accepts whatever a plain div accepts, so class names and inline styles both work. That design is why the bundle can be so small: there is no runtime theming code, only markup with stable names. It also means those names are a public contract, which is worth remembering before you rely on them in a design system that will outlive this version.
A typed input component arrived in an early version with two switches
The README admits a gap immediately: the picker has no text field. Then it explains the philosophy, that this is a modular library and you can build the picker you need, and points at a companion component added in an early version specifically to pair with it. That component takes two properties. One allows the alpha forms of hexadecimal, and the other controls whether the hash prefix is displayed, both off by default. The paragraph after the table, which would presumably cover the default value styling, is cut off in the visible text. So the input exists, it is documented, and the sentence explaining its last detail is missing.
The exports map points at a file the build creates afterwards
The package manifest is belt and braces. It has the usual source, main, module and types fields, plus two custom ones for an ES module build and a universal module build, and then a proper exports map on top, which in modern terms makes most of the older fields redundant. The map resolves types first, then a universal build, then two different files depending on whether the consumer imports or requires, with a fallback. Two of those targets do not exist when the bundler runs. The build produces a module file, and a step after the build copies that file to a second name with its source map, and it is the renamed copy that the exports map hands to importers. It works, and it is the kind of arrangement where a change to the build's output name silently breaks resolution.
The classic JSX runtime, inline styles, and a manual two-step publish
Three build details matter for a component you intend to drop into someone else's application. The build passes an explicit JSX factory argument, which means the component is compiled against the classic runtime rather than the automatic one, so consumers on the newest major version of the framework may need the extra setting that shims the difference. Styles are compiled inline into the bundle rather than shipped as a separate stylesheet. And publishing is a two-step manual sequence: one script builds, one script publishes, with a separate dry-run script between them for checking the release. The test and type commands are equally direct, one runner with coverage and one compiler in no-emit mode.
Editorial conclusion
This is the picker to reach for when a colour input has to live inside a design system that already styles its own components, because the entire theming contract is a set of documented class names and there is no runtime theming layer to carry. Two things to know before you ship it. The size numbers quoted in the README, the repository description and the build budget are three different figures, so take the enforced budget as the real one. And the class names are the API, so a rename between minor versions would be a breaking change for your stylesheet even though nothing about the component changed.
Frequently asked questions
what is react colorful
A tiny colour picker component for React and Preact applications, written in TypeScript with no dependencies, shipped with types, and described as following accessibility guidelines, working across browsers and touch screens, and being tree-shakeable so only the parts you import reach your bundle.
How do I install react-colorful?
One command installs the package, then you import the picker for the colour model your state holds and pass it a colour value and a change callback. There is no peer setup to configure and no dependency to install alongside it.
react color vs react colorful
The README compares itself to react-color on one measure only, weight: it states its own bundle is about twelve times lighter, quoting just over three kilobytes gzipped. It makes no comparison on features, maintenance or compatibility.
Does react-colorful include a text input for typing a color?
Not in the picker itself, which the README says deliberately excludes. A companion component added in version 2.1 works alongside it, with two switches: one allowing the alpha hexadecimal formats and one controlling whether the hash prefix is displayed, both off by default.
How do I style react-colorful?
By class names rather than props. The documented approach is to write your own stylesheet overriding four default class names for the container, the saturation area, the hue bar and the pointer, and every picker also accepts whatever a plain div accepts, including class names, inline styles and accessibility attributes.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/omgovich-react-colorful)