hueful: CSS Color Parsing and Conversion in JavaScript

Category: Color , Javascript | October 12, 2026
Author43081j
Last UpdateOctober 12, 2026
LicenseMIT
Tags
Views0 views
hueful: CSS Color Parsing and Conversion in JavaScript

hueful is a JavaScript library for parsing, converting, formatting, and adjusting CSS colors.

It works with RGB and HSL as well as perceptual color spaces like Lab and OKLCH.

Features

  • CSS hex values, color names, and functional color syntax.
  • Converts between 8 color spaces while preserving alpha.
  • Lightness and chroma adjustments through OKLCH.
  • Weighted color mixing in OKLab.
  • Hue rotation, grayscale conversion, and opacity controls.
  • RGB, hexadecimal, percentage RGB, and CSS color-name formatting.
  • WCAG 2 relative luminance and contrast calculations.

How To Use It

Installation

Install the ES module package from npm:

npm install hueful

Browser Usage

Import the ES module from jsDelivr inside a module script.

<script type="module">
  import { parse } from 'https://cdn.jsdelivr.net/npm/[email protected]/+esm';
  console.log(parse('#ff8800'));
</script>

Basic Usage

Use parse() to read a CSS color string and identify its space. convert() accepts a source space, destination space, and array of channel numbers. The output can be passed to the destination space’s format() function to produce a CSS color string.

import { parse, convert, oklch } from 'hueful';
const color = parse('#ff8800');
// { space: 'rgb', value: [255, 136, 0] }
if (color) {
  const channels = convert(color.space, 'oklch', color.value);
  console.log(oklch.format(...channels));
}

Parse And Format CSS Colors

Import a color-space namespace when the input or desired output format is known. A space-specific parse() returns channel values directly. format() accepts those channel values as individual arguments.

import { rgb, oklch, names } from 'hueful';
rgb.parse('#ff8800');                  // [255, 136, 0]
oklch.parse('oklch(0.7 0.15 30)');    // [0.7, 0.15, 30]
rgb.parse('transparent');              // [0, 0, 0, 0]
rgb.format(255, 136, 0);              // 'rgb(255 136 0)'
rgb.formatAsHex(255, 136, 0);         // '#ff8800'
rgb.formatAsPercent(255, 0, 0);      // 'rgb(100% 0% 0%)'
names.rebeccapurple;                  // [102, 51, 153]

Modify And Mix Colors

Hueful changes lightness and chroma in OKLCH, then returns channel values in the original color space. For lighten(), darken(), saturate(), and desaturate(), the amount parameter is a ratio of the current lightness or chroma. A value of 0.2 means a 20% relative adjustment.

import { lighten, darken, rotateHue, mix, rgb } from 'hueful';
lighten('oklch', [0.5, 0.1, 30], 0.2);    // [0.6, 0.1, 30]
darken('oklch', [0.5, 0.1, 30], 0.2);     // [0.4, 0.1, 30]
rotateHue('oklch', [0.5, 0.1, 30], 90); // [0.5, 0.1, 120]
const blended = mix('rgb', [255, 0, 0], [0, 0, 255]);
console.log(rgb.format(...blended));     // 'rgb(140 83 162)'

Calculate Color Contrast

contrast() and contrastLevel() use WCAG 2 relative luminance. contrastLevel() returns 'AA' at 4.5:1 and 'AAA' at 7:1, which are the normal-text thresholds.

import { luminance, contrast, contrastLevel, isDark } from 'hueful';
luminance('rgb', [0, 0, 0]);                       // 0
contrast('rgb', [0, 0, 0], [255, 255, 255]);      // Approximately 21
contrastLevel('rgb', [0, 0, 0], [255, 255, 255]); // 'AAA'
isDark('rgb', [255, 136, 0]);                     // false

Color Spaces And Channel Values

Colors are numeric tuples with an optional final alpha value. The space argument is one of eight lowercase keys.

