Topics
v6.0.0
On this page · sections

Design Token Pipeline

Design tokens are named design decisions stored as data — color, spacing, typography, radius — flowing to CSS variables, TypeScript, iOS Swift, and Android XML from a single source of truth.

LayerExampleWho consumes
Primitivecolor.blue.600: #2563ebToken authors only
Semanticcolor.text.primaryTheme definitions
Componentbutton.primary.backgroundUI components
Output--color-brand-primaryApps via generated CSS

Tokens & Style Dictionary

Definition

{ "color": { "brand": { "primary": { "value": "#2563eb", "type": "color" }, "secondary": { "value": "#64748b", "type": "color" } } }, "spacing": { "md": { "value": "16px", "type": "dimension" } } }
/* dist/css/variables.css — generated, never hand-edited */ :root { --color-brand-primary: #2563eb; --color-brand-secondary: #64748b; --spacing-md: 16px; }

Style Dictionary transforms token JSON/YAML through a build step into platform files using formats and transforms.

// style-dictionary.config.js module.exports = { source: ['tokens/**/*.json'], platforms: { css: { transformGroup: 'css', buildPath: 'dist/css/', files: [{ destination: 'variables.css', format: 'css/variables' }], }, js: { transformGroup: 'js', buildPath: 'dist/js/', files: [{ destination: 'tokens.js', format: 'javascript/es6' }], }, }, };
tokens/*.json → style-dictionary build → dist/css · dist/js · dist/ios · consumers import artifacts

Without a pipeline, Figma hex values get copy-pasted into React and Swift separately — drift within one sprint.

Tokens Studio for Figma exports JSON compatible with Style Dictionary. Tailwind theme can consume generated token output.

Interview: Tokens are source data; CSS/Swift are build output — never edit generated files.

Token Taxonomy

Definition

  • Primitive tokens — raw values — color.blue.600: #2563eb, spacing.4: 16px
  • Semantic tokens — map intent — color.text.primary references primitive
  • Component tokens — scope to UI parts — button.primary.background references semantic
{ "color": { "blue": { "600": { "value": "#2563eb", "type": "color" } }, "text": { "primary": { "value": "{color.slate.900}", "type": "color" } }, "action": { "primary": { "value": "{color.blue.600}", "type": "color" } } } }
export function Button() { return ( <button style={{ background: 'var(--button-primary-background)', color: 'var(--button-primary-text)', }} > Submit </button> ); }

Components consume semantic or component tokens only — never color.blue.600 in a Button.

Primitive → Semantic → Component → React var(--button-primary-background) Dark theme: semantic text.primary remaps to different primitive — components unchanged

Reference syntax: {color.blue.600} in JSON value field. Max depth primitive → semantic → component (3 hops); avoid cycles.

Interview: UI code uses semantic/component tokens — primitives are for token authors and theme definitions.

Multi-Platform Output

Definition

One token source, multiple platforms in config:

module.exports = { source: ['tokens/**/*.json'], platforms: { css: { transformGroup: 'css', buildPath: 'dist/css/', files: [{ destination: 'variables.css', format: 'css/variables', options: { outputReferences: true }, }], }, js: { transformGroup: 'js', buildPath: 'dist/js/', files: [{ destination: 'tokens.mjs', format: 'javascript/esm' }], }, ios: { transformGroup: 'ios', buildPath: 'dist/ios/', files: [{ destination: 'Colors.swift', format: 'ios/swift/class.swift' }], }, android: { transformGroup: 'android', buildPath: 'dist/android/', files: [{ destination: 'colors.xml', format: 'android/colors' }], }, }, };
/* outputReferences: true — shows alias chain */ :root { --color-text-primary: var(--color-slate-900); --color-slate-900: #0f172a; }

Custom transforms convert name case (camelCase → kebab → Swift). Custom formats control file templates.

Tailwind: extend theme from generated JS — tokens are source, Tailwind is one web consumer.

Composite typography tokens bundle fontFamily, fontSize, lineHeight — custom format outputs shorthand CSS.

Interview: One JSON source, N platform outputs — change token once, all platforms update on next build.

CI Integration & Versioning

Definition

{ "scripts": { "tokens:build": "style-dictionary build", "tokens:ci": "style-dictionary build && git diff --exit-code dist/" } }
# CI — fail if generated output not committed - run: pnpm tokens:build - run: git diff --exit-code packages/tokens/dist/

Pipeline:

Designer updates Figma → export JSON → PR → CI builds tokens → diff check → publish @company/tokens package
  • Generated artifacts committed or built in CI before app build — pick one, document it
  • Semver on token package — breaking renames are major bumps
  • Deprecation — alias old token names for one release before removal
  • Visual regression — Chromatic/Percy on components after token changes

Apps depend on @company/tokens semver range — not relative Figma hex. Lock token version in monorepo with Changesets.

Breaking change: rename color.text.primary → coordinate codemod across all consuming apps in same release train.

Interview: CI diff check on dist/ catches “forgot to rebuild tokens” PRs.

Design-System Governance

Definition

Staff concerns at scale:

  • Token RFC process — propose new semantic token with use case, not ad-hoc primitives in product apps
  • Naming convention — category.role.variant (e.g. color.text.primary)
  • Forbidden patterns — no raw hex in product code; lint with stylelint/custom ESLint rule
  • Theme switching — CSS [data-theme="dark"] remaps semantic references, not component rewrites
  • Cross-platform parity — iOS/Android get same semantic names, platform-specific transforms
Governance flow: design proposes → token RFC → design-system team approves → CI build → semver publish → app bumps dep

Figma ↔ code sync: Tokens Studio plugin → JSON in repo → Style Dictionary → package. Designers don’t paste hex into Slack.

Document token deprecation in CHANGELOG. Provide migration map: color.text.default → color.text.primary.

Platform team owns token package, build config, and lint rules. Product teams consume — don’t fork token JSON.

Accessibility: contrast ratios validated at semantic layer — color.text.primary on color.bg.primary must pass WCAG in both themes.

Interview: Governance prevents 50 teams inventing slightly different blues — semantic layer is the contract.

Senior Interview Summary

Tokens

Named design decisions as data. Single source of truth for all platforms.

Style Dictionary

Transforms JSON → CSS/JS/Swift/Android. Custom transforms and formats per platform.

Taxonomy

Primitive → semantic → component. UI consumes semantic/component only.

CI

Build tokens in CI. Diff check on generated output. Semver on token package.

Governance

RFC process, naming conventions, lint against raw hex, deprecation aliases.

Best mental model

Figma JSON → source of truth (via Tokens Studio) Style Dict → build engine dist/ → generated artifacts (never hand-edit) Apps → import package, use CSS variables

Practical rules

Product code → var(--semantic-token), never #2563eb Dark mode → remap semantics, not components Breaking rename → major semver + codemod Token PR → rebuild dist + visual regression

What to say in interviews

Explain three token layers, how Style Dictionary multi-platform output works, CI diff check on generated files, and governance preventing primitive palette sprawl in product apps.

Last updated on