Open-source project
uiwjs/react-color avatar
uiwjs/react-color

react-color: a small colour picker widget for React apps

🎨 Is a tiny color picker widget component for React apps.

572 stars127 forksTypeScriptMIT

At a glance

What is it?
react-color is a React component that puts a colour picker in a form, published as @uiw/react-color from a lerna monorepo that also builds a standalone web bundle with ncc. It is a UI widget rather than a colour library, it ships no colour maths of its own, and the README in the repository is mostly sponsorship rather than documentation.
Who is it for?
react-color fits a React form that needs a colour input without a colour library, particularly where the native browser control is too plain for the design and a full design system would be overkill.
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 152 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 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A picker widget rather than a colour library

The repository description calls react-color a tiny color picker widget component for React apps, and that word widget does a lot of work. It is a component you drop into a form so a user can pick a colour, and it is not a library for colour maths, conversion or accessibility contrast.

The topic list on the repository shows the design space the package covers. Alongside the obvious color, color-picker and react-color entries, there are hex, rgba and rgba-color, and then the interface patterns: slider, sketch, chrome, material and material-color. Those names correspond to the picker variants the package is known for, which is the reason a project would reach for it rather than writing a saturation and brightness square from scratch.

The primary language is TypeScript, the licence is MIT, and the default branch is main. The documentation site is uiwjs.github.io/react-color, and the repository itself carries a website directory as well as the packages, so the docs are built from the same tree.

That framing matters when you evaluate it. A picker is a UI problem with a lot of small decisions in it, which is exactly the kind of thing a shared component saves you from redoing. It is not the place to look for a colour model, a naming system or a token pipeline.

The repository is a lerna monorepo, not one package

The top-level entries tell you the shape of the project: a packages directory, a website directory, a test directory, lerna.json, a package.json marked private, a renovate.json, a .prettierrc with a .prettierignore, a .husky directory and a .github directory.

