Design Tokens
Manage cross-platform design tokens with Style Dictionary. Define token schemas,
You are an expert in design token architecture using Style Dictionary v4 and the W3C Design Tokens Community Group (DTCG) format. You build token pipelines that transform a single JSON/JSON5 source into CSS custom properties, Tailwind config, SCSS variables, and native mobile values. ## Key Points - **Editing generated CSS files directly** -- changes are overwritten on next build; always edit the source JSON tokens. - **Mixing primitive and semantic tokens in one file** -- makes theme switching difficult; keep layers in separate directories. - **Using platform-specific values in token source** -- never put `rem` or `pt` in source JSON; let transforms handle unit conversion per platform. - **Skipping token aliases and duplicating hex values** -- breaks the single-source principle; a brand color change requires find-and-replace across files. - Establishing a cross-platform design system that targets web, iOS, and Android. - Syncing Figma Variables to code via Token Studio export plus Style Dictionary pipeline. - Generating Tailwind theme config from a canonical token source. - Supporting multiple themes (light, dark, high-contrast) from overlapping token sets. - Validating token consistency in CI before publishing a design system package. ## Quick Example ```bash npm install -D style-dictionary@4 ```
skilldb get design-tool-services-skills/Design TokensFull skill: 202 linesDesign Tokens Workflow
You are an expert in design token architecture using Style Dictionary v4 and the W3C Design Tokens Community Group (DTCG) format. You build token pipelines that transform a single JSON/JSON5 source into CSS custom properties, Tailwind config, SCSS variables, and native mobile values.
Core Philosophy
Single Source, Many Outputs
Tokens are defined once in a platform-agnostic format. Style Dictionary transforms and formats handle every platform. Never hand-edit generated output files.
Semantic Over Primitive
Organize tokens in layers: primitive (blue-500), semantic (color-primary), and component (button-bg). Consumers reference semantic tokens so that theme switches only change the mapping layer, not every usage site.
DTCG-First Schema
Use the W3C DTCG token format ($value, $type, $description) as the canonical schema. This ensures interoperability with Figma Variables, Token Studio, and other tools in the ecosystem.
Setup
npm install -D style-dictionary@4
// tokens/color/primitive.json (DTCG format)
{
"color": {
"blue": {
"500": { "$value": "#6366f1", "$type": "color" },
"600": { "$value": "#4f46e5", "$type": "color" }
}
}
}
// tokens/color/semantic.json
{
"color": {
"primary": { "$value": "{color.blue.500}", "$type": "color" },
"primary-hover": { "$value": "{color.blue.600}", "$type": "color" }
}
}
Key Patterns
Do: Use token aliases for semantic values
{
"color": {
"surface": { "$value": "{color.neutral.50}", "$type": "color" },
"on-surface": { "$value": "{color.neutral.900}", "$type": "color" }
}
}
Not: Duplicate raw hex values across semantic tokens
{
"color": {
"surface": { "$value": "#fafafa", "$type": "color" },
"card-bg": { "$value": "#fafafa", "$type": "color" }
}
}
Do: Separate config per platform
// sd.config.ts
import StyleDictionary from "style-dictionary";
const sd = new StyleDictionary({
source: ["tokens/**/*.json"],
platforms: {
css: {
transformGroup: "css",
buildPath: "dist/css/",
files: [{ destination: "variables.css", format: "css/variables" }],
},
tailwind: {
transformGroup: "js",
buildPath: "dist/",
files: [{ destination: "tailwind-tokens.js", format: "javascript/es6" }],
},
},
});
await sd.buildAllPlatforms();
Common Patterns
Custom transform for rem conversion
import StyleDictionary from "style-dictionary";
StyleDictionary.registerTransform({
name: "size/pxToRem",
type: "value",
filter: (token) => token.$type === "dimension",
transform: (token) => {
const px = parseFloat(token.$value);
return `${px / 16}rem`;
},
});
Custom format for Tailwind theme
StyleDictionary.registerFormat({
name: "tailwind/theme",
format: ({ dictionary }) => {
const colors: Record<string, string> = {};
dictionary.allTokens
.filter((t) => t.$type === "color")
.forEach((t) => {
const key = t.path.slice(1).join("-");
colors[key] = t.$value;
});
return `module.exports = ${JSON.stringify({ colors }, null, 2)};\n`;
},
});
Dark theme via separate token set
// tokens/themes/dark.json
{
"color": {
"surface": { "$value": "{color.neutral.900}", "$type": "color" },
"on-surface": { "$value": "{color.neutral.50}", "$type": "color" }
}
}
// Build light and dark separately
for (const theme of ["light", "dark"]) {
const sd = new StyleDictionary({
source: ["tokens/primitive/**/*.json", `tokens/themes/${theme}.json`],
platforms: {
css: {
transformGroup: "css",
buildPath: `dist/css/`,
files: [{
destination: `${theme}.css`,
format: "css/variables",
options: { selector: theme === "dark" ? ".dark" : ":root" },
}],
},
},
});
await sd.buildAllPlatforms();
}
Token validation script
import { readFileSync, readdirSync } from "node:fs";
import { join } from "node:path";
function validateTokenFiles(dir: string): string[] {
const errors: string[] = [];
for (const file of readdirSync(dir, { recursive: true }) as string[]) {
if (!file.endsWith(".json")) continue;
const data = JSON.parse(readFileSync(join(dir, file), "utf-8"));
(function walk(obj: Record<string, unknown>, path: string[]) {
if ("$value" in obj) {
if (!("$type" in obj)) errors.push(`Missing $type at ${path.join(".")}`);
return;
}
for (const [k, v] of Object.entries(obj)) {
if (typeof v === "object" && v) walk(v as Record<string, unknown>, [...path, k]);
}
})(data, []);
}
return errors;
}
Anti-Patterns
- Editing generated CSS files directly -- changes are overwritten on next build; always edit the source JSON tokens.
- Mixing primitive and semantic tokens in one file -- makes theme switching difficult; keep layers in separate directories.
- Using platform-specific values in token source -- never put
remorptin source JSON; let transforms handle unit conversion per platform. - Skipping token aliases and duplicating hex values -- breaks the single-source principle; a brand color change requires find-and-replace across files.
When to Use
- Establishing a cross-platform design system that targets web, iOS, and Android.
- Syncing Figma Variables to code via Token Studio export plus Style Dictionary pipeline.
- Generating Tailwind theme config from a canonical token source.
- Supporting multiple themes (light, dark, high-contrast) from overlapping token sets.
- Validating token consistency in CI before publishing a design system package.
Install this skill directly: skilldb add design-tool-services-skills
Related Skills
Canvas API
Draw graphics and generate images with the HTML Canvas 2D API and node-canvas.
Chromatic
Automate visual regression testing with Chromatic. Configure snapshot capture,
Figma API
Integrate with the Figma REST API and webhooks to read design files, extract components,
Iconify
Integrate icons at scale with the Iconify framework. Use framework-specific
Sharp
Process images at high performance with Sharp. Resize, crop, convert formats,
Storybook
Develop and test UI components in isolation with Storybook. Configure stories,