mrkeyoor.com_
Sat 08 Aug 21:00 UTC
npmWeb Frontendupdated 08 Aug 2026

react-colorful

react-colorful is a controlled color-picker component set for React and Preact. It exports pickers for HEX, RGB, HSL, HSV, alpha-bearing variants, and string or object value shapes, plus a separate HEX text input. Version 5.8 adds onChangeEnd for persistence or undo checkpoints and injects its base styles into the nearest document or ShadowRoot. The package has no runtime dependencies, includes TypeScript declarations, and leaves popovers, swatches, labels, validation messages, and form integration to your application.

Verdict

A strong low-level color control when size, value-shape choice, and composition matter. Skip it if you expect a polished popover field out of the box, because most product UI around the picker is intentionally yours.

API stability5/5The controlled color plus onChange contract has remained small across the 5.x line, with additions such as onChangeEnd and Shadow DOM styling arriving without replacing existing picker components. Each color model has an explicit component and exported TypeScript value type, so changes are easy to detect at compile time. React 16.8 remains the peer floor, and the package exports ESM, CommonJS, UMD, and declarations.
Docs5/5The README documents every supported picker and its exact value shape, controlled props, onChangeEnd semantics, CSS override selectors, HexColorInput alpha and prefix options, TypeScript type imports, Preact aliasing and type conflicts, IE11's Object.assign requirement, recipes, and bundle rationale. The changelog fills in CSP nonce and ShadowRoot style behavior. The main omission is a first-party guide for SSR and popover focus management.
Maintenance5/5Version 5.8.0 was published in July 2026 and the repository was pushed the same day. GitHub showed 35 combined open issues and pull requests on a repository with about 3,500 stars. The latest release adds meaningful onChangeEnd and Shadow DOM support, while the project continues to ship strict TypeScript, automated tests, included declarations, and multiple module formats under an MIT license.
Ecosystem4/5Nearly six million weekly downloads, React and Preact compatibility, TypeScript declarations, a zero-dependency runtime, and visible use in projects such as Storybook give the component broad reach. Recipes cover popovers, swatches, typed input, custom layout, and debouncing. It stops short of a full ecosystem score because there are no official adapters for form libraries or design systems, and non-React frameworks use separate ports.

Use it if

  • You want a small controlled picker and can build the surrounding input, popover, swatches, and form behavior yourself
  • You need HEX, RGB, HSL, or HSV values with optional alpha in typed React code
  • You need touch, keyboard, assistive-technology, Shadow DOM, and old-browser support from the same low-level component
  • You want onChange for live preview and onChangeEnd for database writes, history entries, or other expensive work
Skip it if

Setup reality

npm install react-colorful gives you declarations and no runtime dependencies, but React and react-dom 16.8 or newer are peer dependencies because the components use hooks. The picker is controlled: keep color in state and update it from onChange or the handle will appear stuck. Pick the component whose value shape matches your domain; HexColorPicker uses a string, RgbColorPicker uses an object, and alpha variants change both valid input and output. Version 5.8 also exposes onChangeEnd, which fires on mouseup, touchend, or keyup and is the right place for saves or undo checkpoints; onChange still fires throughout dragging. Base picker CSS is injected at runtime, including into the closest ShadowRoot, so no package CSS import is needed. Your overrides still target static react-colorful class names, and the separate HexColorInput intentionally has no default styles. Strict CSP sites must call setNonce with the server-provided nonce before the style tag is created. All pickers accept normal div attributes, but you still own the field label, error text, popover focus management, close behavior, and how a submitted form serializes the color. HexColorInput needs alpha for four- or eight-digit HEX and prefixed to display the #. Preact usually works through React aliases, but the README documents a TypeScript declaration patch when @types/react enters the graph. IE11 needs Object.assign, according to the browser section. For server rendering, avoid deriving initial color from browser-only state and verify that the style injection fits your framework's hydration and CSP order.

Patterns

Use a controlled HEX pickerpick-hex-color

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

export function ColorField() {
  const [color, setColor] = useState('#aabbcc');
  return <HexColorPicker color={color} onChange={setColor} />;
}

The component is controlled; failing to update color in onChange makes the handle snap back to the old value.

Separate live preview from persistencesave-after-change

<HexColorPicker
  color={color}
  onChange={setColor}
  onChangeEnd={(finalColor) => savePreference(finalColor)}
/>

Version 5.8 onChangeEnd fires after mouse, touch, or keyboard interaction ends, avoiding a write for every drag step.

Work with typed RGB object valuespick-rgb-object

import { useState } from 'react';
import { RgbColorPicker, RgbColor } from 'react-colorful';

const [color, setColor] = useState<RgbColor>({ r: 50, g: 100, b: 150 });
return <RgbColorPicker color={color} onChange={setColor} />;

Choose a string picker if your API expects CSS strings; object pickers intentionally return objects.

Use an RGBA picker with transparencypick-alpha-color

import { RgbaColorPicker, RgbaColor } from 'react-colorful';

const [color, setColor] = useState<RgbaColor>({ r: 20, g: 40, b: 60, a: 0.5 });
return <RgbaColorPicker color={color} onChange={setColor} />;

Alpha is a number from 0 to 1 for RGBA objects; HEX alpha pickers instead use four- or eight-digit strings.

Pair the picker with a typed HEX inputpair-hex-input

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

return (
  <div>
    <HexColorPicker color={color} onChange={setColor} />
    <HexColorInput color={color} onChange={setColor} prefixed />
  </div>
);

HexColorInput has no default styles, so it will look like a bare browser input until your stylesheet handles it.

Allow HEX input with an alpha channelaccept-hex-alpha-input

<HexColorInput
  color={color}
  onChange={setColor}
  alpha
  prefixed
  aria-label="Color including opacity"
/>

Set alpha or four- and eight-digit HEX values are not accepted by the input's normal validation path.

Override the stable picker class namescustomize-picker-css

.brand-picker .react-colorful { height: 240px; }
.brand-picker .react-colorful__saturation { border-radius: 8px 8px 0 0; }
.brand-picker .react-colorful__hue { height: 32px; }
.brand-picker .react-colorful__hue-pointer { width: 14px; }

Base styles are injected automatically; these selectors are overrides and should be scoped to avoid changing every picker.

Pass regular div accessibility attributesadd-accessible-label

<HexColorPicker
  color={color}
  onChange={setColor}
  aria-label="Brand color"
  className="brand-picker"
/>

The picker accepts div attributes, but a complete form still needs visible label, help, validation, and focus behavior around it.

Authorize the injected stylesheet under strict CSPset-csp-nonce

import { setNonce } from 'react-colorful';

setNonce(window.__CSP_NONCE__);

// Render pickers only after the nonce is configured.

The component injects a style tag; call setNonce before the first picker mounts and source the value from the server response.

Keep a serializable form value beside the pickernormalize-form-value

function ColorControl({ value, onValueChange }) {
  return (
    <HexColorPicker
      color={value || '#000000'}
      onChange={(next) => onValueChange(next.toLowerCase())}
    />
  );
}

react-colorful controls color interaction only; your form library still owns touched state, validation, and submission.

Alternatives

PackageRegistryPick it when
react-colornpmYou want a larger collection of ready-made picker designs and accept a much heavier dependency
@uiw/react-colornpmYou want composable color primitives plus more packaged picker variants and utilities
react-color-palettenpmYou prefer a more opinionated picker with a bundled input and simpler preset UI