Skip to main content
A powerful color manipulation library with support for multiple color spaces, conversions, accessibility calculations, and color transformations.

Installation

npm install @temelj/color

Color types

The library uses a consistent RGB color type as the primary representation.
interface Color {
  red: number;    // 0-255
  green: number;  // 0-255
  blue: number;   // 0-255
  alpha?: number; // 0-1 (optional)
}

interface HslColor {
  hue: number;        // 0-360
  saturation: number; // 0-1
  lightness: number;  // 0-1
  alpha?: number;     // 0-1 (optional)
}

interface LabColor {
  l: number;          // 0-100
  a: number;          // -128 to 127
  b: number;          // -128 to 127
  alpha?: number;     // 0-1 (optional)
}

interface OkLchColor {
  l: number;          // 0-1
  c: number;          // 0+
  h: number;          // 0-360
  alpha?: number;     // 0-1 (optional)
}

RGB operations

fromRgb

Creates a color from RGB values.
function fromRgb(red: number, green: number, blue: number, alpha?: number): Color
import { fromRgb } from "@temelj/color";

const red = fromRgb(255, 0, 0);
const blue = fromRgb(0, 0, 255, 0.5); // With alpha

parseRgb

Parses a CSS rgb/rgba color string.
function parseRgb(value: string): Color | undefined
import { parseRgb } from "@temelj/color";

parseRgb("rgb(255, 0, 0)");          // { red: 255, green: 0, blue: 0 }
parseRgb("rgba(0, 128, 255, 0.5)");  // { red: 0, green: 128, blue: 255, alpha: 0.5 }
parseRgb("invalid");                  // undefined

toRgbString / toRgbaString

Converts a color to CSS rgb/rgba string.
function toRgbString(color: Color): string
function toRgbaString(color: Color): string
import { fromRgb, toRgbString, toRgbaString } from "@temelj/color";

const color = fromRgb(255, 128, 64, 0.8);

toRgbString(color);   // "rgb(255, 128, 64)"
toRgbaString(color);  // "rgba(255, 128, 64, 0.8)"

isValidRgb

Validates an RGB color.
function isValidRgb(color: Color): boolean
import { isValidRgb, fromRgb } from "@temelj/color";

isValidRgb(fromRgb(255, 128, 64));     // true
isValidRgb(fromRgb(300, 128, 64));     // false (out of range)
isValidRgb(fromRgb(255, 128, 64, 2));  // false (invalid alpha)

Hex operations

parseHex

Parses a hex color string.
function parseHex(value: string): Color | undefined
import { parseHex } from "@temelj/color";

parseHex("#FF00FF");    // { red: 255, green: 0, blue: 255 }
parseHex("FF00FF");     // { red: 255, green: 0, blue: 255 }
parseHex("#FF00FFFF");  // { red: 255, green: 0, blue: 255, alpha: 1.0 }

toHex / toHexHash

Converts a color to hex format.
function toHex(color: Color): string
function toHexHash(color: Color): string
import { fromRgb, toHex, toHexHash } from "@temelj/color";

const color = fromRgb(255, 0, 255);

toHex(color);      // "ff00ff"
toHexHash(color);  // "#ff00ff"

const withAlpha = fromRgb(255, 0, 255, 0.5);
toHexHash(withAlpha); // "#ff00ff80"

HSL operations

fromHsl

Creates an HSL color.
function fromHsl(hue: number, saturation: number, lightness: number, alpha?: number): HslColor
import { fromHsl } from "@temelj/color";

const red = fromHsl(0, 1, 0.5);      // Pure red
const blue = fromHsl(240, 1, 0.5);   // Pure blue

hslToRgb / rgbToHsl

Converts between HSL and RGB color spaces.
function hslToRgb(color: HslColor): Color
function rgbToHsl(color: Color): HslColor
import { fromHsl, hslToRgb } from "@temelj/color";

const hsl = fromHsl(120, 1, 0.5);  // Green
const rgb = hslToRgb(hsl);
// { red: 0, green: 255, blue: 0 }

toHslString / toHslaString

Converts to CSS hsl/hsla string.
function toHslString(color: HslColor): string
function toHslaString(color: HslColor): string
import { fromHsl, toHslString } from "@temelj/color";

const color = fromHsl(240, 1, 0.5, 0.8);

toHslString(color);   // "hsl(240, 100%, 50%)"
toHslaString(color);  // "hsla(240, 100%, 50%, 0.8)"

normalizeHsl / isValidHsl

Validates and normalizes HSL colors.
function normalizeHsl(color: HslColor): HslColor
function isValidHsl(color: HslColor): boolean
import { fromHsl, normalizeHsl } from "@temelj/color";

