A comprehensive, type-safe color manipulation library for TypeScript that makes color handling trivial. Bismuth provides first-class support for multiple color spaces, perceptual color models, blending modes, color difference metrics, and WCAG contrast checks.
-
Multiple color spaces
- RGB, sRGB, HSL, HSV, HWB, CMYK
- XYZ, Lab, LCH
- OKLab, OKLCH
- Alpha support is built into every space
-
Strong typing
- Fully typed color spaces and blend modes
- Generic
Color<T extends ColorSpace>API
-
Color conversion
- Accurate conversions between all supported color spaces
- Linear RGB and sRGB handling
-
Blending and compositing
- Common blend modes (multiply, screen, overlay, etc.)
- Powerful blend functions
- Alpha-aware compositing
-
Color math and analysis
- Luminance and contrast
- WCAG A / AA / AAA compliance checks
- ΔE color difference (RGB, CIE76, CIE94, CIEDE2000)
-
Utilities
- Interpolation and gradients
- Nearest named color matching
- Complementary colors
- Ideal foreground color selection
-
Visualization
- Render 2D color slices to
<canvas> - Axes, grids, legends, and theming support
- Render 2D color slices to
import { Color } from "bismuth";
const red = new Color("#ff0000");
const blue = new Color("hsl", 220, 0.7, 0.5);
red.toHex(); // "#ff0000ff"
blue.toSpace("rgb").toHex();new Color("#3498db");
new Color("rgb", 52, 152, 219);
new Color("hsl", 204, 0.7, 0.53);
new Color("lab", 60, -5, -40);
new Color(new Color("#ff00ff")); // clone
new Color("oklab", new Color("#ff00ff")); // convert
new Color("rgb(255, 0, 0)");
new Color("hsl(280, 70%, 30%)");
new Color("lab(50, 40, 20)");const c = new Color("#ff8800");
c.r; // red channel
c.hue; // hue (HSL)
c.lightness; // lightness (HSL)
c.alpha; // alpha
c.r = 200;
c.hue = 120;c.toSpace("lab");
c.toSpace("oklch");
c.toSpace("cmyk");c.toString(); // rgb(...)
c.toString("hsl", 2); // hsl with precision
c.toHex(); // #RRGGBBAA
c.toHex(true, true); // compressed hex if possible
// Custom String Formatting:
c.toStringFmt("H:%h S:%s L:%li A:%a");import { blend } from "bismuth-color";
const base = new Color("#3366ff");
const top = new Color("#ff6600");
base.blend(top, "multiply");
base.blend(top, "overlay");
base.blend(top, (a, b) => (a + b) / 2);c.lighten(0.2);
c.darken(0.1);
c.tint(0.3);
c.shade(0.4);
c.hueRotate(45);import { lerp } from "bismuth-color";
lerp(
new Color("#ff0000"),
new Color("#0000ff"),
0.5,
"lab"
);import { contrast, isWCAGCompliant } from "bismuth-color";
contrast(text, background);
isWCAGCompliant(
text,
background,
"small",
"AA"
);import {
diff_RGB,
diff_CIE76,
diff_CIE94,
diff_deltaE
} from "bismuth-color";
diff_deltaE(c1, c2);import { nearestColorName } from "bismuth-color";
nearestColorName(new Color("#f44336")); // "red"