Migration guide

Migrating from version 1.x to 2.0

XYZ D50 vs. D65

The CSS Color Module Level 4 specification has been updated to include separate predefined color profiles for the XYZ color space for the two most common white points: xyz-d50 for the D50 illuminant, and xyz-d65 for the D65 illuminant. The xyz predefined color profile is now an alias for the D65-relative XYZ color space. (w3c/csswg-drafts#6722).

In Culori, the D50-relative XYZ color space has been changed to use mode: 'xyz50' instead of mode: 'xyz'. The latter mode is no longer supported. If you store color objects in your application, they will have to have their mode property updated accordingly:

import { formatHex } from 'culori';

let color = getFavoriteColor();

if (color.mode === 'xyz') {
color.mode = 'xyz50';


When parsing strings, CSS colors in the color(xyz x y z) format will be parsed as mode: 'xyz65' instead of mode: 'xyz':

import { parse } from 'culori';

// In culori@1.x:
parse('color(xyz 0.5 0.25 1)');
// ⇒ { mode: 'xyz', x: 0.5, y: 0.25, z: 1 }

// In culori@2.0:
parse('color(xyz 0.5 0.25 1)');
// ⇒ { mode: 'xyz65', x: 0.5, y: 0.25, z: 1 }

When serializing with the formatCss() method, the xyz50 and xyz65 modes now use the predefined identifiers xyz-d50 and xyz-d65, as opposed to the custom identifiers --xyz-d50 and --xyx-d65 from 1.x:

import { formatCss } from 'culori';

// In culori@1.x:
formatCss({ mode: 'xyz65', x: 0.5, y: 0.25, z: 1 });
// ⇒ color(--xyz-d65 0.5 0.25 1)

// In culori@2.0:
formatCss({ mode: 'xyz65', x: 0.5, y: 0.25, z: 1 });
// ⇒ color(xyz-d65 0.5 0.25 1)

The following exports have been renamed in all applicable entry points:

<number> for L no longer valid in lab() and lch()

CSS defines the lab syntax as lab(<percentage> <number> <number>), for example:

lab(75% 40 30)

...and the lch syntax as lch(<percentage> <number> <hue>):

lch(75% 50 15deg)

Culori used to support <number> as the L channel, so these colors used to be also valid:

lab(75 40 30)
lch(75 50 15deg)

In version 2.0, we drop this quirk and bring Culori in line with the specification.

Migrating from version 0.x to 1.0

Using the library

Starting with version 1.0, Culori will be published to npm as an ES Module (ESM) package, with type: module and a set of exports in its package.json file.

If you're using Node.js 10, you should be able to continue using Culori as before.

If you're on Node.js 12 or later, and you've switched to native ES modules (by adding type: module to your package.json), you need to use import:

import * as culori from 'culori';

If you're on Node.js 12 or later, and you're still using CommonJS modules, there's a separate export that can be used with require() calls:

const culori = require('culori/require');

Removed methods

The clamp(method) function has been removed. Use clampRgb() and clampChroma() instead.

The formatter(method) function has been removed. Use formatHex(), formatRgb() etc. instead.

The following undocumented interpolation functions have been removed (note the interpolate prefix):

The differenceDino99() color difference function has been removed. Use differenceEuclidean('dlab') instead.

The methods deficiencyProt, deficiencyDeuter, and deficiencyTrit have been removed. Use filterDeficiencyProt, filterDeficiencyDeuter, and filterDeficiencyTrit instead.

Renamed methods

The following methods have been renamed:

Color space definitions

A few properties on the color space definition object have been changed for better clarity.