mrkeyoor.com_
Wed 23 Sept 00:34 UTC
npmWeb Frontendupdated 22 Sept 2026

react-colorful review

Our esbuild browser run put the full react-colorful 5.8.0 namespace at 22.9 KB minified and 7.8 KB gzipped. The package supplies React and Preact sliders for HEX, RGB, HSL, and HSV, including alpha variants and either string or channel-object values. HexColorInput is a separate export. Your application still provides the label, text-field styling, popover, swatches, validation message, and form connection. Version 5.8.1 fixes an alpha-slider bug that could turn RGB 200, 120, 35 into 199, 119, 34 even though the user changed only opacity; the component API stayed the same.

Verdict

Our install of react-colorful 5.8.0 completed in 1.3 seconds with 0 audit findings, and the full browser namespace measured 7.8 KB gzipped. Use 5.8.1 when a React or Preact screen can own the field shell; pass if the requirement is CSS Color 4 editing or a finished popover control.

We installed it

Lab card: what happened when we installed react-colorfulScreenshot of react-colorful documentation
Install✓ · 1.3s4 packages on disk · 8 MB
ImportESM import works · require() works · CommonJS package with exports map
Browser7.8 KBgzipped (22.9 KB minified), bundled with esbuild
TypesTypeScript types bundled
Known vulns00 critical · 0 high · 0 moderate · 0 low (npm audit)

Answers from our run

Does react-colorful install cleanly?

Yes. In a fresh container with an empty cache, npm install react-colorful finished in 1 seconds, leaving 4 packages and 8 MB on disk. npm audit reported no known vulnerabilities.

How much does react-colorful add to a browser bundle?

7.8 KB gzipped (22.9 KB minified) when the whole package is bundled for the browser with esbuild. Importing only part of it is usually smaller.

Does react-colorful work with both ESM and CommonJS?

Yes. Both import 'react-colorful' and require('react-colorful') worked in Node 22 in our run. The package is published as CommonJS with an exports map.

Does react-colorful include TypeScript types?

Yes, type declarations ship inside the package, so no @types install is needed.

react-colorful or react-color: which should you use?

react-color: Pick react-color 2.19.3 when named Sketch, Photoshop, and Chrome-style picker layouts are more useful than a bare field primitive. Our install of react-colorful 5.8.0 completed in 1.3 seconds with 0 audit findings, and the full browser namespace measured 7.8 KB gzipped.

When should you not use react-colorful?

Your product edits OKLCH, Lab, LCH, HWB, or wide-gamut color; the exported picker types cover only HEX, RGB, HSL, and HSV families

API stability5/5The documented 5.x picker contract remains a color value plus onChange, with div attributes accepted on the outer element. Version 5.7 added the optional onChangeEnd callback instead of replacing the existing change path. Version 5.8 moved style placement according to the mount root, and 5.8.1 changed only conversion precision while keeping emitted formats intact. The published exports map still names separate import and require entries, and both paths opened in our Node 22 test.
Docs4/5The README maps 14 picker exports to concrete string or object values, then documents onChangeEnd, overridable class names, HexColorInput flags, Preact aliases, keyboard use, touch support, and the IE11 polyfill. Its linked demos cover swatches, popovers, arbitrary input parsing, custom layout, and delayed updates. Production field assembly is scattered: the README does not put CSP nonce setup, dialog focus, Escape handling, form errors, and native submission into one working example.
Maintenance4/5npm published 5.8.1 on September 1, 2026, and GitHub records the last repository push on that date. The patch closed a reproducible alpha-channel defect and added regression cases for RGBA objects, RGBA strings, and alpha HEX. GitHub's search API currently separates 30 open issues from 3 open pull requests, and the repository is unarchived with 3,552 stars. The gap from 5.6.1 in August 2022 to 5.6.2 in May 2026 keeps this below a top cadence score.
Ecosystem4/5The npm downloads endpoint counted 3,103,105 downloads from September 3 through September 9, 2026, while GitHub reported 3,552 stars. Our package inspection found 2 peers and bundled TypeScript declarations, and the README explains Preact aliasing plus separate vanilla custom-element and Angular ports. The public surface stays focused on pickers and HexColorInput; it has no official adapter that supplies form state, a design-system field, or a framework-neutral DOM API.

