npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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 work

In 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.)