A design system is easy to start and hard to keep. The first two months are enjoyable: colours get named, spacing becomes a scale, buttons stop having eleven variants. Then real product pressure arrives — a launch date, an enterprise customer with unusual requirements, a marketing campaign that needs something the system does not cover — and the library begins to drift from the product. Six months later the codebase has three button implementations again, and nobody trusts the Figma file.

The systems that survive are not the most beautiful ones. They are the ones designed around how teams actually make decisions under deadline pressure.

Start from the product, not from the grid

Teams often begin with foundations: type ramp, spacing tokens, colour palette, elevation. Foundations matter, but building them in isolation produces a system that answers questions nobody asked. A better starting point is an audit of the screens people use most. Take the five highest-traffic flows, inventory every component in them, and count how many variations of the same idea already exist. That count is your real backlog.

Working this way gives you two advantages. The first components you ship remove real duplication, so adoption is a saving rather than a cost. And the foundations you extract are ones the product already needed, which makes them much harder to argue with later.

Name things for intent, not appearance

A token called grey-200 tells you what it looks like. A token called surface-muted tells you what it is for. The second survives a rebrand, a dark mode, and an accessibility fix; the first has to be found and replaced everywhere. The same rule applies to components: a DangerButton communicates intent, while a RedButton communicates a decision you will regret when the brand palette changes.

If a designer and an engineer would describe a component differently, the name is wrong.

Document the decision, not just the component

Most documentation explains props and shows a canvas. What teams actually need is guidance on choice: when to use a modal instead of a side sheet, when a toast is the wrong pattern, why the destructive confirmation requires typing a name. Documenting the reasoning turns the system into a shared judgement, which means people follow it when you are not in the room.

  • One paragraph of intent for every component: what problem it solves.
  • A short 'use this instead' list for the closest alternatives.
  • One real product screenshot, not just an isolated example.
  • Accessibility notes written as requirements, not suggestions.

Give the system an owner and an escape hatch

Systems without an owner rot, and systems without an escape hatch get bypassed. Both failures look the same from the outside: teams shipping one-off components. Name a maintainer with real time allocated, and publish a sanctioned path for exceptions — a clearly marked experimental namespace, with a review at the end of each quarter to promote or delete what is in it. Exceptions that are visible become future components. Exceptions that are hidden become technical debt.

Measure adoption, not completeness

Component count is vanity. The useful metrics are the share of UI rendered from system components, the number of duplicate implementations still in the codebase, and the time it takes a new engineer to build a standard form. If those three numbers improve each quarter, the system is working — regardless of how many components remain unbuilt.

A design system is a product with internal customers. Treat it that way: talk to its users, watch where they struggle, ship improvements on a rhythm, and delete what nobody uses. The reward is compounding — every product decision after that starts a step ahead.