oklch-greyscaler
v2.1.0
Published
Deterministic OKLCH grayscale algorithm and design tokens generator
Maintainers
Readme
oklch-greyscaler
Deterministic grayscale palette generation built on the OKLCH perceptual color space — with accessibility-first contrast validation baked in.
Generate beautiful, perceptually uniform grey scales from a seed color, a preset, or manual OKLCH parameters. Every token ships with WCAG AA/AAA contrast ratios pre-computed for both light and dark backgrounds.
Works in Node.js, browsers, and edge runtimes — zero DOM dependencies.
Install
npm install oklch-greyscalerQuick Start
import { generateFromSeed } from "oklch-greyscaler";
// One-liner: brand color → full 11-step grey palette
const tokens = generateFromSeed("#FDB347");
tokens?.forEach((t) => {
console.log(`Grey ${t.step}: ${t.hex} — contrast on white: ${t.contrastOn50}`);
});Advanced: Manual Configuration
import { generateGrayScale } from "oklch-greyscaler";
// Full control over hue, chroma, and curve
const tokens = generateGrayScale({
hue: 250,
baseChroma: 0.014,
curveStrength: 1,
});API Reference
generateFromSeed(hex, curveStrength?): GrayToken[] | null
The simplest way to generate a palette. Pass any hex color and get back an 11-step grayscale derived from that color's perceptual hue and chroma.
generateFromSeed("#FDB347");
// → 11 tokens with hue ~73, baseChroma ~0.0121
generateFromSeed("#FF6B6B", 1.1);
// → Same but with stronger lightness curveReturns null if the hex is invalid.
generateGrayScale(config): GrayToken[]
Generates an 11-step grayscale palette (50–950) with full control.
type GrayScaleConfig = {
hue: number; // 0–360
baseChroma: number; // 0.004–0.03
curveStrength: number; // 0.8–1.2
};Returns an array of GrayToken objects:
type GrayToken = {
step: 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950;
hex: string;
oklch: { l: number; c: number; h: number };
// Light mode contrast (against light backgrounds)
contrastOn50: number;
contrastOn100: number;
aaOn50: boolean;
aaOn100: boolean;
aaaOn50: boolean;
aaaOn100: boolean;
// Dark mode contrast (against dark backgrounds)
contrastOn900: number;
contrastOn950: number;
aaOn900: boolean;
aaOn950: boolean;
aaaOn900: boolean;
aaaOn950: boolean;
};deriveConfigFromSeedHex(hex): { hue, baseChroma } | null
Extracts perceptual hue and chroma from any hex color, clamped to safe greyscale ranges.
deriveConfigFromSeedHex("#FF6B6B");
// → { hue: 25.07, baseChroma: 0.016 }contrastRatio(foreground, background): number
Computes the WCAG 2.1 contrast ratio between two hex colors.
contrastRatio("#000000", "#FFFFFF"); // → 21
contrastRatio("#767676", "#FFFFFF"); // → 4.54normalizeHexInput(input, options?): string | null
Normalizes and validates hex color input. Supports 3-digit and 6-digit hex.
normalizeHexInput("#abc"); // → "#AABBCC"
normalizeHexInput("fdb347"); // → "#FDB347"
normalizeHexInput("#12"); // → nullExport Utilities
Ready-made formatters to drop your palette into any workflow.
CSS Custom Properties
import { exportCssVars } from "oklch-greyscaler";
console.log(exportCssVars(tokens));
// :root {
// --gray-50: #F9F9FA;
// ...
// --gray-950: #141417;
// }Tailwind CSS
import { exportTailwind } from "oklch-greyscaler";
console.log(exportTailwind(tokens));
// theme: {
// extend: {
// colors: {
// gray: {
// 50: "#F9F9FA",
// ...
// }
// }
// }
// }Figma Design Tokens (JSON)
import { exportFigmaTokensJson } from "oklch-greyscaler";
console.log(exportFigmaTokensJson(tokens));
// {
// "Grey": {
// "50": { "value": "#F9F9FA", "type": "color" },
// ...
// }
// }Compatible with Variables Import plugins and Token Studio.
Why OKLCH?
Traditional color spaces like HSL produce greys that look uneven to the human eye. A grey at HSL lightness 50% doesn't feel like it's halfway between black and white.
OKLCH is a perceptually uniform color space — meaning equal numeric steps produce equal visual steps. This makes your grey scales feel balanced, natural, and consistent across light and dark themes.
TypeScript
Full type definitions are included:
import type {
GrayToken,
GrayStep,
GrayScaleConfig,
} from "oklch-greyscaler";Steps
Every palette contains 11 steps following the standard design token convention:
50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950
License
MIT
