Colors

Exporting Color Tokens: Tailwind, CSS, JSON

Shaheer Malik14 min read
ZepixoCOLORS
Exporting Color Tokens: Tailwind, CSS, JSON
On this page

Color design tokens are the bridge between a palette and a codebase. A token is a named color, like color-text-primary, that points to a value, like #1e293b. Instead of pasting raw hex codes all over your app, you reference the name. Change the value once, and every place that uses the token updates. That single idea keeps a color system consistent and easy to evolve.

This guide is for designers and developers who have a palette and now need to ship it as code. I will explain what tokens are, how to name them so they scale, the main formats with a comparison table, how to export from Zepixo, and how to use the tokens in real projects. By the end you will move colors from your palette into Tailwind, CSS variables, JSON, or SCSS with confidence.

What you'll learn

  • What design tokens are and why they beat raw hex
  • How to name tokens with a layered system
  • The main token formats and when to use each
  • How to export tokens from Zepixo
  • How to wire tokens into Tailwind, CSS, and JS

What color design tokens are

A design token is a name-value pair that stores a design decision. For color, the name describes a role or a step, and the value is the actual color. The token is the single source of truth, and your code points at it rather than at a hardcoded color.

The payoff is consistency and speed. When a designer tweaks the brand color, you update one token and the whole product follows. There is no hunting through files for stray hex codes. The same token can also hold a light value and a dark value, which makes theming a swap instead of a rewrite.

#5b5bd6
color-brand
the token
TailwindCSS varsJSONSCSS
One value becomes a named token, then exports to every format your stack needs.

How to name tokens

Naming is where token systems live or die. Good names are predictable, so anyone can guess the token they need. The most robust approach uses two layers, primitive and semantic.

Primitive tokens

Primitive tokens name raw values by hue and step, with no meaning attached. Think indigo-500 or slate-900. They are the full ladder of every color, the raw material. You rarely use these directly in components.

Semantic tokens

Semantic tokens name a job, and they point at a primitive. Think color-text-primary or color-surface, which might point at slate-900 and white. These are what you actually use in code, because they carry meaning and survive a theme change.

The split is powerful. When dark mode arrives, color-surface points at slate-900 instead of white, and every component follows without edits. The component asked for the surface, not for a specific gray. This is the heart of a maintainable system.

LayerExample namePoints atUsed in components
Primitiveindigo-500#5b5bd6Rarely
Primitiveslate-900#0f172aRarely
Semanticcolor-brandindigo-500Yes
Semanticcolor-text-primaryslate-900Yes
Semanticcolor-surfacewhite or slate-900Yes

Keep names lowercase with dashes, grouped by category. A predictable pattern like color-{role}-{variant} scales to hundreds of tokens without chaos. Our accessible color system guide covers how the roles map to contrast.

The main token formats

The same tokens can live in several formats, one per part of your stack. Here are the four you will meet most, and what each is best at.

FormatLooks likeBest for
Tailwind configtheme.colors.brandTailwind projects, utility classes
CSS variables--color-brandAny site, runtime theming
JSON{ "color-brand": "#5b5bd6" }Tooling, cross-platform, native
SCSS$color-brandSass codebases, build-time

Tailwind config

Tailwind reads your colors from its config and generates utility classes like bg-brand or text-brand-700. Tailwind v4 ships colors in OKLCH by default, which keeps scales even. This is the smoothest path if you already use Tailwind. See the Tailwind colors docs.

CSS variables

CSS custom properties, the --color-brand syntax, work in any project with no build step. They are the only format that can change at runtime, which is what makes them ideal for theme switching. A media query or a class on the body can swap the whole palette.

JSON

JSON is the universal, tool-friendly format. It carries no opinion about your stack, so build tools, native apps, and design tools can all read it. It is the common interchange format behind the Design Tokens standard.

SCSS

SCSS variables suit codebases already using Sass. They resolve at build time, so they are fast but cannot change at runtime. If your project compiles Sass, exporting SCSS keeps the tokens native to your workflow.

Exporting tokens from Zepixo

The Zepixo Colors workspace is built to hand off real tokens, not just swatches. You generate each role as a 50 to 950 OKLCH scale, then export the whole system in the format your stack uses.

Generate the scales

Set your primary, secondary, accent, and functional roles, and let the workspace build each as an even OKLCH scale. Lock any shade you want to keep fixed, and check the 11 by 11 contrast grid so the pairings pass. This is the palette your tokens will carry.

Pick a format and export

From the export panel, choose Tailwind, CSS variables, JSON, or SCSS. The workspace writes the tokens with consistent names and the right syntax for that format. You copy the output or download the file and drop it into your project.

