Design Tokens and Component Architecture
Token pipelines, naming conventions, and component composition strategies that scale across platforms.
Why
Hardcoded colors and spacing create theme drift and make white-labeling impossible. Design tokens centralize decisions as named values, enabling dark mode, multi-brand theming, and cross-platform parity (web + iOS + Android) from a single source of truth.
Tokens Studio (formerly Figma Tokens) has 500k+ installs, and the W3C Design Tokens Format Module is nearing candidate recommendation. Tokens enable dark mode, multi-brand theming, and platform parity from a single source.
When
Introduce tokens when you have 2+ themes, ship to multiple platforms, or need design-engineering sync without Figma-to-code drift. Start with color + spacing; add typography and motion later.
How
Example
Common Problems
- ⚠Too many token tiers — primitive + semantic + component for every value creates 500+ tokens nobody uses
- ⚠Tokens not exported to all platforms — web uses CSS vars but iOS gets hardcoded colors, drift returns
- ⚠Renaming a token breaks every consumer — no codemod, so teams keep deprecated aliases forever
- ⚠Theme override specificity wars — !important everywhere because component styles beat :root tokens
Best Practices
- ✓Use 3 tiers max: primitive → semantic → component, and only add component tier when reuse is proven
- ✓Generate platform outputs in CI — fail the build if tokens.css and tokens.swift diverge
- ✓Write a codemod (jscodeshift) for token renames — run it in the same PR as the rename
- ✓Keep theme overrides at :root[data-theme='dark'] — never override inside component CSS
FAQ
How many token tiers should I have?
Three max: primitive (color.blue.500) → semantic (color.action.primary) → component (button.bg). Add the component tier only when reuse is proven; otherwise you get 500+ unused tokens.
Style Dictionary vs Tokens Studio — which should I use?
They're complementary: Tokens Studio authors tokens in Figma and exports JSON; Style Dictionary compiles that JSON to CSS vars, JS, Swift, Kotlin. Use both in a pipeline.
How do I rename a token without breaking consumers?
Write a jscodeshift codemod that updates all references, run it in the same PR as the rename. Keep a deprecated alias for one release cycle, then remove.
Why do my dark-mode overrides need !important?
Because component CSS beats :root tokens by specificity. Move overrides to :root[data-theme='dark'] at the document level, never inside component CSS.
How do I keep web and iOS tokens in sync?
Generate both outputs in CI from one JSON source — fail the build if tokens.css and tokens.swift diverge. Never hand-edit platform outputs.