A Design System Is a Refusal
By Trent Design Development 4 min read
Most design systems are described by what they contain: a button, a card, a set of tokens, a documentation site. That inventory is the least important thing about them.
What makes a design system work is what it refuses. Every time it says “there is one button, and this is it”, it removes a decision from every page that will ever be built. The removed decisions are the product. The components are the delivery mechanism.
One of everything, and the cost of the second
Take the button. A system with one button has settled a question permanently: what does an action look like here? A system with two buttons has not settled it — it has documented that the question is open and provided two answers, which means every future page must decide, which means the decision recurs forever at zero marginal cost to the person adding the third.
The second one is where the loss happens. Not the tenth. By the tenth everyone already knows the system does not decide anything.
So the useful rule is stated as a boundary rather than a preference: a second primitive is a dialect, not a variant. A second Button, a second Card, a second link treatment, a second arrow affordance — each is a fork of a decision the system existed to close.
Where the rule stops applying
This gets misapplied, and the misapplication is expensive in the other direction.
“One of everything” is a rule about primitives. At the section layer it is wrong, and following it there produces a system that can only build one page.
A hero is not a primitive. It is an arrangement — of the one button, the one type scale, the one frame motif, the one stat block. Ten hero layouts built from the same primitives is inventory: it is depth, and depth at the section layer is what stops every page looking identical. Ten hero components, each with its own colours and spacing, is ten dialects.
The test is simple. Does the new thing introduce a new visual decision — a colour, a type step, a spacing value, an interaction? Then it is a dialect and the answer is no. Does it only rearrange existing decisions? Then it is a layout and the answer is probably yes.
Surfaces, not props
The most common structural failure in a component library is making every component responsible for knowing where it is.
You end up with <Card theme="dark" />, <Heading onDark />, <Button variant="light" /> — and now the correctness of a page depends on every author passing the right value to every component in every nesting. It will be wrong somewhere. It is always wrong somewhere.
The alternative is to make the ground declare itself once, and have everything inside read from it:
<section data-surface="inverse">
<!-- every heading, body, hairline, link, icon and focus ring
inside is now correct, with nothing passed down -->
</section>
The components stop having a surface prop at all, because there is nothing for an author to get wrong. A card knows to step one luminance level from whatever it is sitting on; it does not know, and does not need to know, what that is.
This matters twice as much once a reader can choose a theme. A section that hard-codes black is a black hole for someone reading in light mode. Semantic roles — canvas, raised, inverse — resolve per theme; literal colour names cannot. Keep the literals available as escape hatches for the cases that genuinely must not move (a photographic letterbox, a brand plate) and reach for a role every other time.
The thing that decides whether any of it survives
A design system decays through reasonable exceptions, and the reasonable exception always arrives as an inline style.
One style="color: …" on one component, because the token was not quite right and the deadline was real. It ships. Nothing breaks. Then there are seventy-nine of them across fifteen files, every one reaching directly into the cascade, and the system is now a suggestion.
The remedy is not vigilance. It is that the exception has to be visible — a build assertion, a lint rule, a review checklist item — so that taking it is a decision somebody makes rather than a thing that happens.
What “done” looks like
A design system is finished, for a given site, when a new page can be built without anyone choosing a colour, a font size, a spacing value or a border. Not because those decisions are forbidden, but because they have already been made, in one place, and there is no reason to revisit them.
At that point the components are almost incidental. What you have is a set of questions nobody has to ask again — which is the only thing that scales.
Read next
The whole archive-
Cloud
The Bill Is the Architecture
Cloud cost is usually treated as an optimisation problem to be solved after the fact. It is more honest to read the invoice as a description of the system you actually built, including the parts you did not mean to.
-
Writing & Content
RSS Is Still the Best API You Can Ship
A feed costs a few dozen lines, requires no keys, no versioning and no support, and gives every consumer — reader, aggregator, script or agent — the same view of your archive. Almost nobody ships one properly.
-
SEO
A Taxonomy Is a Commitment, Not a Filing Convenience
Categories, subcategories and tags look like three flavours of the same idea. They are three different promises about permanence, and confusing them is how a site ends up with two answers to what a page is about.
Keep reading
More on Design
Every vertical on this site carries its own writing, its upcoming events and its answers on one page — and the whole archive is available as a feed with a real publication date on every item.