Every design system starts as a promise of consistency and ends — more often than not — as an unused Figma file and a components/legacy folder. Ours nearly did too, until we changed one thing: we stopped treating it as a product people must adopt, and started treating it as a set of defaults nobody has to think about.
The failure mode
Our first attempt was classic. A 40-component library, exhaustive docs, versioned releases, a contribution process with three approval stages.
Six months later:
- Teams vendored their own buttons because upgrading meant reading a changelog.
- The system team became a bottleneck for every new component.
- Designers stopped updating specs because engineers ignored them anyway.
The problem wasn't quality. It was friction.
What we changed
One: tokens over components
We invested in design tokens before components — colors, spacing, type scale, radii — exposed as CSS custom properties:
:root {
--color-accent: #c05e0a;
--space-unit: 0.25rem; /* 4px */
--radius-card: 0.75rem;
}
[data-theme="dark"] {
--color-accent: #f0a12e;
}Adoption cost dropped to near zero: you could consume tokens inside your own markup with no library dependency at all. Half our consistency wins came from this alone.
Two: primitives, not pages
Instead of shipping opinionated <PageHeader> blocks, we shipped small composable pieces. Teams assembled them freely. Consistency came from shared atoms, not from forbidding composition:
// Encouraged — small primitives
<Card>
<CardTitle>Usage</CardTitle>
<Metric value={82} unit="%" />
</Card>
// Discouraged — god components
<UsageReportCard data={report} theme="marketing" />Three: codemods instead of changelogs
The biggest unlock. When we renamed or restructured something, we didn't ask forty engineers to migrate manually — we wrote the migration once and ran it across every repo:
npx @ourco/design-system-migrate v3-tokensA breaking change went from "quarter-long coordination project" to "afternoon." That single practice did more for adoption than any documentation we wrote.
Results after a year
| Metric | Before | After |
|---|---|---|
| Token adoption | ~30% | >95% |
| Component duplication | 14 button variants | 2 |
| Time to ship a themed feature | weeks | days |
Takeaways
- Lower the adoption cost to zero before asking for adoption. Tokens beat libraries for this.
- Automate migrations or don't break APIs. Changelogs are where design systems go to die.
- Consistency is an emergent property of good defaults, not an enforcement outcome.
Design systems fail socially, not technically. Design for the humans importing the components, and the pixels take care of themselves.