@palettebro/generator v2.0.5
@palettebro/generator
Simple yet powerful color palette generator for your web application based on Culori.
Features
- Easily use advanced color manipulation functions to create harmonious and accessible color palettes
- Automatically generate
lightanddarkthemes - Use MUI palettes with Tailwind 4
- Reverse the scale of
lightanddarkcolor shades to drastically reduce the use ofdark:selectors - Output palette colors in multiple formats:
rgb,hex,hsl,lchandoklch - Use the same palette and color tokens across different frontend frameworks
Purpose
This library automates the generation of a comprehensive color palette given a minimum of one to a maxium of three colors (primary, secondary, accent -a primary color is always required). The library generates shades, tones and surface colors most common in modern web design by using color manipulation functions in the OKHSL/OKLCH color spaces (*)
primary, secondary and accent colors get:
- A set of shades with a range compatible with different frameworks (**)
- Container and foreground tints (
on-primary,primary-container,on-primary-container)
Additionally:
- The
primarycolor gets a rainbow scale to use in charts - Various surface and outline colors are generated following Material UI 3 color roles guidelines
(*) Hues are rotated in OKLCH, which has more uniform hues than other color spaces. However, instead of using OKLCH's chroma and lightness, it uses saturation and lightness from OKHSL, as it is a more human-friendly way of interacting with color. See Schemist
(**) Currently supported Tailwind, Material UI and Bootstap
Palette

MUI Shades

Tailwind Shades

