Decisions, not files
A design system is the set of decisions your interface has already made: which greys exist, which spacing values are allowed, what a button looks like in each state, how much space sits between a heading and its paragraph. The components and the documentation are how those decisions are stored — not the thing itself.
That's why copying someone else's component library doesn't give you a design system. You get their decisions, applied to your problem, and you'll still be arguing about spacing on the tenth screen.
Start with tokens
Tokens are named values — a colour, a spacing step, a font size — used everywhere instead of raw numbers. They come first because components are assembled from them; building components on raw values means changing a grey later requires finding every place it was typed.
:root { /* Colour: role names, not appearance names */ --color-bg: #fcf9f8; --color-surface: #f6f3f2; --color-text: #1c1b1b; --color-text-muted: #414754; --color-line: #dfe3ee; --color-accent: #0058c3; /* Spacing: the only gaps allowed */ --space-1: 0.25rem; --space-2: 0.5rem; --space-3: 0.75rem; --space-4: 1rem; --space-6: 1.5rem; --space-8: 2rem;}Note the naming. `--color-text-muted` describes the role; `--color-grey-400` describes the appearance. Role names survive a redesign and survive a dark theme — appearance names produce the absurdity of `--color-grey-400` being light blue in dark mode.
The four layers, in build order
| Layer | Contains | Worth building at |
|---|---|---|
| Tokens | Colour, spacing, type, radius, motion | Screen one |
| Primitives | Button, input, card, badge, link | Screen three |
| Patterns | Form layout, page header, empty state, table | Screen eight |
| Documentation | Rules, examples, and what not to do | When a second person joins |
The right-hand column is the part people get wrong in both directions. Tokens on day one cost almost nothing and save constantly. A documented pattern library on day one is a project that competes with your product for time and usually loses.
Rules make it a system
A component library with no rules becomes a drawer of similar-looking parts. The rules — written as plain sentences — are what keep it coherent.
- One primary button per screen
- Only spacing values from the scale; a new value means adding a token, not an exception
- Colour never carries meaning alone — pair it with an icon, a label, or a weight change
- Every interactive element has a visible focus state, and it's the same one everywhere
- If a component needs a seventh variant, question the design instead of adding it
The afternoon version
- Write down the colours actually in useYou'll find nine greys where you meant to have three. Reduce, then name them by role.
- Pick one spacing scale and one type scaleEight spacing values, six type sizes. Nothing outside them.
- Build button, input, and card against those tokensThree components covers most of an early product.
- Write five rules in a plain text fileThat file is the documentation until it needs to be more.
Common mistakes
- Building a component library before three screens exist to inform it
- Naming colours by appearance instead of role, which breaks the moment a theme changes
- Adding a variant for every one-off instead of questioning the one-off
- Treating the system as a design artefact that engineering copies by eye, rather than shared code
- Never deleting anything, until the system is larger than the product
Key takeaways
- A design system is stored decisions; components are just where they live
- Tokens first — components assembled from raw values can't be changed centrally
- Name by role, not appearance
- A handful of written rules is what separates a system from a parts drawer
Try it yourself
Screenshot three screens of your product and list every distinct colour and gap value across them. Reduce each list to the smallest set that still works, name them by role, and replace the raw values in one screen to see what breaks.
