Material Design 3 provides an open source Material Color Utilities package that can generate dynamic color schemes based on a set of input colors. This note documents how to use it and provides a playground to experiment.

Warning

The output of this tool is different from Material Theme Builder. Unfortunately, the Material Theme Builder is not open source, so I couldn't determine the exact differences in implementation.

Playground

Use this playground to generate Material Design 3 dynamic color schemes.

Select base colors

ColorSelect
Source Color
Primary
Secondary
Tertiary

Preview

Click on the color blocks to learn more about each color role and when to use them.

Tonal palettes

PaletteTones
Primary
0
10
20
30
40
50
60
70
80
90
95
99
100
Secondary
0
10
20
30
40
50
60
70
80
90
95
99
100
Tertiary
0
10
20
30
40
50
60
70
80
90
95
99
100
Neutral
0
10
20
30
40
50
60
70
80
90
95
99
100
Neutral Variant
0
10
20
30
40
50
60
70
80
90
95
99
100
Error
0
10
20
30
40
50
60
70
80
90
95
99
100

Color roles

CSS

Code

Note

Feel free to open the browser console and use m3 global variable to experiment with Material Color Utilities API. The scheme variable is also available for inspection.

// Import Material Color Utilities
import * as m3 from '@material/material-color-utilities'

// Whether to use dark mode
const sourceColorHct = m3.Hct.fromInt(m3.argbFromHex('#d7fc70'))
const isDark = true
const contrastLevel = 0.0

// Create a palette based on a variant. Choose one of these constructors:
// - m3.SchemeMonochrome
// - m3.SchemeNeutral
// - m3.SchemeTonalSpot
// - m3.SchemeVibrant
// - m3.SchemeExpressive
// - m3.SchemeFidelity
// - m3.SchemeContent
// - m3.SchemeRainbow
// - m3.SchemeFruitSalad
const dynamicScheme = new m3.SchemeTonalSpot(
  sourceColorHct,
  isDark,
  contrastLevel
)

// If you want to override the primary, secondary, and tertiary colors manually:
Object.assign(dynamicScheme, {
  primaryPalette: m3.TonalPalette.fromInt(m3.argbFromHex('#d7fc70')),
  secondaryPalette: m3.TonalPalette.fromInt(m3.argbFromHex('#8c9570')),
  tertiaryPalette: m3.TonalPalette.fromInt(m3.argbFromHex('#5e9c91')),
})

// Get the tonal palette color as a hex string
console.log(m3.hexFromArgb(dynamicScheme.primaryPalette.tone(40)))

// Get the color of a color role as a hex string
console.log(m3.hexFromArgb(dynamicScheme.primary))

References