color2k
A color parsing and manipulation library for JavaScript that ships in roughly 2kB, covering hex, RGB, HSL, and named CSS colors.
Repository Health
Technical Analysis
color2k is a lightweight color parsing and manipulation library built for situations where every kilobyte of bundle size matters. It accepts the color formats developers already use day to day — hex, rgb()/rgba(), hsl()/hsla(), CSS named colors, and transparent — and exposes a set of small, tree-shakeable functions for reading and transforming them: adjusting hue, lightening or darkening, saturating or desaturating, mixing two colors together, computing luminance and WCAG contrast ratios, and picking a readable text color against a given background.
The library’s core selling point is size. Where comparable libraries like chroma-js, polished, and tinycolor2 range from 5kB to nearly 14kB, color2k’s full bundle comes in around 2.8kB and can shrink further with tree shaking, since each function is published and exported independently with sideEffects: false. It has zero runtime dependencies, is written entirely in TypeScript with generated .d.ts output, and is distributed as CJS, ESM, and a UMD build for direct <script>/CDN use.
color2k is commonly reached for inside CSS-in-JS setups (Emotion, styled-components) and design-system code where colors need to be derived programmatically — for example computing a hover-state shade from a brand color, or checking contrast for accessibility compliance — without pulling in a general-purpose color library that duplicates the CSS parsing the browser already does.
What You Get
- Format-agnostic parsing -
parseToRgbaandparseToHslaaccept hex,rgb(),hsl(), CSS named colors, andtransparent, normalizing them into numeric channel tuples. - Color adjustment functions -
darken,lighten,saturate,desaturate,adjustHue,opacify, andtransparentizeeach perform one focused transformation and return a color string. - Color mixing -
mixblends two colors using the same weighted algorithm as Sass’smix()function, accounting for alpha channel differences. - Accessibility helpers -
getContrast,getLuminance,hasBadContrast, andreadableColorimplement WCAG relative luminance and contrast ratio math to pick readable text colors. - Scale generation -
getScaleproduces an evenly interpolated array of colors between two endpoints, useful for gradients or data-visualization ramps. - Zero dependencies, tree-shakeable - every function is a separate module with
sideEffects: false, so bundlers only include what’s actually imported.
Common Use Cases
- Deriving hover/active states - a design system computes a darker or lighter shade of a brand color at runtime instead of hand-authoring every state.
- Accessibility contrast checks - a component library uses
getContrast/hasBadContrastto validate or auto-correct text-on-background color pairs. - CSS-in-JS theming - Emotion/styled-components themes mix or adjust a small palette of base colors into the full set of shades a design needs.
- Data visualization color ramps -
getScalegenerates a gradient of colors for charts or heatmaps from a start and end color. - Parsing user-supplied colors - an app that accepts arbitrary color input (hex, rgba, named) normalizes it to a single format before storing or rendering.
Under The Hood
Architecture
color2k has no central runtime or class hierarchy — it’s a flat collection of independent pure functions (in src/) that each import only the small parsing/formatting helpers they need (parseToRgba, parseToHsla, guard, ColorError), re-exported from a single index.ts barrel file. parseToRgba is the foundational primitive: it runs a color string through a sequence of regex matchers (reduced hex, hex, rgb(), hsl(), named colors) and returns a normalized [r, g, b, a] tuple that every other transform (mix, darken, getContrast, etc.) builds on. This flat, function-per-file structure means the core abstraction to worry about is the parsing pipeline in parseToRgba.ts — if its regex matching or channel normalization changes, every downstream color function is affected, but the functions themselves have no interdependencies on each other.
Tech Stack
The library is authored in TypeScript with zero runtime dependencies, targeting sideEffects: false for tree shaking. It builds with Rollup (rollup.config.mjs) into CJS, ES module, and UMD bundles plus generated .d.ts types, and uses Babel (@babel/preset-env + @babel/preset-typescript) for the ESLint parser and test transforms rather than for the production build itself. Releases are automated via semantic-release, and the package explicitly opts into npm provenance (publishConfig.provenance).
Code Quality
Every exported function has a co-located *.test.ts file using Jest, including inline snapshot assertions (toMatchInlineSnapshot) for expected color outputs across many input permutations — the test suite is comprehensive relative to the library’s small surface area. Linting runs via a flat ESLint config with the Babel parser for TypeScript support, and the CI pipeline (GitHub Actions) runs lint, tests with coverage, a full build, doc generation checks, and a production dependency audit before any release, indicating a strict quality gate despite the library’s small size.
What Makes It Unique color2k’s differentiator is deliberately narrow scope rather than novel algorithms — it reimplements well-known color math (Sass’s mix algorithm, WCAG relative luminance/contrast formulas) but optimizes hard for bundle size by publishing every function as an independently tree-shakeable module with no shared runtime dependencies, landing at roughly half the size of the next-smallest comparable library.
Used by 2 apps in this directory
Chatwoot
Customer Support
Open-source omnichannel customer support platform with AI-powered agents, live chat, and self-hosting — a full Intercom and Zendesk alternative.
Sanity
CMS
Open-source headless CMS with a fully customizable React Studio, real-time collaborative editing, structured content modeling, and GROQ query language