Generate a perceptual lightness scale from one OKLCH color. Zero dependencies. Part of huekit, the OKLCH toolkit for designers.
import { scale } from '@huekit/scale'
scale('#3b82f6')
// → {
// 50: 'oklch(0.971 0.188 259.81)',
// 100: 'oklch(0.936 0.188 259.81)',
// ...
// 900: 'oklch(0.317 0.188 259.81)',
// 950: 'oklch(0.257 0.188 259.81)',
// }A color scale (50, 100, 200 … 900, 950) is the backbone of every design system. The problem with building one in hex or HSL: the steps don't look evenly spaced. A 50%-lightness yellow looks far brighter than a 50%-lightness blue, so hand-built scales come out lopsided — the mid-tones feel muddy, the darks feel inconsistent across hues.
OKLCH is perceptually uniform. Step the L value evenly and the colors look evenly stepped, regardless of hue. @huekit/scale holds your hue and chroma constant, walks lightness across a tuned ramp, and hands you a complete palette that's consistent across every color in your system.
npm install @huekit/scale| Parameter | Type | Description |
|---|---|---|
input |
string | { c, h } |
A hex string ('#3b82f6') or an OKLCH object ({ c: 0.19, h: 260 }) |
options.precision |
number |
Decimal places in each output string (default: 4) |
options.stops |
Record<string, number> |
Custom stop → lightness map (default: 11 Tailwind-style stops) |
Returns an object keyed by stop name, each value an oklch() CSS string.
// From a hex color
scale('#6366f1')
// From OKLCH directly
scale({ c: 0.19, h: 260 })
// Control precision
scale('#6366f1', { precision: 3 })
// Custom stops
scale('#6366f1', { stops: { soft: 0.9, base: 0.5, deep: 0.2 } })
// → { soft: 'oklch(0.9 ...)', base: 'oklch(0.5 ...)', deep: 'oklch(0.2 ...)' }The default stops:
import { DEFAULT_STOPS } from '@huekit/scale'
// { 50: 0.971, 100: 0.936, 200: 0.885, 300: 0.808, 400: 0.704,
// 500: 0.602, 600: 0.519, 700: 0.446, 800: 0.379, 900: 0.317, 950: 0.257 }import { hexToOklch } from '@huekit/hex'
import { scale } from '@huekit/scale'
// Brand hex → full perceptual palette in two lines
const base = hexToOklch('#6366f1', 4, { raw: true })
const palette = scale(base)const palette = scale('#6366f1', { precision: 3 })
// In your CSS:
// @theme {
// --color-brand-50: oklch(0.971 ...);
// --color-brand-500: oklch(0.602 ...);
// ...
// }| Package | What it does |
|---|---|
@huekit/hex |
hex → oklch() conversion |
@huekit/scale ← you are here |
perceptual lightness scale from one color |
@huekit/contrast |
WCAG contrast ratios for OKLCH (soon) |
@huekit/mix |
blend OKLCH colors, no muddy midpoint (soon) |
@huekit/tailwind |
brand hex → Tailwind v4 @theme block (soon) |
@huekit/tokens |
design tokens → CSS custom properties (soon) |
MIT