Skip to content

Harmonies & Palette Generation ​

Color Harmonies ​

All harmonies are implemented as hue rotations on the normalized hex value — saturation and lightness are unchanged.

complement(color) ​

string — a #rrggbb color

The complementary color — a 180° hue rotation.

triadic(color) ​

[string, string, string]

3 colors evenly spaced 120° apart on the color wheel.

analogous(color, angle?) ​

[string, string, string]

3 neighboring colors — the input plus one rotated -angle and one rotated +angle. angle defaults to 30.

splitComplementary(color) ​

[string, string, string]

The base color plus two colors at 150° and 210° — a softer alternative to the direct complement.

tetradic(color) ​

[string, string, string, string]

4 colors evenly spaced 90° apart on the color wheel.

ts
import { triadic, analogous, tetradic } from 'color-value-tools'

triadic('#6c3483') // ['#6c3483', '#836d34', '#34836d']
analogous('#6c3483', 45) // ['#343783', '#6c3483', '#83345e']
tetradic('#6c3483') // ['#6c3483', '#834534', '#4b8334', '#347283']

Palette Generation ​

colorShades(color, steps?) ​

string[]

A light-to-dark scale by sweeping HSL lightness from 100 to 0 at the color's own hue/saturation. steps defaults to 9.

monochromatic(color, steps?) ​

string[]

A scale at fixed lightness with varying saturation. steps defaults to 5.

tints(color, steps?) ​

string[]

Mixes the color toward white in Oklab — equivalent to interpolateColors(color, '#ffffff', steps, { space: 'oklab' }). steps defaults to 5.

shades(color, steps?) ​

string[]

Mixes the color toward black in Oklab. steps defaults to 5.

tones(color, steps?, gray?) ​

string[]

Mixes the color toward a gray of your choice in Oklab. steps defaults to 5; gray defaults to '#808080'.

randomColor(options?) ​

ts
function randomColor(options?: {
  hRange?: [number, number] // default: [0, 360]
  sRange?: [number, number] // default: [40, 90]
  lRange?: [number, number] // default: [30, 70]
}): string

string — a #rrggbb color

Picks a uniformly random value inside each of the three HSL ranges (options sets independent min/max for hue, saturation, and lightness). Each call returns a different color — useful for demo data, avatars, or chart palettes, not for deterministic output.

ts
import { randomColor } from 'color-value-tools'

randomColor() // e.g. '#2a9d8a' — anywhere in the default ranges
randomColor({ hRange: [200, 260], sRange: [60, 80], lRange: [40, 60] }) // e.g. '#2b64bf' — blues only

Lazy generation ​

generateTints(color, steps, opts?) ​

Generator<string>

Lazy, generator-function equivalent of tints — yields one color at a time instead of building the whole array upfront. opts: { format?: 'hex' | 'rgb' | 'hsl' }.

generateShades(color, steps, opts?) ​

Generator<string>

Lazy, generator-function equivalent of shades. Same signature shape as generateTints.

ts
import { generateTints } from 'color-value-tools'

// Stop early without computing the remaining steps
const first5: string[] = []
for (const tint of generateTints('#e74c3c', 100)) {
  first5.push(tint)
  if (first5.length === 5) break
}