What a design system actually is
A design system is more than a color palette or a folder of components. It's three layers working together as the single source of truth for how a product looks and behaves:
Design tokens: the atoms
Tokens are named design decisions stored as variables — one place to define every color, space, and size. In CSS they're custom properties; components reference the name, never a raw value.
:root { --color-brand: #7c3aed; --color-text: #0f172a; --space-2: 8px; --radius: 10px; --font-body: 'Inter', sans-serif; } .button { background: var(--color-brand); border-radius: var(--radius); }
--color-brand once and every button, link, and badge that references it updates instantly. You'll see exactly that in the live demo in Step 6.A color system, not just colors
Systems organize color two ways. A scale gives each hue numbered steps (50 lightest → 900 darkest). Semantic tokens map meaning to those steps (“primary,” “danger,” “surface”) so components ask for a role, not a raw color.
A brand scale
Semantic roles
| Semantic token | Points at | Used for |
|---|---|---|
| --color-primary | violet-600 | Main actions, links. |
| --color-surface | white / slate-50 | Card & page backgrounds. |
| --color-danger | red-600 | Errors, destructive actions. |
The typography scale
Pick a base size (usually 16px) and a ratio, and generate a type scale — a fixed set of sizes. Designers choose from the scale instead of inventing arbitrary sizes, so headings and body text stay in harmony.
--font-heading, --leading-tight — so type is never a one-off guess.The spacing scale
Consistent spacing is what makes a UI feel calm and deliberate. Systems base spacing on a unit — usually 4px or 8px — and only use multiples of it. No random 13px margins.
Components built from tokens
Components assemble tokens into reusable parts. Because they reference token names, re-theming is instant. Click a brand color below — one token changes, and the button variants, the link, and the badge all update together:
Card component
This card, its badge, and the buttons all read from one --brand token.
Variants & states
A real component isn't one appearance — it's a documented set of variants (primary, secondary, ghost) and states. Every interactive component should define all of these:
| State | Must show |
|---|---|
| default | The resting appearance. |
| hover | Feedback that it's interactive (darken, lift). |
| focus | A visible focus ring — essential for keyboard users. |
| active | The pressed moment. |
| disabled | Clearly non-interactive, lower contrast. |
--brand-d) and tab to it (a focus ring appears). The disabled button shows the non-interactive state. Documenting all states is what separates a system from a sketch.Documentation & naming
A system is only as good as its docs. Each component needs: what it is, when to use it (and when not), its variants and props, accessibility notes, and do/don't examples. Clear, predictable naming ties it together.
- Token naming: go from general to specific —
color-bg-surface,space-inset-lg. Consistent prefixes make tokens discoverable. - Component naming: name by role, not appearance —
Button/Alert, notGreenBox. - Do / Don't: pair every guideline with a visual example of the right and wrong way.
Systems you can learn from
The biggest companies publish their design systems openly — a goldmine for seeing how tokens, components, and guidelines fit together at scale:
| System | By | Known for |
|---|---|---|
| Material Design | The most widespread; deep guidelines & theming. | |
| Human Interface | Apple | Platform-native clarity across iOS/macOS. |
| Polaris | Shopify | Exemplary component docs & content guidelines. |
| Carbon | IBM | Open-source, token-driven, enterprise scale. |
| Primer | GitHub | Practical, developer-focused, fully open. |
Design system checklist
- Values live as tokens (CSS variables), never hard-coded in components
- Color has a scale + semantic roles (primary, surface, danger)
- Type and spacing follow fixed scales (e.g. an 8-point grid)
- Components define every variant & state (incl. focus & disabled)
- Naming is consistent and role-based; everything is documented
- Design (Figma) and code share the same token names