SpaceChannel array
rgb[r, g, b, alpha?]: RGB values use the 0 to 255 scale.
hsl[h, s, l, alpha?]: hue in degrees, saturation and lightness in 0 to 100 percentage units.
hwb[h, w, b, alpha?]: hue in degrees, whiteness and blackness in 0 to 100 percentage units.
lab[l, a, b, alpha?]: lightness in 0 to 100 percentage units, followed by Lab coordinates.
lch[l, c, h, alpha?]: lightness in 0 to 100 percentage units, chroma, then hue in degrees.
oklab[l, a, b, alpha?]: lightness on a 0 to 1 scale, then OKLab coordinates.
oklch[l, c, h, alpha?]: lightness on a 0 to 1 scale, chroma, then hue in degrees.
cmyk[c, m, y, k, alpha?]: CMYK channels on a 0 to 1 scale.

Core API Reference

FunctionDescription
parse(input)Returns { space, value } for a recognized CSS color string, or null for an invalid or unrecognized string.
convert(from, to, color)Converts a channel array from one color space to another and preserves the optional alpha value.

Color Manipulation Functions

FunctionDescription
lighten(space, color, amount)Increases OKLCH lightness by a ratio of its current value.
darken(space, color, amount)Decreases OKLCH lightness by a ratio of its current value.
saturate(space, color, amount)Increases OKLCH chroma by a ratio of its current value.
desaturate(space, color, amount)Decreases OKLCH chroma by a ratio of its current value.
grayscale(space, color)Sets OKLCH chroma to zero and keeps perceived lightness.
rotateHue(space, color, degrees)Rotates OKLCH hue by the specified number of degrees.
mix(space, a, b, weight?)Mixes colors in OKLab. weight is the contribution of b and defaults to 0.5. The blend accounts for alpha.
fadeIn(space, color, amount)Increases an existing alpha by a ratio of its value. Leaves colors with no alpha unchanged.
fadeOut(space, color, amount)Reduces alpha by a ratio of its value. Uses an initial alpha of 1 if no alpha entry exists.

Color Analysis Functions

FunctionDescription
luminance(space, color)Returns relative luminance as a number.
contrast(space, a, b)Returns the contrast ratio between two colors.
contrastLevel(space, a, b)Returns 'AAA' for ratios of at least 7, 'AA' for at least 4.5, or null.
isDark(space, color)Returns true when the color contrasts more against white than black.
isLight(space, color)Returns true when the color contrasts at least as much against black as white.

Color-Space Namespace Functions

The 8 exported namespaces are rgb, hsl, hwb, lab, lch, oklab, oklch, and cmyk. Each exposes parse(input) and format(...channels) for that space.

They also expose toXYZ(...channels) and fromXYZ(x, y, z) conversion helpers, which use XYZ with a D65 reference white, plus channelCount (3 for seven spaces and 4 for CMYK).

The additional namespace functions accept individual channel arguments. rgb.formatAsName() returns null if no corresponding CSS color name exists or the alpha is not opaque. Hex and CSS formatting functions do not perform gamut mapping.

FunctionDescription
rgb.formatAsHex(r, g, b, alpha?)Formats RGB channels as a hex string. Includes alpha when supplied.
rgb.formatAsPercent(r, g, b, alpha?)Formats RGB channels as CSS percentages.
rgb.formatAsName(r, g, b, alpha?)Returns a matching CSS color name or null.
rgb.invert(r, g, b)Inverts each channel on the RGB 0 to 255 scale.
hsl.toRGB(h, s, l)Converts HSL channels to RGB.
hsl.fromRGB(r, g, b)Converts RGB channels to HSL.
hwb.toRGB(h, w, b)Converts HWB channels to RGB.
hwb.fromRGB(r, g, b)Converts RGB channels to HWB.
hwb.whiten(h, w, b, amount)Increases whiteness by a ratio of its value.
hwb.blacken(h, w, b, amount)Increases blackness by a ratio of its value.
lch.toLab(l, c, h)Converts LCH coordinates to Lab.
lch.fromLab(l, a, b)Converts Lab coordinates to LCH.
oklch.toOKLab(l, c, h)Converts OKLCH coordinates to OKLab.
oklch.fromOKLab(l, a, b)Converts OKLab coordinates to OKLCH.
cmyk.toRGB(c, m, y, k)Converts CMYK channels to RGB.
cmyk.fromRGB(r, g, b)Converts RGB channels to CMYK.

Alternatives And Related Resources

You Might Be Interested In:


Leave a Reply