Most design systems die the same way: not with a dramatic collapse, but with a slow bleed. A new designer joins and can't find the button they need, so they copy one from a Figma frame and tweak the radius. An engineer ships a "one-off" variant that becomes three variants that becomes the thing everyone uses. Six months later, nobody knows which button is the button, the documentation hasn't been touched since launch, and the team is quietly rebuilding from scratch — usually calling it a "v2."
I've built and inherited enough of these to know that the systems which survive are not the cleverest ones. They're the ones with the most boring habits behind them. Here's what those habits look like in practice.
Start with primitives, not components
The first mistake teams make is opening Figma and drawing a button. The button is the last thing you should draw. Long before the button, you need its ingredients: the colour it sits on, the type it carries, the space around it, the corner it rounds to, the shadow it casts when hovered. These primitives — tokens, in the trade — are the actual design system. Components are just the most visible packaging of those tokens.
A token is a named decision: --color-accent, --space-4, --radius-lg. Decisions belong in one place, get referenced everywhere, and change in one place when the world changes. Tokens are how a forty-engineer team ends up with one shade of clay instead of fourteen near-identical ones with names like brandPrimaryNew2_FINAL.
A token you reach for ten thousand times is worth more than a component you use ten. Optimise for the decision you'll keep making, not the artefact you'll ship once.
Name things for the question, not the answer
The most common naming argument in any system is semantic versus descriptive — should the primary action colour be called --color-brand or --color-clay? Both lose. The right name answers the question "what role does this play?" rather than either "what brand does it belong to?" or "what does it look like?"
Our convention is to name by intent and layer by scale: --color-action (the role), aliased to --color-clay-500 (the value, on a scale). When we rebrand, we change one alias. When a designer asks "what do I use for the submit button?", the name tells them. Nobody has to memorise a hex code or argue about whether clay is really more of a terracotta.
The test for a good name
Can a new joiner, given only the name and no context, guess correctly nine times out of ten where to use it? If yes, the name earns its keep. If they have to ask, the name is doing archaeology instead of communication.
Treat documentation as a product
A design system with no docs is a rumour. A design system with docs nobody updates is a lie. The systems that last treat their documentation the way they treat their components: it has owners, a changelog, a review process, and a place in the roadmap. If nobody's job description includes "keep the docs honest," the docs will rot within a quarter.
The minimum viable doc for a component answers four questions: what is it for, when should I not use it, what are its variations, and what does accessible usage look like. Most docs answer the first and third. The systems I trust most spend as many words on the second — the "don't" — as on everything else combined. Knowing when a component is the wrong tool is half of using it well.
Governance is just a small, named group
"Everyone owns the design system" means nobody does. Contributions stall in a queue because nobody has the authority to merge. Quality drifts because nobody has the authority to reject. The fix isn't bureaucracy — it's a named group of two or three people with a standing thirty-minute slot, a shared inbox, and the explicit remit to say both yes and no fast.
The healthiest contribution model I've seen treats the system like an open-source project inside the company: anyone can propose, the maintainers decide, decisions are written down. It sounds heavy. In practice it's lighter than the alternative, which is three competing button variants merged by three different teams on the same Friday.
Deprecate loudly, delete quietly
A system that never removes anything grows a graveyard. Old tokens linger for years after the component that used them is gone, because someone might be referencing them, somewhere. The solution is the same as in any healthy codebase: mark deprecated, warn in the tooling, set a removal date, and when the date comes — remove. Provide a codemod or a migration guide, then delete.
The teams that won't do this are the teams that end up rebuilding from scratch every two years. Subtraction is a feature.
Resist premature abstraction
This is the one that bites ambitious teams. You build a button. Then someone needs a button with an icon. Then a button that's a link. Then a button group. Before long you've generalised <Button> into a seventeen-prop component that nobody fully understands, because you abstracted before you had three real instances to learn from.
Our rule of thumb, borrowed from smarter people than us:
- Wait until you have three concrete, shipped examples before promoting anything to the system.
- If two of those three examples disagree on a detail, the detail probably shouldn't be a prop yet — it should stay local.
- Every prop is a future maintenance debt. Add it when the cost of not having it exceeds the cost of owning it.
- A component with more than two Boolean flags is usually two components pretending to be one.
The fastest way to kill a system is to make it clever before it's correct.
Test the things that matter
Components get unit tests; tokens rarely get any. But a broken token — say, --color-action that silently lost its contrast against the new background — propagates everywhere instantly. The healthy systems I've worked in run a tiny test suite over the token layer: contrast checks against every text/background pairing, a snapshot of the resolved values, a guard that fails the build if a primitive is referenced before it's defined.
It's twenty lines of code. It catches the bugs that visual review never will, because visual review can't see the difference between #c9794e and #c9784e at a glance. Your CI can.
The system is the boring part
None of this is exciting. Tokens, naming, docs, governance, deprecation, restraint — there are no conference talks that get standing ovations for a well-maintained --space scale. But the systems still standing in five years will be the ones that did this work quietly, every week, while everyone else was rebuilding theirs for the third time.
A design system isn't a library of components. It's a set of shared decisions, defended over time. Defend the decisions. The components will follow.