Design Tokens
Manage cross-platform design tokens with Style Dictionary. Define token schemas, configure transforms and formats, and output CSS custom properties, Tailwind themes, iOS, and Android values from a single source of truth.
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: 201 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
Figma API
Integrate with the Figma REST API and webhooks to read design files, extract components, manage variables, export images, and sync comments. Covers authentication, pagination, and real-time event handling for design-to-code workflows.
Iconify
Integrate icons at scale with the Iconify framework. Use framework-specific components for React and Vue, register custom icon sets, and leverage the Iconify API for on-demand SVG delivery without bundling thousands of icons.
Sharp
Process images at high performance with Sharp. Resize, crop, convert formats, extract metadata, and build streaming pipelines for thumbnails, responsive images, and batch transformations using libvips under the hood.
Storybook
Develop and test UI components in isolation with Storybook. Configure stories, addons, args, play functions, and visual testing to build a living component library with interactive documentation and automated interaction tests.
Tailwind Plugins
Build custom Tailwind CSS plugins that add utilities, components, and variants. Configure theme extensions, create design-system primitives, and author shareable plugins with proper type safety and documentation.
Canvas API
Draw graphics and generate images with the HTML Canvas 2D API and node-canvas. Render charts, create dynamic OG images, manipulate pixels, and build server-side image generation pipelines with the Canvas rendering context.