const color = fromHsl(370, 1.5, -0.2);
const normalized = normalizeHsl(color);
// { hue: 10, saturation: 1, lightness: 0 }

Lab and OKLCH

Lab and OKLCH color spaces provide perceptually uniform color manipulation.

rgbToLab / labToRgb

Converts between RGB and Lab color spaces.
function rgbToLab(color: Color): LabColor
function labToRgb(color: LabColor): Color
import { fromRgb, rgbToLab, labToRgb } from "@temelj/color";

const rgb = fromRgb(255, 0, 0);
const lab = rgbToLab(rgb);
const backToRgb = labToRgb(lab);

OKLCH conversions

OKLCH is a modern perceptually uniform color space.
function rgbToOkLch(color: Color): OkLchColor
function okLchToRgb(color: OkLchColor): Color
import { fromRgb, rgbToOkLch, okLchToRgb } from "@temelj/color";

const rgb = fromRgb(100, 150, 200);
const oklch = rgbToOkLch(rgb);
const backToRgb = okLchToRgb(oklch);
OKLCH is ideal for generating color palettes and ensuring perceptually uniform color transitions.

Color manipulation

mix

Mixes two colors together.
function mix(a: Color, b: Color, weight?: number): Color
import { fromRgb, mix } from "@temelj/color";

const red = fromRgb(255, 0, 0);
const blue = fromRgb(0, 0, 255);

mix(red, blue);      // 50/50 mix (purple)
mix(red, blue, 0.8); // 80% red, 20% blue
mix(red, blue, 0.2); // 20% red, 80% blue

lighten / darken

Adjusts the lightness of a color.
function lighten(color: Color, amount: number): Color
function darken(color: Color, amount: number): Color
import { fromRgb, lighten } from "@temelj/color";

const color = fromRgb(100, 50, 150);

lighten(color, 0.1);  // Slightly lighter
lighten(color, 0.3);  // Much lighter

saturate / desaturate

Adjusts the saturation of a color.
function saturate(color: Color, amount: number): Color
function desaturate(color: Color, amount: number): Color
import { fromRgb, saturate, desaturate } from "@temelj/color";

const color = fromRgb(150, 100, 100);

saturate(color, 0.2);    // More vibrant
desaturate(color, 0.2);  // More muted

grayscale

Converts a color to grayscale.
function grayscale(color: Color): Color
import { fromRgb, grayscale } from "@temelj/color";

const color = fromRgb(255, 100, 50);
const gray = grayscale(color);
// Fully desaturated version

Accessibility

getLuminance

Calculates relative luminance according to WCAG 2.0.
function getLuminance(color: Color): number
import { fromRgb, getLuminance } from "@temelj/color";

const white = fromRgb(255, 255, 255);
const black = fromRgb(0, 0, 0);

getLuminance(white); // 1.0
getLuminance(black); // 0.0

getContrastRatio

Calculates the contrast ratio between two colors.
function getContrastRatio(a: Color, b: Color): number
import { fromRgb, getContrastRatio } from "@temelj/color";

const white = fromRgb(255, 255, 255);
const black = fromRgb(0, 0, 0);
const darkGray = fromRgb(64, 64, 64);

getContrastRatio(white, black);    // 21 (maximum)
getContrastRatio(white, darkGray); // ~9.6
  • AA (normal text): 4.5:1 minimum
  • AA (large text): 3:1 minimum
  • AAA (normal text): 7:1 minimum
  • AAA (large text): 4.5:1 minimum

Interpolation

lerpRgb / lerpHsl

Interpolates between two colors.
function lerpRgb(a: Color, b: Color, t: number): Color
function lerpHsl(a: HslColor, b: HslColor, t: number): HslColor
import { fromRgb, lerpRgb } from "@temelj/color";

const red = fromRgb(255, 0, 0);
const blue = fromRgb(0, 0, 255);

lerpRgb(red, blue, 0);    // Pure red
lerpRgb(red, blue, 0.5);  // Purple
lerpRgb(red, blue, 1);    // Pure blue
RGB interpolation can produce dull colors in the middle range. For better results, consider interpolating in Lab or OKLCH color spaces.

Examples

import { fromRgb, lighten, darken } from "@temelj/color";

function generatePalette(base: Color) {
  return {
    50: lighten(base, 0.4),
    100: lighten(base, 0.3),
    200: lighten(base, 0.2),
    300: lighten(base, 0.1),
    400: base,
    500: darken(base, 0.1),
    600: darken(base, 0.2),
    700: darken(base, 0.3),
    800: darken(base, 0.4),
    900: darken(base, 0.5)
  };
}

const blue = fromRgb(59, 130, 246);
const palette = generatePalette(blue);
For design systems, use OKLCH color space for generating palettes to ensure perceptually uniform color steps.

Build docs developers (and LLMs) love