This is the complete public API of chroma-flow. All functions are
tree-shakeable ESM exports and have zero runtime dependencies.
- Palette generation
- Color space conversions
- WCAG contrast
- APCA contrast
- Color vision deficiency
- Text color suggestion
- Semantic themes
- Exporters
- Types
Generate a full 50–950 palette from a seed hex color.
const palette = generatePalette("#6366f1");
// { 50: "#e8f5ff", 100: "#deecff", ..., 950: "#0c033d" }Options
| Option | Type | Default |
|---|---|---|
distribution |
"linear" | "perceptual" |
"perceptual" |
chromaFalloff |
number (0–1) |
0.5 |
hueShift |
number (degrees) |
0 |
maxChroma |
number |
0.32 |
Generate multiple named palettes at once.
const system = generatePalettes({
primary: "#6366f1",
success: "#10b981",
warning: "#f59e0b",
});Returns the ordered array of palette stops: [50, 100, 200, ..., 950].
Convert between hex strings and the OKLCH color space.
Lower-level conversion helpers.
Normalize any hex form (#abc, #aabbcc) to a 7-character #aabbcc string.
WCAG 2.1 relative luminance of an RGB color (0–1).
Returns the WCAG contrast ratio (1–21).
Full conformance check:
{
ratio: 8.48,
passesAANormal: true,
passesAALarge: true,
passesAAANormal: true,
passesAAALarge: true,
}Boolean check for "AA" or "AAA" (normal text).
Formats a ratio for display: 4.53 → "4.53:1".
APCA (Accessible Perceptual Contrast Algorithm) is the WCAG 3 candidate contrast method. It is more perceptually accurate than the WCAG 2.1 ratio — especially for dark backgrounds, where WCAG 2.1 overestimates readability.
Returns a signed Lc value (roughly −107 to +106):
- Positive = dark text on a light background.
- Negative = light text on a dark background.
- Magnitude = perceived contrast strength.
apcaContrast("#000000", "#ffffff"); // +106
apcaContrast("#ffffff", "#000000"); // -107Full APCA check with conformance helpers:
{
Lc: -87.6,
magnitude: 87.6,
recommendedMinSize: 12,
passesBodyText: true, // |Lc| ≥ 75
passesLargeText: true, // |Lc| ≥ 60
passesNonText: true, // |Lc| ≥ 45
}Formats an Lc value: -87.6 → "Lc -87.6".
Returns "#000000" or "#ffffff" based on APCA magnitude.
Simulate one CVD type. type ∈ "protanopia" | "deuteranopia" | "tritanopia" | "achromatopsia".
Simulate all four CVDs, returning [{ type, hex, original }, ...].
Score (0–1) how distinguishable two colors remain under each CVD.
Returns "#000000" or "#ffffff", whichever is more readable.
Find the palette stop with the highest passing contrast ratio.
Per-stop accessibility audit (best text color, AA pass for black/white).
Generate a coordinated light + dark theme from a single seed. The dark variant isn't an inverted ramp — it's recomposed with lower-chroma surfaces, lighter text roles, and a desaturated primary for comfort on emissive screens.
Returns a ThemePair with light, dark, lightAudit, and darkAudit.
const theme = generateTheme("#6366f1");
theme.light.primary; // "#3f37bb"
theme.dark.primary; // "#8b95ff"
theme.darkAudit; // [{ role, background, text, wcagRatio, apcaLc, passesAA }, ...]Each SemanticTheme contains: background, surface, surfaceMuted,
border, text, textMuted, textSubtle, primary, primaryForeground,
accent, accentForeground, success, warning, danger.
Emits :root { ... } plus a .dark { ... } override block.
Emits { seed, light, dark } JSON.
Single entry point. format ∈ "css" | "tailwind" | "json" | "scss" | "svg" | "android-xml" | "swift" | "compose".
toCSS(palette, name?)— CSS custom properties.toCSSMulti(palettes)— multiple named palettes as CSS.toTailwind(palette, name)— Tailwind config fragment.toTailwindMulti(palettes)— multiple palettes as Tailwind config.toJSON(palette)— JSON object.toSCSS(palette, name?)— SCSS variables.toSVG(palette, name?)— SVG swatch sheet.toAndroidXML(palette, name?)— Androidcolors.xml.toSwift(palette, name?)— SwiftUIColorextension.toCompose(palette, name?)— Jetpack ComposeColorobject.
All types are exported from the package root: RGB, OKLCH, OKLab,
PaletteStop, Palette, GenerateOptions, WCAGLevel, ContrastResult,
CVDType, CVDPreview, ExportFormat, APHAResult, SemanticTheme,
ThemeAudit, ThemePair.