Tailwind
CSS variables
JSON
SCSS

Ready to export? Open the Zepixo Colors workspace, build your roles as OKLCH scales, and export tokens in Tailwind, CSS, JSON, or SCSS. The export reference walks through each format.

Using tokens in code

Exporting is only half the job. The other half is wiring the tokens into your project so components reference them. Here is how each format lands in real code.

CSS variables

Declare the tokens on the root, then reference them anywhere. Swapping a theme is just overriding the same variables under a selector.

:root {
  --color-surface: #ffffff;
  --color-text-primary: #1e293b;
  --color-brand: #5b5bd6;
}
[data-theme="dark"] {
  --color-surface: #0f172a;
  --color-text-primary: #e2e8f0;
  --color-brand: #a5b4fc;
}
.button {
  background: var(--color-brand);
  color: #ffffff;
}

Tailwind

Map your tokens in the config, then use the generated utility classes in markup.

/* tailwind config */
theme: {
  colors: {
    brand: { 500: "#5b5bd6", 700: "#4338ca" },
    surface: "#ffffff",
  }
}

<button class="bg-brand-500 text-white">Save</button>

JSON in JavaScript

Import the JSON and read tokens by name in components or a theme object.

import tokens from "./tokens.json";

const style = {
  background: tokens["color-surface"],
  color: tokens["color-text-primary"],
};

The pattern is the same in every format. Components ask for a named token, never a raw hex. That indirection is what lets you restyle the whole app from one place. For the official model, see the MDN custom properties reference.

Tokens and theming

Theming is the clearest payoff of semantic tokens. Because a component asks for color-surface, not for white, you can point that token at a different value per theme and the component just follows.

Define each theme as a set of token values. The light theme maps color-surface to white, and the dark theme maps it to a deep slate. The structure is identical, only the values change. This is why dark mode is a swap, not a rewrite, when tokens are in place.

TokenLight valueDark value
color-surface#ffffff#0f172a
color-text-primary#1e293b#e2e8f0
color-brand#5b5bd6#a5b4fc

For the full dark side of this, see our dark mode color palette guide. The tokens are the mechanism, and the dark palette is the content you pour into them.

Keeping tokens in sync

Tokens only help if they stay the single source of truth. The risk is drift, where someone pastes a raw hex into a component and the token no longer reflects reality. A few habits keep the system honest.

Ban raw hex in components

Make a rule that components never contain a hardcoded color. If a value is not a token, it does not belong. A linter can flag stray hex codes so they never slip in. This one rule preserves everything tokens give you.

Re-export when the palette changes

When a designer updates the palette in Zepixo, re-export and replace the token file. Because everything points at the tokens, the change ripples through automatically. The export is the handoff, and re-exporting keeps design and code aligned.

Version your tokens

Commit the token file to your repo and treat changes like any code change, with review. A diff on the token file shows exactly which colors moved. This makes color changes reviewable and reversible, which large teams need.

Frequently asked questions

What is a color design token?

It is a named color that points to a value, like color-brand pointing at #5b5bd6. Code references the name instead of the raw hex, so changing the value once updates everywhere. Tokens are the single source of truth for a color system.

What is the difference between primitive and semantic tokens?

Primitive tokens name raw values by hue and step, like indigo-500, with no meaning. Semantic tokens name a job, like color-text-primary, and point at a primitive. Components use semantic tokens, which is what makes theming a simple value swap.

Which token format should I use?

Use Tailwind config for Tailwind projects, CSS variables for any site that needs runtime theming, JSON for tooling and cross-platform use, and SCSS for Sass codebases. Many teams export several formats from one source palette.

How do tokens enable dark mode?

A semantic token like color-surface can hold a light value and a dark value. Components ask for the token, so swapping the theme repoints the token and every component follows. No component edits are needed for the theme change.

How do I export tokens from Zepixo?

Build your roles as OKLCH scales in the Colors workspace, check the contrast grid, then open the export panel. Choose Tailwind, CSS variables, JSON, or SCSS, and copy or download the generated tokens to drop into your project.

How do I keep tokens from drifting?

Forbid raw hex in components so every color is a token, and use a linter to catch strays. Re-export and replace the token file whenever the palette changes, and commit the file so color changes are reviewed like any code.

Name tokens in two layers, export the format your stack needs, ban raw hex, and re-export on changes. Do that and your colors will stay consistent from design to production. You have got this.

S

Shaheer Malik

Founder of Zepixo — building the whole brand studio in one tab. Try Zepixo →

Related posts