What is this?
4444 color names, evenly spread over the OKLab color space, covering the full Rec2020 gamut — every point above is one named color.
This project grew out of color-names, my crowd-sourced collection of 30 000+ color names. Plotted in perceptual color space, that list clusters heavily where humans historically looked — reds, skin tones, popular sRGB pastels — while whole regions of the gamut sit almost empty. colornames-oklab is the experiment in the other direction: what does a color name list look like when it's equally distributed?
Here the positions come first. Points are placed with best-candidate (blue-noise) sampling in OKLab, so they are perceptually evenly spaced: dense nowhere, sparse nowhere, no two names awkwardly close together. Sampling is seeded and grown in stable passes, so ids and names never change as the list is extended.
Each point is classified by the smallest standard gamut that contains it, and the commonness of its name tracks its tier:
| tier | count | meaning | naming register |
|---|---|---|---|
srgb | 2041 | displayable everywhere | the everyday canon — Moss, Denim, Butter, Charcoal |
p3 | 776 | needs a Display P3 screen | vivid & recognizable — Electric Blue, Neon Carrot |
rec2020 | 1627 | beyond P3, the outer shell | rare pigments & superlatives — Smaragdine, Zaffre, Impossible Green |
The naming was done with Claude Fable 5 (Anthropic), point-by-point with each color's OKLCH coordinates and gamut tier in view, using the existing color-names list as inspiration for tone and style. Every name is unique, and ~80 obvious names (Red, Blue, Navy, Pink, White, …) are audited to sit on srgb-tier points near their reference colors — nobody needs a P3 monitor to see “Pink”.
Install
npm install colornames-oklab
The package ships one JSON file plus ESM and CJS entry points — no dependencies.
Usage
// ESM
import colors from 'colornames-oklab';
// CJS
const colors = require('colornames-oklab');
colors.length; // 4444
colors.find(c => c.name === 'Emerald');
// { name: 'Emerald', tier: 'srgb', hex: '#089156', oklab: [0.577, -0.1257, 0.0551] }
A tiny dependency-free lookup ships with the package — pass raw OKLab values (convert your colors yourself), get the nearest named color. With unique, every name is used at most once, like color.pizza's noduplicates:
import { closest } from 'colornames-oklab';
closest([0.7, 0.1, 0.1]).name; // → a warm coral
closest([[0.7, 0.1, 0.1], [0.3, 0, 0]]); // one match per query
closest(palette, { unique: true }); // no name twice
For CSS, spell the exact color as oklab() — every evergreen browser renders it and gamut-maps to whatever the display can show. The hex is the pre-clamped sRGB fallback:
el.style.background = 'oklab(' + c.oklab.join(' ') + ')'; // exact, browser gamut-maps
el.style.background = c.hex; // sRGB fallback (OKLCH-clamped)
| field | what it is |
|---|---|
name | unique colour name |
tier | srgb · p3 · rec2020 — smallest gamut containing the colour |
hex | sRGB fallback, chroma-clamped in OKLCH (hue & lightness preserved) |
oklab | exact sampled [L, a, b]; OKLCH is hypot(a,b) / atan2(b,a) away |
Support
If you find this project useful, please consider buying me a coffee. It keeps my caffeine levels high enough to distinguish between #fafafa and #fbfbfb.
All 4444 names
The full list, alphabetical (locale-aware — accents sort where you'd expect). Type to filter.