chroma-js, color, color-convert, rgb-hex, rgb2hex, and tinycolor2 are all JavaScript libraries designed to handle color manipulation, conversion, and analysis in web applications. They enable developers to parse color values, convert between formats (like RGB, HSL, HEX, LAB), adjust brightness or saturation, generate palettes, and perform accessibility checks. While they share overlapping capabilities, each package targets different use cases — from ultra-lightweight single-purpose utilities (rgb-hex) to full-featured toolkits for data visualization (chroma-js) or production-grade UI systems (tinycolor2).
When building modern web applications, developers often need to work with colors—converting between formats, adjusting brightness or saturation, generating palettes, or ensuring accessibility. The JavaScript ecosystem offers several well-maintained libraries for these tasks, each with its own focus and trade-offs. Let’s compare chroma-js, color, color-convert, rgb-hex, rgb2hex, and tinycolor2 from a practical, engineering perspective.
chroma-js is a full-featured color library designed for designers and data visualizers. It supports advanced operations like interpolation, color scales, and perceptually uniform adjustments (e.g., lightness in CIELAB space). It handles a wide range of input formats and excels at creating smooth gradients or diverging palettes.
// chroma-js: Interpolate between red and blue in Lab space
const gradient = chroma.scale(['red', 'blue']).mode('lab');
const midColor = gradient(0.5).hex(); // '#800080' (purple)
color (by Qix-) provides a fluent, chainable API focused on conversions and basic manipulations. It wraps color-convert under the hood but adds methods for lightening, darkening, rotating hue, etc. It’s ideal when you need readable, expressive code without heavy dependencies.
// color: Chainable transformations
const adjusted = color('#ff0000').lighten(0.2).saturate(0.1).hex();
color-convert is a low-level, zero-dependency utility strictly for converting between color spaces (RGB, HSL, HSV, XYZ, LAB, etc.). It doesn’t parse strings or offer manipulation methods—just pure math functions. Use it when you already have numeric values and need fast, direct conversion.
// color-convert: Direct numeric conversion
const [h, s, l] = convert.rgb.hsl(255, 0, 0); // [0, 100, 50]
rgb-hex and rgb2hex are ultra-lightweight utilities that do one thing: convert RGB values (as numbers or arrays) to hex strings. They don’t support other formats or manipulations. rgb-hex is actively maintained; rgb2hex appears unmaintained and redundant.
// rgb-hex: Simple RGB → hex
const hex1 = rgbHex(255, 0, 0); // '#ff0000'
const hex2 = rgbHex([255, 0, 0]); // '#ff0000'
// rgb2hex: Same functionality, but less flexible
const hex3 = rgb2hex(255, 0, 0); // '#ff0000'
tinycolor2 is a battle-tested, all-in-one solution used in projects like Bootstrap. It supports parsing almost any color format, offers extensive manipulation methods (brighten, spin, mix), and includes utilities for readability and contrast checks. Its API is imperative rather than chainable.
// tinycolor2: Parse and manipulate
const tc = tinycolor('#f00');
const lighter = tc.lighten(20).toHexString(); // '#ff6666'
const isDark = tc.isDark(); // true
How each library handles input varies significantly:
chroma-js: Accepts hex, named colors, RGB/RGBA arrays, HSL strings, and more. Very forgiving.
chroma('red');
chroma([255, 0, 0]);
chroma('hsl(0, 100%, 50%)');
color: Similar flexibility—strings, objects, arrays.
color('red');
color({r: 255, g: 0, b: 0});
color([255, 0, 0]);
color-convert: Only accepts numeric arguments—no string parsing.
convert.rgb.hsl(255, 0, 0); // works
convert.rgb.hsl('red'); // throws error
rgb-hex / rgb2hex: Accept either three numbers or an array of three numbers.
rgbHex(255, 0, 0);
rgbHex([255, 0, 0]);
tinycolor2: Extremely permissive—handles CSS strings, objects, arrays, even malformed inputs gracefully.
tinycolor('red');
tinycolor({r: 255, g: 0, b: 0});
tinycolor('rgb(255, 0, 0)');
All libraries can do this, but with different ergonomics:
// chroma-js
chroma(255, 0, 0).hex(); // '#ff0000'
// color
color.rgb(255, 0, 0).hex(); // '#ff0000'
// color-convert (requires manual formatting)
const [r, g, b] = [255, 0, 0];
'#' + [r, g, b].map(x => x.toString(16).padStart(2, '0')).join('');
// rgb-hex
rgbHex(255, 0, 0); // '#ff0000'
// rgb2hex
rgb2hex(255, 0, 0); // '#ff0000'
// tinycolor2
tinycolor({r: 255, g: 0, b: 0}).toHexString(); // '#ff0000'
Only higher-level libraries support this:
// chroma-js
chroma('red').brighten(1).hex(); // '#ff6666'
// color
color('red').lighten(0.2).hex(); // '#ff6666'
// tinycolor2
tinycolor('red').lighten(20).toHexString(); // '#ff6666'
// color-convert, rgb-hex, rgb2hex: Not supported
Only chroma-js and tinycolor2 provide built-in accessibility tools:
// chroma-js
chroma.contrast('white', 'black'); // 21 (maximum)
// tinycolor2
tinycolor.readability('white', 'black'); // 21
// Others: Not supported
Use chroma-js if you’re building data visualizations, design systems, or need perceptually accurate interpolations. Its support for LAB, LCH, and custom color scales is unmatched.
color strikes a great balance between power and simplicity. It’s perfect for UI theming, dynamic color adjustments, or when you prefer functional-style chaining.
color-convert is your go-to. It’s tiny, dependency-free, and blazing fast—ideal for performance-critical paths where you control input format.
rgb-hex is sufficient. Avoid rgb2hex—it offers no advantages and appears unmaintained.
tinycolor2 has been tested in production for years (used in Bootstrap, Photoshop plugins, etc.). Its error tolerance, wide format support, and accessibility helpers make it reliable for user-facing tools.
rgb2hex: Last published in 2016. No GitHub repository linked on npm. Consider it deprecated—use rgb-hex instead.chroma-js, color, color-convert, rgb-hex, tinycolor2) are actively maintained as of 2024.| Package | Parsing | Manipulation | Color Spaces | Accessibility | Bundle Impact | Best For |
|---|---|---|---|---|---|---|
chroma-js | ✅ Rich | ✅ Advanced | ✅ Many (LAB, LCH, etc.) | ✅ Contrast ratio | Medium | Data viz, design systems |
color | ✅ Good | ✅ Basic | ✅ Standard (RGB, HSL, etc.) | ❌ | Small | UI theming, readable code |
color-convert | ❌ None | ❌ None | ✅ Many (numeric only) | ❌ | Tiny | Low-level conversion |
rgb-hex | ❌ RGB only | ❌ None | ❌ RGB → Hex only | ❌ | Minimal | Simple RGB→hex needs |
rgb2hex | ❌ RGB only | ❌ None | ❌ RGB → Hex only | ❌ | Minimal | ❌ Avoid—use rgb-hex |
tinycolor2 | ✅ Excellent | ✅ Extensive | ✅ Standard + extras | ✅ Readability | Medium | Production UIs, editors |
rgb(255,0,0) → #ff0000, use rgb-hex.rgb2hex; everything else is safe for production.color’s chainable API is easier to read; tinycolor2’s imperative style is more familiar to jQuery-era devs.Choose based on your actual needs—not just features, but also maintainability, bundle size, and how the API fits into your codebase.
Choose chroma-js when you need advanced color operations like perceptually uniform interpolation, multi-stop color scales, or support for color spaces beyond RGB/HSL (e.g., CIELAB, LCH). It’s ideal for data visualization, design systems, or applications requiring precise color math. Avoid it if you only need basic conversions—it’s heavier than necessary for simple tasks.
Choose color when you want a clean, chainable API for common color manipulations (lighten, darken, rotate) with solid format support. It wraps color-convert but adds developer-friendly syntax. It’s a great middle ground for UI theming or dynamic color adjustments without the weight of larger libraries.
Choose color-convert only when you’re working with raw numeric color values and need fast, dependency-free conversion between color spaces (e.g., RGB to XYZ). It does not parse strings or offer manipulation methods, so it’s best used as a low-level building block inside other tools.
Choose rgb-hex if your sole requirement is converting RGB values (as numbers or arrays) to hexadecimal strings. It’s tiny, well-maintained, and does exactly one thing well. Don’t use it if you need any other color functionality.
Do not choose rgb2hex for new projects. It provides the same narrow functionality as rgb-hex but hasn’t been updated since 2016 and lacks an official repository. Use rgb-hex instead for the same use case with active maintenance.
Choose tinycolor2 when building production UIs, editors, or design tools that require robust parsing of diverse color formats, extensive manipulation methods, and built-in accessibility utilities (like contrast checking). Its battle-tested reliability and comprehensive feature set make it suitable for user-facing applications where error tolerance matters.
Chroma.js is a tiny small-ish zero-dependency JavaScript library for all kinds of color conversions and color scales.
Install from npm
npm install chroma-js
Import package into project
import chroma from "chroma-js";
Initiate and manipulate colors:
chroma('#D4F880').darken().hex(); // #a1c550
Working with color scales is easy, too:
scale = chroma.scale(['white', 'red']);
scale(0.5).hex(); // #FF7F7F
Lab/Lch interpolation looks better than RGB
chroma.scale(['white', 'red']).mode('lab');
Custom domains! Quantiles! Color Brewer!!
chroma.scale('RdYlBu').domain(myValues, 7, 'quantiles');
And why not use logarithmic color scales once in your life?
chroma.scale(['lightyellow', 'navy']).domain([1, 100000], 7, 'log');
Why not dive into the interactive documentation (there's a static version, too). You can download chroma.min.js or use the hosted version on unpkg.com.
You can use it in node.js, too!
npm install chroma-js
Or you can use it in SASS using chromatic-sass!
Come over and say hi in our Discord channel!
First clone the repository and install the dev dependencies:
git clone git@github.com:gka/chroma.js.git
cd chroma.js
npm install
Then compile the coffee-script source files to the build files:
npm run build
Don't forget to tests your changes! You will probably also want to add new test to the /test folder in case you added a feature.
npm test
And to update the documentation just run
npm run docs
To preview the docs locally you can use
npm run docs-preview
Chroma.js is written by Gregor Aisch.
Released under BSD license. Versions prior to 0.4 were released under GPL.
There have been no commits in X weeks. Is chroma.js dead?
No! It's just that the author of this library has other things to do than devoting every week of his life to making cosmetic changes to a piece of software that is working just fine as it is, just so that people like you don't feel like it's abandoned and left alone in this world to die. Bugs will be fixed. Some new things will come at some point. Patience.
I want to help maintaining chroma.js!
Yay, that's awesome! Please say hi at our Discord chat to get in touch