Every product team hits the same wall around its third year. The app has 14 shades of grey, six button styles, and three date pickers, and every new screen starts a debate that was already settled twice. A design system is how you settle those debates once and get back to shipping features.
We have built systems for teams from four people to forty. The failures all look alike: a beautiful component library that nobody adopts. The successes look alike too. This post is the pattern behind the successes.
What a design system actually is
Strip away the tooling and a design system is three things: shared decisions (tokens for colour, spacing, and type), shared parts (a component library in design and in code), and shared rules for when to use which part. The Figma library and the React package are just where those agreements live.
That framing matters because it tells you what "done" means. A system is working when a new screen can be designed and built without inventing anything, and when a brand tweak lands everywhere by changing one token. It is not working when the library exists but every squad still ships bespoke buttons.
Start with an audit, not a wishlist
The first task is always an interface inventory. Screenshot every screen, cut out every button, input, card, and modal, and cluster the duplicates on one board. It takes two or three days and it is always uncomfortable. One retail client counted 23 distinct text styles on a single checkout flow.
The audit gives you two things a wishlist cannot: an honest scope, because you can count exactly how many variants you are consolidating, and instant buy-in, because nobody argues for keeping 14 greys once they are all pinned up next to each other.
Tokens before components
Teams want to start with components because components are visible. Start with tokens instead. Colour, spacing scale, type scale, radii, and shadows are the alphabet everything else is spelt with. If you build components first, every later token change becomes a breaking change.
Keep the token set small and semantic. Name for role, not appearance: surface-raised, text-muted, border-strong. A colour named blue-500 tells an engineer nothing about when to use it, and it becomes a lie the day the brand shifts to teal.
The first ten components
Build components in order of leverage: how often they appear times how often they are rebuilt badly. For almost every product that ordering starts the same way.
| Priority | Component | Why first |
|---|---|---|
| 1 | Button | Appears on every screen, most-forked component in any codebase |
| 2 | Input and field wrapper | Labels, errors, and help text get reinvented constantly |
| 3 | Select | Single and multi in one component, hardest to retrofit later |
| 4 | Modal and drawer | Focus handling and layering bugs hide here |
| 5 | Table | The densest surface in most B2B products |
| 6 | Toast and alert | Feedback patterns drift fastest without a home |
| 7 | Card | Cheap to build, huge visual consistency payoff |
| 8 | Tabs | Keyboard behaviour is always wrong in bespoke versions |
| 9 | Badge and pill | Status colour rules belong in one place |
| 10 | Empty state | The most-skipped screen in every product |
Ship the system in code and in Figma at the same time, and make the code version the source of truth. A design-only system drifts within a quarter, because engineers build what the codebase makes easy, not what the Figma file suggests.
Governance without a committee
Small teams cannot afford a design system team, and they do not need one. What they need is a clear contribution path. Ours fits in four lines: anyone can propose a component or token in a short RFC, one named maintainer per discipline reviews it within a week, additions ship behind a minor version, breaking changes are batched into scheduled majors.
The other half of governance is a hard rule about forking: if a shared component is missing a feature, you extend the shared component, you do not copy it into your feature folder. One fork is a workaround. Three forks is a dead system.
Measure adoption, not completeness
The health metric that matters is the share of interface built from system parts. You can measure it: lint for raw hex values and hardcoded pixel sizes, count imports of the component package versus bespoke equivalents, and track it per squad. On a recent engagement that number went from 31% to 84% in four months, and the design-review time for a new feature dropped from days to hours.
Accessibility belongs in the system too, because fixing it once in a shared component fixes it everywhere. We wrote about that approach in accessibility as a feature. And if your team wants help getting from audit to adopted system, our experience design practice runs this exact playbook.
