What Is a Design System? (And When You Actually Need One)
“Just make it consistent” is not an instruction a team of five designers and twelve engineers can follow without something written down. A design system is what gets written down — and, more importantly, what gets generated, versioned and enforced.
What is a design system, in one sentence?
A design system is a shared library of design tokens (colour, type, spacing), reusable components (buttons, cards, form fields) and the documented rules for using them, maintained as a single source of truth so a product looks and behaves consistently no matter who builds which screen.
It is not a style guide, which is usually a static document describing intent. It is not a component library on its own, which is usually just code with no rules attached. And it is not a Figma file, however tidy — a Figma file that the codebase does not read from is a suggestion, not a system.
The distinction matters because teams routinely announce they have a design system when what they have is one of the three parts. A design system is the tokens, the components, and the reasoning that connects them, kept in sync between the design tool and the codebase by something other than good intentions.
What problem does it actually solve?
Every product without one eventually accumulates the same failure mode: four slightly different shades of the same blue, three button components that all do the same job, and a new hire who has no way to know which one is correct. None of this is any one person's fault. It is what happens when consistency depends on memory instead of a shared reference.
The cost is rarely visible as a line item, which is why it goes unaddressed for so long. It shows up instead as a designer spending twenty minutes deciding a padding value that was already decided last quarter, an engineer rebuilding a dropdown because finding the existing one was slower than starting over, and a QA cycle that catches visual regressions no one intended to introduce.
A design system fixes this by giving every decision a single home. When a designer needs a warning colour, there is one token for it, not a colour picker. When an engineer needs a card, there is one to import, not a decision to make from scratch. The saving is not the hour spent building the component — it is the hundred small deliberations that never have to happen again.
When do you actually need one?
The honest answer is: later than most teams think, and earlier than most teams act. A one-person side project does not need a design system — it needs consistent instincts, which a single person already has. The need shows up at a specific, recognisable point, and usually more than one of these signals is true at once.
- More than one designer or more than one front-end engineer is working on the same product.
- The product spans more than roughly eight to ten distinct screens or templates.
- Editorial or non-technical teams need to assemble pages themselves, inside a CMS, without a designer present for every change.
- The product needs to support more than one brand, theme, or white-label client from the same codebase.
- Two codebases — say an Angular admin panel and a React customer app — need to look like the same product.
- You've caught yourself, more than twice, asking “which button is the real one?”
When you don't need one
This gets said far less often, so it is worth saying plainly. If you are pre-product-market-fit and the interface is going to be substantially rewritten within six months, a design system is premature. You would be systematising decisions that have not settled yet, and every change to the underlying idea would ripple through a structure built to resist change.
The same is true for a marketing site of a dozen pages built once and edited rarely, or an internal tool with four screens and one maintainer. In both cases a short conventions file — here are our five colours, here is the spacing scale, use these and nothing else — will get you ninety per cent of the benefit for two per cent of the effort.
Building a system too early is not a neutral mistake either. It creates an artefact that has to be maintained, and an unmaintained design system is worse than none, because people trust it and it is wrong.
What actually goes into one?
In practice, a working design system has three layers, and skipping the first one is the most common reason systems fail.
- Tokens — the raw values: colour, spacing, type scale, radii, shadow, motion timing. These are named, not hard-coded, so a value can change everywhere at once.
- Components — the assembled, reusable pieces: buttons, inputs, cards, navigation, built from tokens and shipped with every variant and state (default, hover, focus, active, disabled, loading, error, empty).
- Guidelines — the written rules for when to use which component and why, including accessibility requirements like contrast ratios, focus order and keyboard behaviour.
The layer everyone forgets: states and edge cases
A component that ships with only its default state is not a component, it is a picture. The states that get skipped are always the same ones, and they are always the ones that reach production unfinished: the loading state, the empty state, the error state, and the state where the content is three times longer than the designer assumed.
When I owned the design system across AcademyHQ and ConnectedRMS at HiUp Solutions, the single change that most reduced back-and-forth between design and engineering was making every component specification carry its full state matrix before it was considered done. It slowed the first version of each component down. It removed almost all of the second and third versions.
A useful test: hand the component to an engineer who was not in the design conversation. Every question they have to ask is a gap in the specification, and every gap will otherwise be filled by a guess.
Who owns it?
A design system with no owner decays at a predictable rate. But a design system owned by a walled-off central team becomes a bottleneck, and product teams route around bottlenecks by building their own components in a folder called `local`.
The model that works in small and mid-sized teams is a light one: one named maintainer who owns the tokens and the review bar, and a contribution route that lets any product engineer propose a component. Contributions get accepted into the system when a second team needs the same thing — not before. That threshold keeps the system from bloating with one-off components dressed up as shared ones.
Write down who decides. Ambiguity about ownership does more damage to a design system than any technical decision in it.
How to start without stopping delivery
The failure pattern here is the six-week design system project that delivers nothing shippable and gets cancelled in week four. The alternative is to build it out of work you were doing anyway.
- Audit first. Screenshot every button, input and card currently in production. The duplication in that grid is your business case, and it takes an afternoon.
- Agree tokens before components. Colour, spacing scale, type scale, radii. Nothing else. This is days, not weeks.
- Convert the next five components you were going to build anyway, building them from tokens instead of raw values.
- Document as you go, in the same repository as the code. A separate documentation site that lives elsewhere will fall behind within a quarter.
- Only then go back and migrate what already exists, highest-traffic screens first.
How do you know it's working?
Adoption is the only metric that matters, and it is measurable. Count the number of raw hex codes and hard-coded pixel values in the codebase and watch the number fall. Count how many components live outside the system. Both numbers should trend one way, and if they don't, the system is being avoided for a reason worth understanding.
The softer signal is quieter but just as reliable: design review conversations stop being about padding and colour and start being about whether the flow makes sense. That shift is the actual return on the investment.
What about Figma libraries, Storybook and the rest of the tooling?
Tooling is the last decision, not the first, and teams reliably get this backwards. A design system with agreed tokens and six well-specified components documented in a plain markdown file is worth more than an immaculate Storybook instance sitting on top of decisions nobody has made.
That said, the tools do earn their place once the decisions exist. A published Figma library gives designers the same components engineers have, and — critically — lets you deprecate a component centrally rather than by messaging people. Storybook or a similar component workshop is where states get built and reviewed in isolation, which is the single most effective way to stop the loading and error states from being skipped.
The one piece of tooling I would install before any of it is a token generator. Everything else improves how the system is communicated; the generator is what stops the system from becoming untrue.
Where design systems go wrong
The single most common failure is documentation drifting from the shipped code. Figma says one thing, the component library ships another, and trust in the system collapses the first time someone gets caught out by the gap. The fix is mechanical rather than cultural: tokens should be the same values in both places, generated from one source rather than maintained twice by hand.
The second most common failure is building the component layer before agreeing the tokens. A button built before the colour and spacing tokens exist has to be rebuilt the day those tokens are finalised. In the wrong order, a design system costs more than the inconsistency it was meant to prevent.
The third is treating the system as finished. A design system is a product with internal users, and like any product it needs a changelog, a versioning policy and someone who answers questions about it. The moment it stops being maintained, teams start working around it, and the workarounds become the new inconsistency.
The shortest version
Build tokens first, components second, documentation alongside both, never after. Give it one owner and an open contribution route. Start with the work already in your sprint rather than a separate project. And measure adoption, because a design system nobody uses is not a system — it is a folder.