@bobfrankston/colorlib
v0.1.10
Published
Color conversion library for RGB, HSL, HSB, HSBK and Kelvin
Readme
@bobfrankston/colorlib
Colour conversion between RGB, HSL, HSB, HSBK and Kelvin, plus one flexible parser.
Pure TypeScript, no dependencies, works in the browser and in Node — with one exception, named colours, described below.
import { parseColor, rgbToHsbk, kelvinToRgb, HSBK } from '@bobfrankston/colorlib';
parseColor('#ff8800') // { h: 32, s: 100, b: 100, k: 3500 }
parseColor('rgb(255,136,0)') // same
parseColor('hsl(32,100%,50%)') // same
parseColor(2700) // white at 2700K: { h: 0, s: 0, b: 100, k: 2700 }
parseColor({ r: 255, g: 136, b: 0 })Types
| type | fields |
|---|---|
| RGB | r, g, b — 0-255 |
| HSL | h 0-360, s 0-100, l 0-100 |
| HSB | h 0-360, s 0-100, b 0-100 |
| HSBK | h 0-360, s 0-100, b 0-100, k Kelvin 1500-9000 |
| HSBK16 | the same scaled to 0-0xFFFF for wire protocols; k stays in Kelvin |
| ColorInput | string | number | RGB | HSL | HSB | HSBK |
Guards: isRGB, isHSL, isHSB, isHSBK.
Kelvin defaults: DEFAULT_KELVIN 3500, range 1500-9000. A bare number passed to parseColor is
read as a colour temperature and must be in that range.
Conversions
rgbToHsl hslToRgb rgbToHsb hsbToRgb hslToHsb hsbToHsl
rgbToHsbk hslToHsbk hsbToHsbk (each takes an optional kelvin, default 3500)
kelvinToRgb hsbkTo16 hsbk16ToHsbk⚠️ Named colours are browser-only
parseColor('red') works in a browser and throws under Node.
There is no colour table in this library. parseNamed (parse.ts:45) creates a canvas, assigns the
name to fillStyle, and reads back whatever the browser resolved:
const ctx = canvas.getContext('2d');
ctx.fillStyle = name; // the browser's own CSS parser does the workIn a browser that is a good trade: you inherit the entire CSS keyword list, always current, for zero
bytes of data. Outside one there is no document, the guard fails, and every name — including
red — throws Unknown color name.
Everything else works everywhere. #rrggbb, #rgb, rgb(...), hsl(...), Kelvin numbers and
all the object forms are pure arithmetic and have no DOM dependency.
What to do in Node
Resolve the name first, then hand the hex to parseColor. @bobfrankston/rmfc already carries the
full CSS table (aliceblue through rebeccapurple) behind colorToHex, which returns its input
unchanged when it does not know a name:
import { parseColor } from '@bobfrankston/colorlib';
import { colorToHex } from '@bobfrankston/rmfc';
function anyColor(text: string) {
try { return parseColor(text); } // #hex, rgb(), hsl(), Kelvin, objects
catch {
const hex = colorToHex(text.trim()); // rmfc owns colour NAMES
if (!hex.startsWith('#')) throw new Error(`unknown colour "${text}"`);
return parseColor(hex); // colorlib owns colour MATHS
}
}That is what utils/setcolor does. rmfc is deliberately not a dependency here: it is a
Node-oriented library and is not in Houser's import map, so depending on it would drag it into the
browser bundle. Keeping the split — rmfc for names, colorlib for maths — costs the caller four
lines and keeps this library dependency-free on both platforms.
(Discovered 2026-09-02 when setcolor -c red failed from the command line while the same call
worked in Houser. Written up by Claude Code at Bob's direction so the next caller does not have to
rediscover it. If colorlib should ever resolve names itself, the options are a shared table both
libraries use, or — since msger can evaluate HTML and return a result — a webview round trip, which
would work but makes parseColor async and adds a host dependency.)
