color-thief
Grab the color palette from an image using just Javascript. Works in the browser and in Node.
Top Related Projects
A JavaScript library for binding keyboard combos without the pain of key codes and key combo conflicts.
Extract prominent colors from an image. JS port of Android's Palette.
Fast, small color manipulation and conversion for JavaScript
JavaScript library for all kinds of color manipulations
Quick Overview
Color Thief is a JavaScript library that extracts the dominant color or a color palette from an image. It uses a fast, quality-driven algorithm to analyze the image and return the most prominent colors, making it useful for dynamic theming, color-based UI adjustments, and image analysis.
Pros
- Easy to use with a simple API
- Works with both browser and Node.js environments
- Supports various image formats (PNG, JPEG, GIF)
- Lightweight and has no dependencies
Cons
- May not always accurately represent the perceived dominant color
- Performance can be slow for large images
- Limited customization options for color extraction algorithm
- Requires image to be fully loaded before analysis
Code Examples
Getting the dominant color:
const colorThief = new ColorThief();
const img = document.querySelector('img');
const dominantColor = colorThief.getColor(img);
console.log(dominantColor); // Returns [R, G, B]
Extracting a color palette:
const colorThief = new ColorThief();
const img = document.querySelector('img');
const palette = colorThief.getPalette(img, 5); // Get 5 dominant colors
console.log(palette); // Returns [[R, G, B], [R, G, B], ...]
Using with Node.js:
const ColorThief = require('colorthief');
ColorThief.getColor('path/to/image.jpg')
.then(color => console.log(color))
.catch(err => console.log(err));
Getting Started
-
Install Color Thief:
npm install colorthief -
Include the library in your project:
<script src="node_modules/colorthief/dist/color-thief.min.js"></script> -
Use Color Thief in your JavaScript:
const colorThief = new ColorThief(); const img = document.querySelector('img'); if (img.complete) { console.log(colorThief.getColor(img)); } else { img.addEventListener('load', function() { console.log(colorThief.getColor(img)); }); }
This setup allows you to extract colors from images in your web application. Make sure the image is fully loaded before calling Color Thief methods to ensure accurate results.
Competitor Comparisons
A JavaScript library for binding keyboard combos without the pain of key codes and key combo conflicts.
Pros of KeyboardJS
- Focuses on keyboard event handling and key binding, providing a specialized solution for keyboard interactions
- Offers a more comprehensive API for managing keyboard shortcuts and combinations
- Supports complex key sequences and multiple key presses
Cons of KeyboardJS
- Limited to keyboard-related functionality, unlike Color Thief's broader color extraction capabilities
- May have a steeper learning curve for developers not familiar with advanced keyboard event handling
- Potentially unnecessary for projects that don't require extensive keyboard interaction features
Code Comparison
KeyboardJS:
KeyboardJS.bind('ctrl + shift + a', function(e) {
console.log('Ctrl + Shift + A was pressed');
});
Color Thief:
const colorThief = new ColorThief();
const dominantColor = colorThief.getColor(imageElement);
console.log(dominantColor);
Summary
KeyboardJS is a specialized library for handling keyboard events and creating complex key bindings, while Color Thief focuses on extracting color information from images. KeyboardJS offers more advanced keyboard interaction features but is limited to that specific functionality. Color Thief, on the other hand, provides a simpler API for color-related tasks but lacks keyboard event handling capabilities. The choice between these libraries depends on the specific requirements of your project, whether it's focused on keyboard interactions or color extraction from images.
Extract prominent colors from an image. JS port of Android's Palette.
Pros of Vibrant.js
- Provides a more diverse color palette, including vibrant, muted, and dark variants
- Offers better performance for larger images due to its downsampling technique
- Includes TypeScript support out of the box
Cons of Vibrant.js
- Less actively maintained compared to Color Thief
- Slightly more complex API, which may require a steeper learning curve
- Limited browser support for older versions
Code Comparison
Color Thief:
const colorThief = new ColorThief();
const dominantColor = colorThief.getColor(imageElement);
const palette = colorThief.getPalette(imageElement, 5);
Vibrant.js:
Vibrant.from(imageElement).getPalette((err, palette) => {
const vibrantColor = palette.Vibrant.hex;
const mutedColor = palette.Muted.hex;
});
Both libraries aim to extract dominant colors from images, but they differ in their approach and output. Color Thief focuses on providing a simple, straightforward color extraction, while Vibrant.js offers a more comprehensive color palette with various color types. The choice between the two depends on the specific needs of your project, such as the desired color variety, performance requirements, and target browser support.
Fast, small color manipulation and conversion for JavaScript
Pros of TinyColor
- More comprehensive color manipulation functions (e.g., lighten, darken, complement)
- Supports a wider range of color formats (RGB, HSL, HSV, HEX)
- Smaller file size and faster performance for color operations
Cons of TinyColor
- Does not extract colors from images (Color Thief's primary function)
- Less focused on color palette generation
- May require additional processing for image-based color operations
Code Comparison
TinyColor:
var color = tinycolor("red");
console.log(color.toHexString()); // "#ff0000"
console.log(color.lighten(20).toHexString()); // "#ff6666"
Color Thief:
var colorThief = new ColorThief();
var dominantColor = colorThief.getColor(sourceImage);
console.log(dominantColor); // [r, g, b]
Summary
TinyColor is a versatile color manipulation library, offering a wide range of color operations and format support. It excels in programmatic color handling but lacks image color extraction capabilities. Color Thief, on the other hand, specializes in extracting color palettes from images, making it more suitable for image-based color analysis. The choice between the two depends on whether the primary need is color manipulation (TinyColor) or image color extraction (Color Thief).
JavaScript library for all kinds of color manipulations
Pros of chroma.js
- More comprehensive color manipulation library with a wide range of functions
- Supports various color spaces and color scales
- Offers advanced features like color interpolation and color harmonies
Cons of chroma.js
- Larger file size and potentially more complex to use for simple tasks
- May have a steeper learning curve for beginners
- Focuses on color manipulation rather than color extraction from images
Code Comparison
color-thief:
const colorThief = new ColorThief();
const dominantColor = colorThief.getColor(imageElement);
console.log(dominantColor); // [r, g, b]
chroma.js:
const color = chroma('#ff0000');
const darkerColor = color.darken();
console.log(darkerColor.hex()); // '#cc0000'
Summary
Color Thief is primarily focused on extracting colors from images, making it ideal for tasks like generating color palettes from uploaded images or analyzing dominant colors in photographs. It's lightweight and easy to use for these specific tasks.
Chroma.js, on the other hand, is a more comprehensive color manipulation library. It offers a wide range of functions for working with colors, including color space conversions, color scales, and advanced color operations. While it doesn't focus on color extraction from images, it provides powerful tools for manipulating and analyzing colors in various contexts.
The choice between these libraries depends on the specific requirements of your project. If you need to extract colors from images, Color Thief is the better option. For more advanced color manipulation and analysis, Chroma.js would be the preferred choice.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
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';
// Dominant color
const color = getColorSync(img);
color.hex(); // '#e84393'
color.css(); // 'rgb(232, 67, 147)'
color.isDark; // false
color.textColor; // '#000000'
// Palette
const palette = getPaletteSync(img, { colorCount: 6 });
palette.forEach(c => console.log(c.hex()));
// Semantic swatches (Vibrant, Muted, DarkVibrant, etc.)
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.jpgwith JSON, CSS, and ANSI output - Zero runtime dependencies
API at a Glance
| Function | Description |
|---|---|
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
| Option | Default | Description |
|---|---|---|
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
| Property / Method | Returns |
|---|---|
.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.
Live extraction with observe()
import { observe } from 'colorthief';
// Watch a video and update ambient lighting as it plays
const controller = observe(videoElement, {
throttle: 200, // ms between updates
colorCount: 5,
onChange(palette) {
updateAmbientBackground(palette);
},
});
// Stop when done
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
# Dominant color
colorthief-cli photo.jpg
# Color palette
colorthief-cli palette photo.jpg
# Semantic swatches
colorthief-cli swatches photo.jpg
Output formats
# Default: ANSI color swatches
colorthief-cli photo.jpg
# ââ #e84393
# JSON with full color data
colorthief-cli photo.jpg --json
# CSS custom properties
colorthief-cli palette photo.jpg --css
# :root {
# --color-1: #e84393;
# --color-2: #6c5ce7;
# }
Options
colorthief-cli palette photo.jpg --count 5 # Number of colors (2-20)
colorthief-cli photo.jpg --quality 1 # Sampling quality (1=best)
colorthief-cli photo.jpg --color-space rgb # Color space (rgb or oklch)
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
colorthiefandsharpinstalled in a project, you can also usecolorthiefdirectly as the command name (without the-clisuffix).
Links
Contributing
npm run build # Build all dist formats
npm run test # Run all tests (Mocha + Cypress)
npm run test:node # Node tests only
npm run test:browser # Browser tests (requires npm run dev)
npm run dev # Start local server on port 8080
Releasing
# 1. Make sure you're on master with a clean working tree
git status
# 2. Run the full test suite
npm run build
npm run test:node
npm run test:browser # requires npm run dev in another terminal
# 3. Preview what will be published
npm pack --dry-run
# 4. Tag and publish
npm version <major|minor|patch> # bumps version, creates git tag
npm publish # builds via prepublishOnly, then publishes
git push && git push --tags
License
MIT - Lokesh Dhakar
Top Related Projects
A JavaScript library for binding keyboard combos without the pain of key codes and key combo conflicts.
Extract prominent colors from an image. JS port of Android's Palette.
Fast, small color manipulation and conversion for JavaScript
JavaScript library for all kinds of color manipulations
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot