Design tokens

Express every UI design decision — color, spacing, typography, radius, motion, elevation, opacity — once as a named design token in a single platform-agnostic source of truth, then generate platform artifacts from it. Application code and components MUST reference semantic tokens, never raw values, so one edit propagates everywhere.

Single source of truth

  • Design decisions MUST live in one shared source, not duplicated per platform.
  • The source format SHOULD be the W3C Design Tokens Community Group (DTCG) JSON format, which reached its first stable version (2025.10) in October 2025. Pin to a dated revision (e.g. 2025.10) rather than tracking the living draft, which carries a do-not-implement notice.
  • Each token MUST carry an explicit $type (e.g. color, dimension, duration, fontFamily) and a $value; design intent SHOULD be captured in $description.
  • Platform outputs (Swift, Kotlin, TypeScript/CSS custom properties, C#/XAML) SHOULD be generated by a build step (e.g. Style Dictionary) — never hand-maintained copies.

Three tiers

Use three layers so values change in one place and intent stays stable:

Tier Holds Example May code reference it?
Primitive (global) Raw, context-free values color.blue.600 = #2563EB No
Semantic (alias) Intent, references a primitive color.action.primary → color.blue.600 Yes
Component Per-component intent button.bg.default → color.action.primary Yes
  • Components and application code MUST reference semantic or component tokens only; they MUST NOT reference primitives directly.
  • Semantic and component tokens MUST be aliases (DTCG {token.path} references), not duplicated literals, so a primitive change cascades automatically.
  • Tier count SHOULD stay at three; add a component tier only when a real second consumer exists (YAGNI) — a flat alias layer is enough for a single app.

Theming and modes

  • Variants (light/dark, density, brand) SHOULD be modeled by swapping the semantic layer's primitive references, leaving component tokens untouched.
  • Mode-specific values SHOULD be expressed as sets/themes resolved at build or runtime; the component contract stays identical across modes.
  • Naming MUST be consistent and platform-neutral (color.action.primary), so the same identifier resolves on every platform.

Accessibility and validation

  • Color-pair tokens (foreground on background) SHOULD be checked for WCAG 2.2 contrast (4.5:1 body text, 3:1 large text/UI) in the token pipeline, failing the build on violation.
  • The token file SHOULD be schema-validated in CI so malformed or dangling aliases fail fast rather than shipping.

Anti-patterns

  • Do NOT hardcode hex/spacing/font literals in components — that defeats single-source propagation.
  • Do NOT reference primitive tokens from components; an intent change then requires editing many call sites.
  • Do NOT fork per-platform token copies; divergence is inevitable.

Privacy/compliance note: this is engineering guidance, not legal advice.

version
1.0.0
platforms
swift, kotlin, typescript, csharp, web
tags
design-system, tokens, theming
author
Mike Fullerton
modified
2026-06-09

Change History

Version Date Author Summary
1.0.0 2026-06-09 Mike Fullerton Initial creation