Color Thief
Extract dominant colors and palettes from images in the browser and Node.js.

Install
npm install colorthief
Or load directly from a CDN:
<script src="https://unpkg.com/colorthief@3/dist/umd/color-thief.global.js"></script>
Quick Start
import { getColorSync, getPaletteSync, getSwatches } from 'colorthief';
const color = getColorSync(img);
color.hex();
color.css();
color.isDark;
color.textColor;
const palette = getPaletteSync(img, { colorCount: 6 });
palette.forEach(c => console.log(c.hex()));
const swatches = await getSwatches(img);
swatches.Vibrant?.color.hex();
Features
- TypeScript — full type definitions included
- Browser + Node.js — same API, both platforms
- Sync & async — synchronous browser API, async for Node.js and Web Workers
- Live extraction —
observe() watches video, canvas, or img elements and emits palette updates reactively
- Web Workers — offload quantization off the main thread with
worker: true
- Progressive extraction — 3-pass refinement for instant rough results
- OKLCH quantization — perceptually uniform palettes via
colorSpace: 'oklch'
- Semantic swatches — Vibrant, Muted, DarkVibrant, DarkMuted, LightVibrant, LightMuted
- Rich Color objects —
.hex(), .rgb(), .hsl(), .oklch(), .css(), contrast ratios, text color recommendations
- WCAG contrast —
color.contrast.white, color.contrast.black, color.contrast.foreground
- AbortSignal — cancel in-flight extractions
- CLI —
colorthief photo.jpg with JSON, CSS, and ANSI output
- Zero runtime dependencies
API at a Glance
getColorSync(source, options?) | Dominant color (sync, browser only) |
getPaletteSync(source, options?) | Color palette (sync, browser only) |
getSwatchesSync(source, options?) | Semantic swatches (sync, browser only) |
getColor(source, options?) | Dominant color (async, browser + Node.js) |
getPalette(source, options?) | Color palette (async, browser + Node.js) |
getSwatches(source, options?) | Semantic swatches (async, browser + Node.js) |
getPaletteProgressive(source, options?) | 3-pass progressive palette (async generator) |
observe(source, options) | Watch a source and emit palette updates (browser only) |
createColor(r, g, b, population) | Build a Color object from RGB values |
Options
colorCount | 10 | Number of palette colors (2–20) |
quality | 10 | Sampling rate (1 = every pixel, 10 = every 10th) |
colorSpace | 'oklch' | Quantization space: 'rgb' or 'oklch' |
worker | false | Offload to Web Worker (browser only) |
signal | — | AbortSignal to cancel extraction |
ignoreWhite | true | Skip white pixels |
Color Object
.rgb() | { r, g, b } |
.hex() | '#ff8000' |
.hsl() | { h, s, l } |
.oklch() | { l, c, h } |
.css(format?) | 'rgb(255, 128, 0)', 'hsl(…)', or 'oklch(…)' |
.array() | [r, g, b] |
.toString() | Hex string (works in template literals) |
.textColor | '#ffffff' or '#000000' |
.isDark / .isLight | Boolean |
.contrast | { white, black, foreground } — WCAG ratios |
.population | Raw pixel count |
.proportion | 0–1 share of total |
Browser
import { getColorSync, getPaletteSync } from 'colorthief';
const img = document.querySelector('img');
const color = getColorSync(img);
console.log(color.hex());
const palette = getPaletteSync(img, { colorCount: 5 });
Accepts HTMLImageElement, HTMLCanvasElement, HTMLVideoElement, ImageData, ImageBitmap, and OffscreenCanvas.
import { observe } from 'colorthief';
const controller = observe(videoElement, {
throttle: 200,
colorCount: 5,
onChange(palette) {
updateAmbientBackground(palette);
},
});
controller.stop();
Works with <video>, <canvas>, and <img> elements. For images, it uses a MutationObserver to detect src changes. For video and canvas, it polls using requestAnimationFrame with throttle.
Node.js
import { getColor, getPalette } from 'colorthief';
const color = await getColor('/path/to/image.jpg');
console.log(color.hex());
const palette = await getPalette(Buffer.from(data), { colorCount: 5 });
Accepts file paths and Buffers. Uses sharp for image decoding.
CLI
Quick start
npx colorthief-cli photo.jpg
The colorthief-cli package bundles everything needed (including sharp for image
decoding), so it works immediately with no extra setup.
Commands
colorthief-cli photo.jpg
colorthief-cli palette photo.jpg
colorthief-cli swatches photo.jpg
Output formats
colorthief-cli photo.jpg
colorthief-cli photo.jpg --json
colorthief-cli palette photo.jpg --css
Options
colorthief-cli palette photo.jpg --count 5
colorthief-cli photo.jpg --quality 1
colorthief-cli photo.jpg --color-space rgb
Stdin is supported — use - or pipe directly:
cat photo.jpg | colorthief-cli -
Multiple files are supported. Output is prefixed with filenames, and --json wraps
results in an object keyed by filename.
Note: If you already have colorthief and sharp installed in a project, you
can also use colorthief directly as the command name (without the -cli suffix).
Links
Contributing
npm run build
npm run test
npm run test:node
npm run test:browser
npm run dev
Releasing
git status
npm run build
npm run test:node
npm run test:browser
npm pack --dry-run
npm version <major|minor|patch>
npm publish
git push && git push --tags
License
MIT - Lokesh Dhakar