← All tools

Export a colour palette

Your palette as code, ready to paste.

Base colour

Getting colours into your codebase

Picking colours is the short part. Getting them into a project in a form that stays maintainable is where palettes usually go wrong, and the format you export in largely decides how painful the next rebrand will be.

The formats

CSS custom properties. The default choice for most projects. Define them once on :root, reference them everywhere, and they update live — including inside media queries, which is what makes dark mode straightforward.

:root {
  --blue-500: #3d8bf5;
  --color-text-primary: var(--blue-800);
}

Sass variables. Resolved at build time, so they cannot change at runtime and cannot power a theme switch on their own. Still useful for values that genuinely never vary, and for computing a palette at build time.

Tailwind config. Extends the default theme so your scale becomes available as utility classes. Worth keeping the numbered-step convention so it matches Tailwind’s own scales.

Design tokens (JSON). The interchange format when the same palette has to reach web, iOS, Android and design tools. More setup, and the only approach that genuinely keeps multiple platforms in step.

SVG and image formats for swatch sheets, and plain lists when you just need to paste values into a document.

Two layers of naming

The single most useful thing you can do at export time is separate what a colour is from what it is for:

:root {
  /* Layer 1 — the palette. Descriptive, never used directly in components. */
  --blue-600: #2b6cb0;
  --grey-900: #1a202c;

  /* Layer 2 — semantic. This is what components reference. */
  --color-action: var(--blue-600);
  --color-text-primary: var(--grey-900);
}

Components reference only the second layer. Rebranding then means repointing a handful of semantic tokens rather than finding every use of --blue-600 — and dark mode becomes a matter of redefining layer two under a media query while layer one stays put.

Dark mode

Two approaches. Either redefine the semantic tokens inside @media (prefers-color-scheme: dark), or define both sets and switch with a data-theme attribute on the root element. The attribute approach is more code but supports an explicit user toggle, which most people eventually want. Whichever you choose, remember that a scale does not simply invert — contrast behaves differently on dark backgrounds and saturated colours read as brighter. Recheck the pairs with the contrast checker.

Where people go wrong

Exporting hex when you generated in OKLCH. Hex is fine as output, but keep the OKLCH values in source somewhere. Regenerating a scale from hex means redoing the perceptual work.

Naming by appearance. --light-blue has nowhere to go when you need something between it and --blue. Number by lightness; the colour scale generator covers the convention.

Skipping the semantic layer on small projects. It costs almost nothing up front and saves a great deal later. Small projects grow.

Committing exported colours without checking them in context. A palette that looks right in a swatch grid can be wrong in a layout, where areas differ wildly in size. Large surfaces need quieter colours than small ones.

Letting the palette drift. Once colours live in code, people add “just one more” shade inline. Periodically diffing what is used against what is defined is worth the hour.

Our guide on colour scales for design systems covers structuring the palette before you export it.

Common questions

Which export format should I use?

CSS custom properties for most web projects — they work everywhere and can be themed at runtime. Tailwind config if you are already using it. JSON when a build step or design tool consumes the tokens.