Use it if

  • A React settings panel already has its field shell and needs a compact color surface inside it
  • Application state stores HEX text or explicit RGB, HSL, or HSV channels that match a named picker export
  • Live preview belongs in onChange while persistence or undo history should wait for onChangeEnd
  • A web component needs the picker inside its ShadowRoot; version 5.8 and later place the base style element in that root
Skip it if

Setup reality

We installed react-colorful 5.8.0 in 1.3 seconds using an unprivileged node:22-bookworm container with 3 CPUs, 8 GB RAM, and no cache. It left 4 packages occupying 8 MB. npm audit found 0 known vulnerabilities at every severity. The current npm release is 5.8.1, but these lab figures belong to 5.8.0.

The installed package was 504 KB unpacked, declared 0 direct dependencies and 2 peer dependencies, and included its TypeScript declarations. Your app supplies React and React DOM 16.8 or newer. It is a CommonJS package with an exports map; require() and ESM import both loaded on Node 22. There are no credentials or config files, and the license is MIT.

Our full-package browser build of 5.8.0 measured 22.9 KB minified and 7.8 KB gzipped. Starting with 5.8, the runtime inserts one base style element into each Document or ShadowRoot that hosts a picker, with a WeakMap preventing a second insertion for the same root. A strict CSP needs setNonce() before the first picker renders unless Webpack supplies the nonce. Custom sizing still uses the documented react-colorful selectors.

onChange fires throughout a drag and for each arrow-key adjustment. Version 5.7 added onChangeEnd, which runs after a changed mouse, touch, or keyboard interaction finishes and is the better place for a database write. HexColorInput withholds onChange until its text is valid, then restores the last color when unfinished text loses focus. The package leaves popover dismissal, field errors, native form serialization, and focus return to your code. IE11 also needs the README's Object.assign polyfill.

Patterns

Bind a HEX picker to React state control-hex-picker

import { useState } from 'react';
import { HexColorPicker } from 'react-colorful';

export function AccentPicker() {
  const [color, setColor] = useState('#2563eb');

  return (
    <section>
      <HexColorPicker
        color={color}
        onChange={setColor}
        aria-label="Accent color"
      />
      <output>{color}</output>
    </section>
  );
}

HexColorPicker accepts a HEX string and sends the next string to onChange. Feed that value back through color so the sliders stay in sync.

Persist after the drag finishes save-on-change-end

<HexColorPicker
  color={color}
  onChange={setColor}
  onChangeEnd={(settledColor) => saveAccent(settledColor)}
/>

Version 5.7 added onChangeEnd for mouseup, touchend, and arrow-key release. Keep visual updates in onChange and put the remote write in the end callback.

Store RGB channels with opacity edit-rgba-opacity

import { useState } from 'react';
import { RgbaColorPicker } from 'react-colorful';
import type { RgbaColor } from 'react-colorful';

const [overlay, setOverlay] = useState<RgbaColor>({
  r: 200,
  g: 120,
  b: 35,
  a: 0.5,
});

return <RgbaColorPicker color={overlay} onChange={setOverlay} />;

Version 5.8.1 preserves r, g, and b during an alpha-only move. Earlier releases could lower each channel in the 200, 120, 35 regression case.

Keep the value as CSS HSL text store-hsl-string

import { useState } from 'react';
import { HslStringColorPicker } from 'react-colorful';

const [surface, setSurface] = useState('hsl(210, 50%, 40%)');

return (
  <HslStringColorPicker
    color={surface}
    onChange={setSurface}
    aria-label="Surface color"
  />
);

HslStringColorPicker reads and emits hsl(...) strings. HslColorPicker is the separate export for objects with h, s, and l keys.

Represent opacity in a HEX value pick-alpha-hex

import { HexAlphaColorPicker } from 'react-colorful';

<HexAlphaColorPicker
  color={overlayHex}
  onChange={setOverlayHex}
  aria-label="Overlay color and opacity"
/>

HexAlphaColorPicker accepts shorthand input, but an interaction emits normalized 8-digit HEX whenever opacity is below 1. HexColorPicker has no alpha slider.

