GitHub

logo

Twitter URL

Spectral.js is a lightweight JavaScript library for realistic color mixing based on the Kubelka-Munk theory. It's designed specifically for developers and artists aiming to implement realistic pigment mixing in their projects.


🧭 Design Philosophy

Spectral.js is built on the idea that realistic color mixing should be both accurate and accessible. While most digital color tools rely on linear or additive RGB blending, Spectral.js takes a physically-informed approach by simulating how pigments interact with light using the Kubelka-Munk theory.

The goals behind Spectral.js:

  • 🎨 Physically-based: Pigment mixing is modeled using spectral data and light-matter interaction, not RGB math tricks.
  • βš–οΈ Perceptually aware: Uses color spaces like OKLab and OKLCh for perceptual uniformity and smart gamut mapping.
  • 🧠 Intelligent mixing: Every mix uses luminance, tinting strength, and user-defined intent to calculate effective concentration.
  • πŸš€ Optimized for performance: Lazy memoization and fast math make it lightweight and fast, even in browser environments.
  • πŸ› οΈ Simple API: Designed for developers and artists alike β€” works with familiar hex, RGB, and CSS strings.
  • πŸ“ Accurate under the hood: All calculations use 64-bit floating point math and are grounded in color science literature.

Whether you’re building a color picker, a digital painting app, or just experimenting with creative coding, Spectral.js gives you a closer approximation to how real pigments behave.

πŸ‘‰ You can try Spectral.js live at spectraljs.com!


The Kubelka-Munk theory is a color science model that predicts how light interacts with pigmented materials by focusing on three main optical properties:

  • Absorption (K): How the material absorbs incident light.
  • Scattering (S): How the material scatters light within it.
  • Reflectance (R): The proportion of light diffusely reflected from the surface.

By modeling the interplay between absorption and scattering, the theory predicts the reflectance of pigmented materials across the visible spectrum (approximately 380 to 750 nm) β€” which in turn determines their perceived color.

Spectral.js uses the "simplified" or single-constant Kubelka-Munk theory, where the scattering coefficient (S) is assumed to be constant. This assumption allows the Kubelka-Munk function ( F(R) ) to directly relate reflectance to absorption:

Read the original on github.com β†—