chroma-js, color, color-convert, and tinycolor are JavaScript libraries designed to handle color operations such as parsing, converting, and manipulating color values. chroma-js focuses heavily on color scales and visualization needs. color provides a robust chainable API for converting and mixing colors. color-convert is a low-level dependency often used for raw conversion between color spaces without object overhead. tinycolor is a legacy library that offers simple parsing and manipulation but is no longer actively maintained. These tools help developers avoid manual math when working with RGB, HSL, HEX, and other color formats in web applications.
Working with color in JavaScript often means dealing with strings, arrays, and math. You might need to turn a HEX code into RGB, lighten a color for a hover state, or generate a gradient scale for a chart. The libraries chroma-js, color, color-convert, and tinycolor all solve these problems, but they take different approaches. Let's look at how they handle real-world tasks.
All four libraries accept common color formats, but their APIs differ in how you create a color instance.
chroma-js uses a function call to create a color object. It auto-detects formats like HEX, RGB, or CSS names.
import chroma from 'chroma-js';
const c1 = chroma('#ff0000');
const c2 = chroma('rgb(255, 0, 0)');
const c3 = chroma('red');
color uses a constructor that requires you to specify the input format or rely on string parsing.
import Color from 'color';
const c1 = Color('#ff0000');
const c2 = Color('rgb(255, 0, 0)');
const c3 = Color('red');
color-convert does not create color objects. It provides functions that convert arrays or values directly. You must know the input space.
import convert from 'color-convert';
// Converts HEX string to RGB array (no object created)
const rgb = convert.hex.rgb('#ff0000');
// Returns [255, 0, 0]
tinycolor uses a function call similar to chroma-js but is less strict with format detection.
import tinycolor from 'tinycolor2';
const c1 = tinycolor('#ff0000');
const c2 = tinycolor('rgb(255, 0, 0)');
const c3 = tinycolor('red');
Getting data out in the right format is crucial for CSS or Canvas rendering.
chroma-js offers specific methods for each format. It handles alpha channels cleanly.
import chroma from 'chroma-js';
const c = chroma('#ff0000');
console.log(c.hex()); // "#ff0000"
console.log(c.rgb()); // [255, 0, 0]
console.log(c.css()); // "rgb(255, 0, 0)"
console.log(c.hsl()); // [0, 1, 0.5]
color uses chainable methods that return new color instances or strings.
import Color from 'color';
const c = Color('#ff0000');
console.log(c.hex()); // "#ff0000"
console.log(c.rgb().array()); // [255, 0, 0]
console.log(c.string()); // "rgb(255, 0, 0)"
console.log(c.hsl().string()); // "hsl(0, 100%, 50%)"
color-convert exports a map of conversion functions. You call the specific path you need.
import convert from 'color-convert';
console.log(convert.hex.rgb('#ff0000')); // [255, 0, 0]
console.log(convert.rgb.hex([255, 0, 0])); // "ff0000"
console.log(convert.rgb.hsl([255, 0, 0])); // [0, 100, 50]
tinycolor provides methods on the instance similar to chroma-js.
import tinycolor from 'tinycolor2';
const c = tinycolor('#ff0000');
console.log(c.toHexString()); // "#ff0000"
console.log(c.toRgb()); // {r: 255, g: 0, b: 0, a: 1}
console.log(c.toRgbString()); // "rgb(255, 0, 0)"
console.log(c.toHsl()); // {h: 0, s: 100, l: 50}
This is where the libraries diverge significantly. Some focus on math, others on design workflows.
chroma-js is built for scales. It excels at interpolation and luminance adjustments.
import chroma from 'chroma-js';
// Brighten by changing luminance
const c = chroma('#ff0000');
const brighter = c.brighten(1);
// Mix two colors (50%)
const mixed = chroma.mix('#ff0000', '#0000ff', 0.5);
color offers a wide range of design-focused operations with a fluent interface.
import Color from 'color';
// Lighten by percentage
const c = Color('#ff0000');
const lighter = c.lighten(0.1);
// Mix two colors
const mixed = c.mix(Color('#0000ff'), 0.5);
color-convert does not support manipulation. It only converts. You would need to write your own math for lightening or mixing.
import convert from 'color-convert';
// No manipulation methods exist.
// You must manually adjust RGB/HSL values before converting back.
const hsl = convert.hex.hsl('#ff0000');
hsl[2] = hsl[2] + 10; // Manually increase lightness
const newHex = convert.hsl.hex(hsl);
tinycolor supports basic manipulation but the API is older and less consistent.
import tinycolor from 'tinycolor2';
// Lighten by percentage
const c = tinycolor('#ff0000');
const lighter = c.lighten(10);
// Mix two colors
const mixed = tinycolor.mix('#ff0000', '#0000ff', 50);
For data visualization, you often need a range of colors between two points.
chroma-js is the industry standard for this. It has a dedicated scale API.
import chroma from 'chroma-js';
const scale = chroma.scale(['#f00', '#00f']);
const colors = scale.colors(5);
// Returns array of 5 colors between red and blue
color does not have built-in scale generation. You must map values manually.
import Color from 'color';
const start = Color('#f00');
const end = Color('#00f');
// Manual interpolation
const colors = Array.from({ length: 5 }, (_, i) => {
return start.mix(end, i / 4).hex();
});
color-convert has no concept of scales. It is a utility for single-value conversion.
import convert from 'color-convert';
// No scale functionality.
// Requires manual implementation of interpolation logic.
tinycolor lacks built-in scale generation similar to color.
import tinycolor from 'tinycolor2';
// Manual interpolation required
const colors = [];
for (let i = 0; i < 5; i++) {
colors.push(tinycolor.mix('#f00', '#00f', i * 25).toHexString());
}
Choosing a library also means choosing its maintenance status.
chroma-js is actively maintained and widely used in the visualization community. It receives updates for color science accuracy.
color is stable and maintained. It is a dependency for many other UI libraries, ensuring it stays compatible with modern Node and browser environments.
color-convert is stable but changes rarely. It is a low-level utility. It is safe to use but offers no high-level features.
tinycolor is effectively deprecated. The original repo is archived. tinycolor2 is the version on npm, but it sees very little activity. New projects should avoid it to prevent technical debt.
| Feature | chroma-js | color | color-convert | tinycolor |
|---|---|---|---|---|
| Primary Use | Visualization & Scales | UI Manipulation | Raw Conversion | Legacy Simple Tasks |
| API Style | Functional / Object | Chainable Object | Static Functions | Object / Functional |
| Scales | β Built-in | β Manual | β None | β Manual |
| Manipulation | β Advanced | β Design-focused | β None | β Basic |
| Status | β Active | β Active | β Stable | β οΈ Deprecated |
chroma-js is the specialist π§ͺ. If you are building charts, maps, or anything data-driven, this is the only choice that makes sense. Its scale API saves weeks of math.
color is the generalist π¨. If you are building a design system, a theme editor, or just need to darken a button on hover, this offers the best developer experience with its chainable API.
color-convert is the utility π§. Use it if you are writing a build tool, a CSS preprocessor plugin, or need to convert values in a pipeline without creating objects.
tinycolor is the legacy code πΈοΈ. It works, but it belongs in the past. If you see it in a new package.json, suggest replacing it with color or chroma-js depending on the use case.
Final Thought: Color math is harder than it looks. Perceptual uniformity, alpha blending, and gamut mapping are tricky. Don't write your own unless you have to. Pick the tool that matches your domain β visualization or UI β and let the library handle the math.
Choose chroma-js if you are building data visualizations, heatmaps, or need advanced color scales and interpolation. It excels at generating ramps between colors and handling perceptual uniformity. It is the best fit for D3.js integrations or scientific dashboards where color accuracy matters.
Choose color if you need a general-purpose color library with a chainable API for web development tasks. It supports mixing, lightening, darkening, and converting between formats easily. It is ideal for theme generators, design systems, or dynamic UI styling where you need to modify base colors.
Choose color-convert if you only need raw conversion functions between color spaces without the overhead of an object-oriented wrapper. It is best used as a utility within a larger build process or when bundle size is critical and you only need conversion logic, not manipulation.
Avoid tinycolor for new projects as it is no longer actively maintained. While it is lightweight and simple, it lacks modern features and security updates. If you are maintaining legacy code that uses it, consider migrating to color or chroma-js for better long-term support.
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