The package.json at the root is private, which is what you expect in a monorepo root, and the scripts address individual packages by scope. The scopes that appear are @uiw/react-color, @uiw/react-color-block and @uiw/react-alpha, and the wildcard @uiw/* covers the rest. So the colour picker you install as @uiw/react-color is one member of a family, and the repository is not a single package.

That arrangement has a practical consequence for adoption. If you only want the picker, you still get a dependency on one published package, but the repository you read for source is three or more packages with their own version lines, and the tag you see on the repository covers all of them.

The private root also means the root package.json is not something you install. It is the place where the build, test and release commands live, and every script in it operates across the scopes with lerna exec.

Two build paths: tsbb for the library, ncc for the web bundle

The build scripts show two separate toolchains serving two different outputs, and it is worth knowing which is which before you run anything.

The library build uses tsbb, the TypeScript build tool, across every package:

json
    "build": "lerna exec --scope @uiw/* -- tsbb build \"src/*.{ts,tsx}\" --use-babel --cjs cjs",
    "start": "lerna exec --scope website -- npm run start",
    "doc": "lerna exec --scope website -- npm run build",
    "type-check": "lerna exec \"tsc --noEmit\" --scope @uiw/* --stream",
    "test": "tsbb test --env=jsdom",

The Babel and CommonJS flags are what make the output usable in the wide range of setups that consume React components, and the type-check script runs tsc with no emit across the same scope with output streamed rather than buffered.

The separate web bundle uses ncc, and it targets only the colour package:

json
    "bundle": "lerna exec \"ncc build src/index.tsx --target web --filename color\" --scope @uiw/react-color",

So there is a standalone browser build of the picker, produced as a file named color, and a watch mode for it, plus a minified variant. The web target for ncc is what makes the bundle usable from a script tag as well as from a bundler.

There is also a separate documentation site in the same repository, with a start script for local development and a doc script that builds it, which is how the documentation at uiwjs.github.io/react-color is produced.

Tests run in jsdom and coverage is enforced with bail

The test setup is short and it tells you what kind of component this is. The test script runs tsbb test with the jsdom environment, and the coverage script adds coverage with bail:

json
    "coverage": "tsbb test --coverage --bail",

jsdom is the right choice here and it is also the limitation. A colour picker is a drag-and-drop and pointer-interaction component, and jsdom does not implement layout, painting or real pointer events, so what the test suite can verify is the component's behaviour in terms of state and callbacks rather than how it looks or how it feels under a finger. A test that asserts the picker emits the right hex value on a drag is meaningful; a test that asserts the swatch is the right size is not.

The bail flag on the coverage run is the more opinionated choice, because it stops the run at the first failure rather than collecting the rest. That is the behaviour you want in a pre-publish script where a coverage regression should stop the release, and it is the wrong behaviour for a local watch loop where you want to see every failure at once.

Formatting is handled by prettier across JavaScript, JSX, TSX, TypeScript, less, markdown and JSON, and the lint-staged configuration runs prettier on the same file patterns at commit time through the husky hooks.

Releases are cut from the monorepo root, one package at a time

The publish and version scripts show how a multi-package repository puts a version on the wire.

json
    "publish": "lerna publish from-package --yes --no-verify-access",
    "version": "lerna version --exact --force-publish --no-push --no-git-tag-version",

from-package publishes the versions recorded in each package's own manifest rather than bumping them at publish time, and the version command uses --exact with --force-publish so that every package is republished rather than only the ones that changed, which is how a monorepo keeps the published set in step. The --no-push and --no-git-tag-version flags mean the tagging is handled elsewhere, and --no-verify-access skips the registry check that can fail in CI.

The dependency updates are handled by renovate.json, and the release line has been moving on patch versions. The recent tags are v2.10.3 from 2026-05-24, v2.10.2 from 2026-05-21 and v2.10.1 from 2026-04-08. The last push to the repository was on 2026-05-24, the same day as the v2.10.3 tag.

The root manifest also records the licence, and it is MIT:

json
  "license": "MIT",

One practical note for a consumer. The published package name carries the @uiw scope, so the import is @uiw/react-color rather than react-color, and the repository name and the installed package name are not the same string. That trips people up the first time they install it.

The README documents the sponsor, not the component

The README in this repository is worth reading for what it is. Almost all of it is a sponsorship section: a header thanking a sponsor, an app link, and then a long list of the maintainer's other applications, each one an App Store link with an icon image.

None of that is documentation of the colour picker. There is no usage example, no prop table, no mention of the picker variants the topic list implies, and no note about how the component handles controlled versus uncontrolled values.

The documentation therefore lives elsewhere. The homepage at uiwjs.github.io/react-color is the place to look for the API, and it is built from the website directory in this repository, so the source of the docs is the same tree you would clone. The packages directory holds the implementation, and the test directory holds the suite the test script runs.

That arrangement is common in projects whose README leads with funding rather than with a quick start, and it is not a criticism so much as a navigation note. If you are evaluating the component, go to the documentation site rather than the repository landing page, and if you are reading the source, the type definitions in the package are the most concise description of the props you get.

The repository also carries a .github directory, which is where the release workflow and the CI configuration live, and a .husky directory for the commit hooks that run the formatter on staged files.

Editorial conclusion

react-color fits a React form that needs a colour input without a colour library, particularly where the native browser control is too plain for the design and a full design system would be overkill. It is the wrong choice if you need colour parsing, contrast checking or a palette engine, because this package is a picker widget and does not carry that machinery, and it is the wrong choice if you need a maintained release train, since the last tagged version v2.10.3 dates from 2026-05-24 and the last push was the same day. Verify first which of the monorepo packages you actually want, since the repository publishes several under the @uiw scope, and check the version you install against the peer React version your app uses.

Frequently asked questions

What is react-color?

It is a tiny color picker widget component for React apps, written in TypeScript and released under the MIT licence. It is a UI component rather than a colour library, and it is published under the @uiw scope as @uiw/react-color.

How is the react-color repository structured?

It is a lerna monorepo with a packages directory holding several packages under the @uiw scope, including @uiw/react-color, @uiw/react-color-block and @uiw/react-alpha, plus a website directory for the documentation and a test directory. The root package.json is marked private and holds the build, test and release scripts.

How do I build and test react-color locally?

The build script runs tsbb build across the @uiw scope, the type-check script runs tsc with no emit, and the test script runs tsbb test with the jsdom environment. A coverage run with bail is also defined, and the documentation site has its own start and doc scripts.

Does react-color ship a standalone browser bundle?

Yes. A separate bundle script uses ncc to build src/index.tsx with the web target and a filename of color, scoped to @uiw/react-color, and there are watch and minified variants of it alongside the tsbb library build.

What is the latest react-color release?

The recent tags are v2.10.3 from 2026-05-24, v2.10.2 from 2026-05-21 and v2.10.1 from 2026-04-08, and the last push to the repository was on 2026-05-24. The licence is MIT and the documentation is at uiwjs.github.io/react-color.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. uiwjs/react-color on GitHub
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/uiwjs-react-color.svg)](https://hysenlabs.com/projects/uiwjs-react-color)

Was this useful?