Modes Of Operation
@palettebro/generator works in three different modes or variants. Each variant has different presets that control how primary, secondary and accent colors relate to each other:
static. This variant requires you to specify only aprimarycolor.secondaryandaccentcolors are generated from theprimarycolor according to some color wheel manipulation rule specified in thepreset. For instance, thetriadpreset will choosesecondaryandaccentcolors as equally spaced in the color wheel.mui. This variant requires you to specify only aprimarycolor.secondaryandaccentcolors are generated from theprimarycolor using the @material/material-color-utilities library. All availablepresetsfrom the library are available, such asmonochromeortonal-spotdynamic. This variant accepts up to three colors:primary,secondaryandaccent. You can generate these colors as you wish, or just input one or two colors if you want a two-colors scheme (likeprimaryandaccent). Use thisvariantto have full control over the generated palette (however you will loose the ability generate harmonious two or three color combinations, as you will have to provide these yourself).
For the full list of options refer to types.ts
Theme Presets
Static Theme Presets
| Preset | Description |
|---|---|
| split-complementary | Uses split-complementary colors for secondary and accent, creating vibrant contrast. |
| tetrad | Uses a four-color (tetrad) harmony for secondary and accent, for rich, balanced palettes. |
| triad | Uses a three-color (triad) harmony for secondary and accent, for dynamic, balanced palettes. |
| hue-shift | Shifts the hue for secondary (+30°) and accent (+60°), creating harmonious variation. |
| depth | Adds highlight and shadow shifts for depth and dimensionality. |
| duotone | Reduces saturation for secondary, highlights for accent, for a soft, two-tone look. |
| neo-brutalist | Boosts saturation and contrast for bold, high-impact palettes. |
| glassmorphism | Desaturates secondary, adds highlights/shadows for accent, for a frosted-glass effect. |
| cyberpunk | Shifts secondary hue (+180°), high contrast for accent, for a neon, futuristic look. |
| vaporwave | Shifts secondary hue (+195°), pastel highlights for accent, for a dreamy, retro look. |
| retro-futurism | Boosts secondary saturation, shifts accent hue (+210°), for a playful, nostalgic palette. |
| nordic-minimalism | Desaturates secondary, cool blue accent, for a clean, minimal look. |
| sunset-gradient | Warm orange secondary (+35°), magenta accent (+320°), for a sunset-inspired palette. |
| electric-neon | Maxes out secondary saturation, high contrast or purple/green accent, for neon vibrancy. |
| earth-tones | Muted secondary, terracotta accent (+50°), for natural, earthy palettes. |
| pastel-dreams | Light, pastel secondary, lavender accent (+280°), for soft, dreamy palettes. |
| monochrome-depth | Adjusts lightness and desaturates for monochrome palettes with depth. |
MUI Theme Presets
| Preset | Description |
|---|---|
| content | Matches the source color closely, with primary container as the seed color and a complementary tertiary. |
| expressive | Medium chroma, primary hue is intentionally shifted for variety and expressiveness. |
| fidelity | Maximizes fidelity to the seed color, adjusting tones for accessibility. |
| fruit-salad | Playful, the source color's hue does not appear in the theme. |
| monochrome | All colors are grayscale, no chroma. |
| neutral | Nearly grayscale, with a hint of chroma. |
| rainbow | Playful, the source color's hue does not appear in the theme. |
| tonal-spot | Pastel, low chroma palettes; the default Material You theme. |
| vibrant | Maximizes colorfulness (chroma) in the primary palette. |
Palette
The getPalette function returns an object with the core palette colors:
const palette = getPalette({
baseColors: {
primary: '#007bff',
},
})
// palette
{
primary: { name: 'Azure', color: 'oklch(60.48144% 0.216559 257.213551)' },
secondary: {
name: 'Lawn green',
color: 'oklch(60.492921% 0.184386 137.302298)'
},
'on-secondary': { name: 'White', color: 'oklch(99.999999% 0 0)' },
'secondary-container': { name: 'Lima', color: 'oklch(91.408137% 0.188345 137.203108)' },
'on-secondary-container': {
name: 'Lincoln green',
color: 'oklch(39.196261% 0.119129 137.152482)'
},
...
}You can output the color in any of the following formats: rgb, hex, hsl, lch and oklch
const palette = getPalette({
baseColors: {
primary: '#007bff',
},
format: ColorFormatEnum.hex
})
// palette
{
primary: { name: 'Galactic purple', color: '#412f9c' },
secondary: { name: 'Evergreen', color: '#19533c' },
'on-secondary': { name: 'White', color: '#ffffff' },
'secondary-container': { name: 'Neo mint', color: '#9bface' },
'on-secondary-container': { name: 'Zucchini', color: '#19513b' },
'secondary-50': { name: 'Mint coffee', color: '#d0fde7' },
'secondary-100': { name: 'Neo mint', color: '#9bface' },
...
}Options
The getPalette function expects an object with a theme property, which should be an object with the following options:
| Option | Type | Description | Default |
|---|---|---|---|
baseColors.primary | string | The primary color (hex). Required. | — |
baseColors.secondary | string | The secondary color. Optional. If omitted, it is generated from the primary color (except in dynamic variant). | — |
baseColors.accent | string | The accent color. Optional. If omitted, it is generated from the primary color (except in dynamic variant). | — |
format | string | Output color format: rgb, hex, hsl, lch or oklch. | oklch |
color-scheme | string | Color scheme: light or dark. Note: a dark theme will be automatically generated from a light theme and viceversa. | light |
variant | string | Palette generation mode: static, mui, or dynamic. | static |
preset | string | Preset to use (see tables above for available presets for each variant). | hue-shift (static) |
reverse | boolean | Swap the secondary and accent colors. | false |
contrast | number | Adjusts contrast (currently only available in the mui variant). | 0 |
reverseLightDarkShades | boolean | Reverse the order of light/dark shades in generated palette. | true |
colorShadesPreset | string | Which shade system to use: tailwind, mui, or bootstrap. | tailwind |
frameworkCompatibilty | string | Framework compatibility: shadcn or daisyui. | shadcn |
Notes
- Required: At minimum, you must provide
baseColors.primary. - Secondary/Accent: If you want full control (e.g., in
dynamicvariant), you can providebaseColors.secondaryand/orbaseColors.accent. - Preset: The available values for
presetdepend on the selectedvariant(see the tables above for static and MUI presets). - format: Controls the output color format for all palette entries.
Example
const palette = getPalette({
theme: {
baseColors: {
primary: '#007bff',
secondary: '#ffb300', // optional
accent: '#e91e63', // optional
},
format: 'oklch',
'color-scheme': 'dark',
variant: 'static',
preset: 'triad',
reverse: false,
contrast: 0,
reverseLightDarkShades: true,
colorShadesPreset: 'tailwind',
frameworkCompatibilty: 'shadcn',
}
});CSS Variables
The paletteToCssVars transforms the core palette colors into CSS variables that can be injected in the DOM or used in your CSS. The function returns an object like:
const cssVars = paletteToCssVars(palette)
// cssVars
{
'--color-primary': 'oklch(60.48144% 0.216559 257.213551)',
'--color-secondary': 'oklch(60.492921% 0.184386 137.302298)',
'--color-on-secondary': 'oklch(99.999999% 0 0)',
'--color-secondary-container': 'oklch(91.408137% 0.188345 137.203108)',
'--color-on-secondary-container': 'oklch(39.196261% 0.119129 137.152482)',
...
}You can choose a framework compatibility option to add to the core CSS variables color tokens compatible with a specific framework. Current supported frameworks are:
const cssVars = paletteToCssVars(palette, FrameworkCompatibilityEnum.daisyui)
// cssVars
{
...
'--color-base-100': 'oklch(98.350639% 0.00791 253.851847)',
'--color-base-200': 'oklch(98.306083% 0.008026 278.639769)',
'--color-base-300': 'oklch(96.656192% 0.015669 266.279586)',
'--color-base-content': 'oklch(17.860627% 0.062743 256.740222)',
'--color-primary-content': 'oklch(99.999999% 0 0)',
'--color-secondary-content': 'oklch(99.999999% 0 0)',
...
}Accessibility (Contrast)
You can verify the accessibility of color pairs against WCAG2 and WCAG3 (APAC) guidelines thanks to the apca-w3 library.
- To get the
WCAG2orWCAG3contrast value of a color pair usewcag2Contrastorwcag3Contrast - To get the
WCAG2orWCAG3grade of a color pair usewcag2ContrastGradeorwcag3ContrastGrade - To check the readability of a color pair, use
isWcag2ReadableorisWcag3Readable
See Demo for example usage.

