colordx

Convert between OKLCH, OKLab, HEX, RGB, HSL and more.
Zero dependencies, fully typed, tree-shakeable.

OKLCH

Accepts hex, rgb(), hsl(), oklch(), oklab()…

In sRGB gamut

Accessibility

Sample Text Small body text for reading
WCAG 2.x

Getting Started

Install
npm install @colordx/core
Convert colors
import { colordx } from '@colordx/core';

const color = colordx('#ff6b35');
color.toHex()           // '#ff6b35'
color.toRgbString()     // 'rgb(255, 107, 53)'
color.toHslString()     // 'hsl(19.2, 100%, 60%)'
color.toOklch()         // { l: 0.68, c: 0.19, h: 38.18 }
color.toOklchString()   // 'oklch(0.6827 0.1946 38.18)'
color.toOklab()         // { l: 0.68, a: 0.149, b: 0.118 }
Gamut checking & mapping
import { inGamutSrgb, toGamutSrgb } from '@colordx/core';

inGamutSrgb('oklch(0.5 0.4 180)')   // false — out of sRGB
inGamutSrgb('oklch(0.5 0.1 180)')   // true  — in sRGB

// Map out-of-gamut color to nearest sRGB boundary
const mapped = toGamutSrgb('oklch(0.5 0.4 180)');
mapped.toHex()  // '#00866e'

Accessibility

What is APCA?

APCA (Accessible Perceptual Contrast Algorithm) is the contrast model proposed for WCAG 3.0. Unlike the WCAG 2.x ratio, it accounts for polarity (dark-on-light vs light-on-dark), spatial frequency, and human contrast sensitivity — producing results that align much more closely with how people actually perceive text readability.

Why is WCAG 2.x contrast not enough?

WCAG 2.x uses a simple luminance ratio that treats dark-on-light and light-on-dark pairs symmetrically, which does not reflect human vision. It is known to fail on mid-tone and dark backgrounds — sometimes rating a barely visible combination as passing, or a clearly readable one as failing. APCA fixes this with a polarity-aware model.

How do I use APCA in colordx?

Load the a11y plugin and call apcaContrast(background) to get the signed Lc value, or isReadableApca(background) to check against APCA thresholds — Lc 75 for body text, Lc 60 for large text. The existing contrast() and isReadable() methods continue to use WCAG 2.x.

What do positive and negative Lc values mean?

A positive Lc value means dark text on a light background; negative means light text on a dark background. The absolute value is what determines readability — Lc −75 and Lc 75 are equally readable. The sign only indicates polarity, which APCA uses internally to apply different contrast curves for each direction.

Why OKLCH?

What is OKLCH?

OKLCH is a perceptually uniform color space derived from OKLab. It represents colors using Lightness (L), Chroma (C), and Hue (H). Unlike sRGB or HSL, equal steps in OKLCH correspond to equal perceived differences — making it far more predictable when building color palettes and design systems.

Why use OKLCH in CSS?

Modern browsers support OKLCH natively via CSS Color Level 4. OKLCH lets you adjust lightness and chroma independently without the perceptual distortions that come with HSL. It's especially powerful for design tokens, accessible color systems, and dynamic theming.

OKLab vs OKLCH — what's the difference?

OKLab uses Cartesian coordinates (L, a, b) where a is the green–red axis and b is the blue–yellow axis. OKLCH is OKLab converted to polar coordinates — the same color described by Lightness, Chroma (distance from neutral), and Hue (angle). OKLCH is more intuitive; OKLab is better for programmatic color math.

Does colordx support gamut mapping?

Yes. colordx exports inGamutSrgb() to check whether a color is within the sRGB gamut, and toGamutSrgb() to map an out-of-gamut color to the nearest sRGB boundary via chroma-reduction binary search — the approach recommended by the CSS Color 4 specification.

What color formats are supported?

Core: HEX, RGB, HSL, HWB, OKLab, OKLCH. Optional plugins add CIE Lab, CIE LCH, XYZ, CMYK, color delta (ΔE), and named CSS colors. The plugin system keeps the core bundle small — import only what you need.

Is colordx compatible with colord?

colordx is API-compatible with colord and designed as a drop-in upgrade. It adds first-class OKLCH/OKLab support, gamut utilities, and a fully-typed plugin system. Most colord usage can be migrated by replacing the import.