Put a typed HEX field beside the picker pair-picker-with-input

import { HexColorInput, HexColorPicker } from 'react-colorful';

<div className="accent-field">
  <label htmlFor="accent-hex">Accent color</label>
  <HexColorInput
    id="accent-hex"
    color={color}
    onChange={setColor}
    prefixed
  />
  <HexColorPicker
    color={color}
    onChange={setColor}
    aria-label="Accent color picker"
  />
</div>

HexColorInput ships without visual styles. The shared color state keeps the text field and picker aligned, while your CSS supplies focus and error treatment.

Allow opacity in typed HEX accept-alpha-hex-input

<HexColorInput
  color={color}
  onChange={setColor}
  alpha
  prefixed
  placeholder="#336699cc"
  aria-label="HEX color with opacity"
/>

The alpha prop accepts #rgba and #rrggbbaa, and prefixed keeps # visible. Invalid partial text stays local and reverts to color on blur.

Build presets from ordinary buttons add-color-swatches

const presets = ['#0f172a', '#2563eb', '#dc2626', '#16a34a'];

<div role="group" aria-label="Preset accent colors">
  {presets.map((preset) => (
    <button
      key={preset}
      type="button"
      aria-label={`Use ${preset}`}
      aria-pressed={color === preset}
      onClick={() => setColor(preset)}
      style={{ backgroundColor: preset }}
    />
  ))}
</div>

react-colorful does not export a swatch grid. A preset button only needs to write into the same color state used by the picker.

Scope picker dimensions to one field resize-picker-with-css

.profile-accent .react-colorful {
  width: 240px;
  height: 220px;
}

.profile-accent .react-colorful__hue {
  height: 28px;
}

.profile-accent .react-colorful__saturation {
  border-radius: 10px 10px 0 0;
}

The package exposes static react-colorful class names for overrides. Prefix them with your field class when different picker instances need different sizes.

Authorize the injected style element set-csp-nonce

import { createRoot } from 'react-dom/client';
import { setNonce } from 'react-colorful';

const nonce = document
  .querySelector('meta[name="csp-nonce"]')
  ?.getAttribute('content');

if (nonce) setNonce(nonce);

createRoot(document.getElementById('root')).render(<App />);

setNonce must run before the first picker mounts because that mount creates the style element. The value must match the nonce in the response's Content Security Policy.

Render the picker in a web component mount-inside-shadow-root

import { useState } from 'react';
import { createRoot } from 'react-dom/client';
import { HexColorPicker } from 'react-colorful';

function ShadowPicker() {
  const [color, setColor] = useState('#7c3aed');
  return <HexColorPicker color={color} onChange={setColor} />;
}

class AccentPickerElement extends HTMLElement {
  connectedCallback() {
    if (this.shadowRoot) return;
    const root = this.attachShadow({ mode: 'open' });
    const mount = document.createElement('div');
    root.append(mount);
    createRoot(mount).render(<ShadowPicker />);
  }
}

customElements.define('accent-picker', AccentPickerElement);

Version 5.8 inserts base rules into the closest ShadowRoot after mount. The custom element still owns React mounting and its public value contract.

Include the color in native FormData submit-color-in-form

<form action="/profile" method="post">
  <HexColorPicker
    color={color}
    onChange={setColor}
    aria-label="Profile accent"
  />
  <input type="hidden" name="accentColor" value={color} />
  <button type="submit">Save</button>
</form>

The picker root is a div, so it contributes no value to native FormData. Mirror the controlled color into a named input when the browser submits the form.

Alternatives

PackageRegistryPick it when
react-colornpmPick react-color 2.19.3 when named Sketch, Photoshop, and Chrome-style picker layouts are more useful than a bare field primitive.
@uiw/react-colornpmUse @uiw/react-color 2.10.3 when one package should expose Sketch, Material, wheel, swatch, alpha, hue, and editable-input components.
react-color-palettenpmChoose react-color-palette 7.3.1 when the default component should already combine saturation, hue, alpha, and HEX, RGB, or HSV input fields.

More web frontend guides

postcss · react · react-dom · tailwindcss · htmlparser2 · tailwind-merge · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.