What is it?
A design system is the shared language a team builds UIs from: tokens (color, space, type), primitives (Button, Input, Dialog), and the rules for composing them. Modern systems lean on headless libraries (Radix, React Aria, Base UI) for behavior + accessibility, and ship the styling on top — the shadcn/ui model.
Why it matters
Every company past a handful of engineers has a design system, official or accidental. Knowing how tokens, primitives, and composition fit together is what lets you contribute to one — or build the one a small team is missing. It's the bridge from "I style components" to "I architect UI."
What to learn
- Design tokens: the single source of truth for visual decisions
- Headless primitives: Radix, React Aria, Base UI — behavior without styles
- The shadcn/ui pattern: copy-paste components you own and restyle
- Composition: compound components, slots, polymorphic
asprops - Variants: class-variance-authority (cva) and type-safe styling
- Documentation: Storybook, or a living styleguide route
- Versioning + breaking changes when others depend on you
Common pitfall
Building primitives from scratch — your own dropdown, your own dialog, your own combobox. Accessible interactive components are deceptively hard (focus management, keyboard nav, ARIA, screen readers). Use a headless library for behavior and own only the styling. Reinventing Radix is a months-long detour most teams regret.
Resources
Primary (free):
- shadcn/ui · docs
- Radix Primitives · docs
- class-variance-authority · docs
- Design tokens — W3C community group · article
Practice
Build a small component library: a Button with three variants (primary,
secondary, ghost) using cva, a Dialog built on Radix or Base UI, and a
token file for colors + spacing. Document them on a /styleguide route.
Done when you can drop the Button into any project and restyle it by
changing tokens only.
Outcomes
- Build a token system that drives a whole component library.
- Use a headless primitive for behavior and own only the styling.
- Create type-safe variants with class-variance-authority.
- Decide build-vs-adopt for any UI primitive with a real reason.