Helmlab vs Oklab vs CIEDE2000: Building a Color Space on 64,000 Human Observations
Why your design system’s gradients have always been wrong — and the two-year journey to build a color space that actually sees like you do.
You create an 8-step color palette. The math says the steps are equal. But on screen, some steps look huge while others are barely there.
This isn’t a design problem. It’s a math problem. The color spaces behind your tools sRGB, HSL, CIE Lab, even Oklab — don’t accurately model how your eyes perceive differences between colors.
I spent the past two years building something to fix this. It’s called Helmlab, and it’s now open source.
The Problem: Color Spaces Lie to You
Here’s what’s happening under the hood when your palette looks off:
Every color space defines a “distance” between colors. When you create a gradient or palette, your tool divides that distance into equal mathematical steps. But if the space’s distance metric doesn’t match human perception, equal math ≠ equal appearance.
- HSL/HSV — Not perceptually uniform at all. A yellow at L=50 and a blue at L=50 look completely different in brightness.
- CIE Lab (1976) — Was designed to be uniform but makes significant errors, especially at high saturation. The best it can do is ΔE76, which has a STRESS of 42.80.
- CIEDE2000 — Patches Lab’s distance formula with 5 correction parameters. Gets STRESS down to 29.18. Industry standard for 25 years.
- Oklab — A beautiful design, now part of CSS Color Level 4. But only 18 parameters, and it doesn’t model phenomena like the Helmholtz-Kohlrausch effect (saturated colors appearing brighter).
STRESS is the CIE-standard metric for evaluating color difference formulas. It measures how well predicted distances match human judgments. Scale: 0 = perfect, 100 = no correlation.
No existing space was directly optimized to minimize STRESS on a large, combined dataset of human observations. That’s what Helmlab does.
What Is Helmlab?
Helmlab is a family of two purpose-built color spaces:
MetricSpace (72 parameters) optimized for perceptual distance measurement. A 13-stage enriched pipeline trained on COMBVD, a combined dataset of 3,813 color pairs from 6 independent psychophysical experiments (64,000+ individual human judgments).
GenSpace (21 parameters) optimized for color generation. A minimal linear-algebra pipeline with Phase1H-optimized matrices. 6× better hue accuracy than Oklab (5.2° vs 30.1° RMS hue error).
The key insight: measurement and generation are different objectives that need different spaces. MetricSpace excels at telling you how different two colors look. GenSpace excels at producing beautiful gradients and palettes. Helmlab gives you both.
The Numbers
MetricSpace achieves a STRESS of 23.30 on COMBVD — a 20% improvement over CIEDE2000 (29.18) and the lowest score ever reported on this dataset.
To make sure this wasn’t overfitting:
- 5-fold cross-validation: mean STRESS ≈ 23.5 (nearly identical to training)
- Bootstrap confidence intervals (10,000 iterations): Helmlab [22.50, 23.93] vs CIEDE2000 [27.64, 30.84] — zero overlap, p < 10⁻⁴
- Analytical form: every operation is a known mathematical function (matrix multiply, power, Fourier series). This acts as a strong structural regularizer.
The 72 parameters were optimized using L-BFGS-B with 8 random restarts. The full methodology is detailed in our arXiv paper.
Perfectly Uniform Gradients
This is probably the most immediately useful feature for designers and developers: gradient() produces gradients where every step looks equally spaced.
The magic isn’t the color space itself — it’s an algorithm called CIEDE2000 arc-length reparameterization. Here’s how it works:
- Interpolate between two colors in GenSpace Lab (256 fine samples)
- Measure the CIEDE2000 perceptual distance along the path
- Redistribute the output steps so each one covers equal perceptual distance
The result: CV ≈ 0% (coefficient of variation of step sizes) on any color pair.
I want to be transparent about this: the same technique could be applied to any color space. You could do arc-length reparameterization in Oklab or CIE Lab too. Helmlab simply ships it built-in. What GenSpace contributes is the color path — its Phase1H-optimized matrices produce better hue linearity, so the colors along the gradient look more natural even before reparameterization.
For Designers: What This Means in Practice
Semantic scales that actually work. Generate a Tailwind-style 50–950 scale from any base color. Every step looks equally spaced because the underlying space models human perception accurately.
Reliable contrast checking. WCAG contrast ratios are computed using luminance, which Helmlab maps accurately. ensureContrast() adjusts a foreground color to meet any target ratio while preserving hue and chroma — no more manual tweaking.
Gradients that don’t band. The gradient() function eliminates the uneven steps you see in CIE Lab or Oklab interpolation. Same endpoints, same number of steps, but every transition looks smooth.
For Developers: Quick Start
Helmlab is available as both an npm package and a Python package.
// JavaScript / TypeScript
npm install helmlab
# Python
pip install helmlab
import { Helmlab } from 'helmlab';const hl = new Helmlab();
// Convert
const lab = hl.fromHex('#3B82F6');
const hex = hl.toHex([0.5, -0.1, 0.2]);
// Gradient (arc-length reparameterized)
const grad = hl.gradient('#ff0000', '#0000ff', 8);
// Contrast
hl.contrastRatio('#ffffff', '#3B82F6'); // → 3.68
hl.ensureContrast('#3B82F6', '#ffffff', 4.5); // → adjusted hex
// Semantic scale
hl.semanticScale('#3B82F6'); // → { '50': '...', '500': '...', '950': '...' }
// Distance
hl.deltaE('#ff0000', '#00ff00'); // → perceptual distance
The npm package is ~12KB gzipped, zero dependencies, with ESM + CJS dual output and full TypeScript types. The Python package requires NumPy and SciPy.
How It Works Under the Hood
MetricSpace’s 13-stage pipeline transforms CIE XYZ tristimulus values to perceptual Lab coordinates:
- M₁ (cone response) — A 3×3 matrix maps XYZ to three cone cell responses (9 params)
- Power compression — Independent gamma per channel, generalizing Stevens’ power law (3 params)
- M₂ (opponent channels) — Another 3×3 matrix produces L (lightness), a (red-green), b (yellow-blue) (9 params)
- Hue correction — 4-harmonic Fourier series equalizes the perceptual hue circle (8 params)
- Helmholtz-Kohlrausch — Chroma-dependent lightness shift: saturated colors appear brighter (2 params)
- Lightness refinement — Cubic + dark-region corrections (6 params)
- Chroma calibration — Hue-dependent and L-dependent chroma scaling (20+ params)
- Neutral correction — Guarantees grays map to a=b=0, chroma < 10⁻⁶ (structural)
- Rigid rotation — φ = -28.2° in the ab-plane. Free optimization (isometry preserves distance)
Every stage is exactly invertible. The round-trip error (Lab → XYZ → Lab) is < 10⁻¹⁴.
Honest Limitations
No single blog post should be all hype. Here’s where Helmlab falls short:
- Not a CSS standard. Unlike Oklab/OKLCH, you can’t use Helmlab natively in CSS. You need the JavaScript library.
- Training data is finite. COMBVD has 3,813 pairs from 6 experiments. More diverse datasets (cross-cultural, display-dependent) would improve generalization.
- 72 parameters is a lot. This is a deliberate trade-off: more parameters = better fit, but also more complexity. The analytical form (vs. neural network) constrains the search space and prevents overfitting, but the model is inherently more complex than Oklab’s 18 parameters.
- Arc-length reparameterization is expensive. gradient() samples 256 intermediate points. For real-time animation, you'd want to cache the parameterization.
What’s Next
- Figma Plugin — Generate Helmlab palettes directly inside Figma
- Tailwind Plugin — @helmlab/tailwind for perceptual scales in utility classes
- More datasets — Expanding training data with new psychophysical experiments
- CSS integration research — Exploring paths toward standardization
Try It
npm install helmlab # JavaScript / TypeScript
pip install helmlab # Python
- Website: helmlab.space
- GitHub: github.com/Grkmyldz148/helmlab
- npm: npmjs.com/package/helmlab
- PyPI: pypi.org/project/helmlab
- Paper: arXiv:2602.23010
- Interactive Demo: helmlab.space (gradient demo)
Helmlab is MIT licensed. Contributions, feedback, and color science discussions are welcome.
Görkem Yıldız is a UI/UX designer and developer with 8+ years of experience crafting digital products. He leads the Figma FoF Ankara community and
builds open-source tools at the intersection of design and color science. Helmlab is his project to bring data-driven perceptual accuracy to
everyday design tools. — gorkemyildiz.com