WCAG 3 (APCA) Contrast Example
You can check the APCA (WCAG 3) contrast grade for a color pair using the new bronze/silver/gold system:
import { wcag3ContrastGrade } from './src/color/contrast/wcag3/contrast-grade';
const bg = '#ffffff';
const fg = '#222222';
// For body text (default)
const grade = wcag3ContrastGrade(bg, fg); // 'bronze' | undefined
// For large text
const largeGrade = wcag3ContrastGrade(bg, fg, 'large'); // 'bronze' | undefined
// For non-text elements
const nonTextGrade = wcag3ContrastGrade(bg, fg, 'nonText'); // 'bronze' | undefined
console.log('WCAG3 (APCA) grade for body:', grade);
console.log('WCAG3 (APCA) grade for large:', largeGrade);
console.log('WCAG3 (APCA) grade for nonText:', nonTextGrade);If the grade is undefined, the color pair does not meet the minimum APCA threshold for bronze.
Installation
npm install @palettebro/generator
# or
yarn add @palettebro/generatorUsage
See Demo
Libraries Used
- Culori: A comprehensive color library for JavaScript, used for color conversions, manipulations, and calculations.
- @material/material-color-utilities: Utilities for Material Design color systems, including tonal palettes and dynamic color schemes.
- apca-w3: Implements the APCA (Advanced Perceptual Contrast Algorithm) for accessible color contrast calculations.
- delta-e: Provides Delta E color difference formulas for measuring perceptual differences between colors.
- nearest-color: Finds the closest named color to a given color value.
- valibot: Type-safe data validation
Note About Color Names
Color names are assigned by finding the closest match to a given color using the nearest-color library. The matching is performed against this list of color names and their corresponding hex values, which aims to provide meaningful and recognizable names for a wide range of colors. If no close match is found, the original hex value is used as the name.
🚨 The color names list adds ~105KB to the base bundle size of ~32KB
License
MIT