Every growing engineering team eventually faces the same question: why do our buttons look different across three products? A design system answers this by encoding decisions — not just components — into a shared, versioned artefact. But building one too early wastes effort, and building one too late means untangling years of inconsistency.
Start with tokens, not components
Design tokens — colours, spacing scales, typography, shadows — are the foundation. Components change frequently, but tokens are stable. We define tokens in a single source of truth and generate platform-specific outputs: CSS custom properties for web, Swift extensions for iOS, Compose theme values for Android. This ensures visual consistency even before shared components exist.
{
"color": {
"brand": {
"teal": { "value": "#14b8a6" },
"teal-dark": { "value": "#0d9488" }
},
"text": {
"primary": { "value": "#0f172a" },
"muted": { "value": "#475569" }
}
},
"spacing": {
"xs": { "value": "4px" },
"sm": { "value": "8px" },
"md": { "value": "16px" }
}
}Governance over perfection
The design systems that survive are the ones with clear contribution guidelines and a lightweight review process. We use a simple RFC model: propose a new component or pattern, get feedback from both design and engineering, merge it, and document the decision. The documentation matters as much as the code — a component without usage guidance will be reimplemented within six months.
- Define tokens before building components
- Version your design system independently from products
- Document decisions, not just APIs
- Assign a maintainer, not a committee