Building a Design System from Scratch: A Practical Guide
Why Build a Design System?#
A design system isn't a component library. It's an agreement — a shared language between designers, developers, and stakeholders about how your product looks, feels, and behaves.
Without one, you get drift: buttons that look slightly different across pages, spacing that varies by whoever built the feature, and colors that multiply like rabbits. With one, you get velocity: new features ship faster because the decisions are already made.
Step 1: Audit What You Have#
Before creating anything new, catalog what already exists. Open your product and screenshot every unique instance of:
- Buttons (sizes, variants, states)
- Typography (headings, body, captions, labels)
- Colors (backgrounds, text, borders, accents)
- Spacing (padding, margins, gaps)
- Form elements (inputs, selects, checkboxes, radios)
- Cards and containers (elevation, border radius, padding)
- Icons (sizes, styles, sources)
Paste them all onto a single canvas. The inconsistencies will be immediately obvious — and motivating.
Speed Tip
Use Figma's selection colors panel to quickly identify how many unique colors exist in your file. You'll likely find 40+ when you should have 12.
Step 2: Define Your Foundations#
Foundations are the atomic decisions everything else builds on.
Color Palette#
Build a semantic color system, not just a list of hex values:
| Token | Purpose | Example |
|---|---|---|
color-bg-primary | Main background | #0A0A0B |
color-bg-secondary | Card/panel backgrounds | #141417 |
color-text-primary | Main readable text | #F5F5F5 |
color-text-muted | Secondary text | #8B8B8D |
color-accent | CTAs, links, active states | #A259FF |
color-success | Confirmations | #34D399 |
color-warning | Caution states | #FBBF24 |
color-error | Errors, destructive actions | #EF4444 |
Each color should serve a role. If you can't name the role, you probably don't need the color.
Typography Scale#
Choose one typeface (two at most) and define a clear scale:
Display: 48px / 56px line-height / 700 weight
H1: 36px / 44px / 700
H2: 28px / 36px / 600
H3: 22px / 30px / 600
Body: 16px / 26px / 400
Small: 14px / 22px / 400
Caption: 12px / 18px / 500
The ratio between sizes matters more than the exact values. A consistent ratio (like 1.25× or the "Major Third" scale) creates visual harmony.
Spacing Scale#
Use a base-4 or base-8 scale for spacing:
4px → xs
8px → sm
12px → md
16px → lg
24px → xl
32px → 2xl
48px → 3xl
64px → 4xl
Everything in your UI should snap to this grid. No magic numbers.
Step 3: Build Core Components#
Start with the components you use everywhere, not the exotic ones.
Priority order:#
- Button — primary, secondary, ghost, destructive, sizes (sm/md/lg), states (default, hover, active, disabled, loading)
- Input — text, password, email, with labels, helper text, error states
- Card — basic container with consistent padding, radius, and elevation
- Badge / Tag — for status indicators and labels
- Avatar — image, initials fallback, sizes
- Modal / Dialog — overlay, focus trap, close behavior
- Toast / Notification — success, error, info, warning
Common Mistake
Don't try to build every component upfront. Start with 5-7 core components, ship them, gather feedback, then expand. A half-finished system that nobody uses is worse than no system at all.
Component anatomy#
Every component should define:
- Variants — visual styles (primary, secondary, ghost)
- Sizes — sm, md, lg (at minimum)
- States — default, hover, focus, active, disabled, loading
- Slots — where content goes (icon left, label, icon right)
- Behavior — what happens on click, keyboard interaction, screen reader announcement
Naming conventions#
Be boringly consistent:
Button / Primary / Medium / Default
Button / Primary / Medium / Hover
Button / Primary / Medium / Disabled
Button / Secondary / Small / Default
...
This naming pattern scales. When you have 200 components, you'll be grateful for the structure.
Step 4: Document Everything#
A component without documentation is a component nobody will use correctly.
For each component, document:
- When to use — and when NOT to use
- Anatomy — labeled diagram of parts
- Variants — visual examples of each
- Props / API — for developers
- Accessibility — keyboard behavior, ARIA attributes, screen reader expectations
- Do / Don't — common mistakes with visual examples
Where to document#
- Figma — component descriptions, variant annotations
- Code — Storybook or similar (interactive playground)
- Written docs — MDX site with search (your design system site)
The best documentation lives where people already work. If your designers live in Figma, put usage guidelines there. If developers live in VS Code, make sure the component API is discoverable via TypeScript intellisense.
Step 5: Establish Contribution Guidelines#
A design system is a living product. It needs governance:
- Who can add components? Define the proposal → review → merge workflow.
- How are changes communicated? Changelogs, version numbers, migration guides.
- What's the quality bar? Accessibility requirements, test coverage, documentation completeness.
- How are decisions made? RFCs for breaking changes, design reviews for new components.
Team Size Matters
For teams under 5, governance can be informal — a shared Figma file and a Slack channel. For teams above 20, you'll need formal processes: versioned releases, migration tooling, and a dedicated owner.
Step 6: Ship Incrementally#
The biggest risk with design systems is building in isolation for months and shipping a "big reveal" that nobody adopts. Instead:
- Week 1-2: Audit, define foundations (colors, type, spacing)
- Week 3-4: Build 5 core components, document them
- Week 5: Integrate into one real feature (not a demo)
- Week 6+: Gather feedback, iterate, expand
Every new component should be built because a real feature needs it — never in the abstract.
Measuring Success#
How do you know your design system is working?
- Adoption rate — what percentage of new features use system components?
- Contribution rate — are people outside the core team adding components?
- Consistency score — visual audit of production pages (fewer one-offs = better)
- Time to build — are new features shipping faster than before?
- Bug surface — fewer UI bugs from inconsistency
The ultimate metric: designers and developers choose to use the system because it makes their lives easier, not because they're told to.
Tools and Resources#
Design:
- Figma Variables and component properties for dynamic systems
- Tokens Studio plugin for design token management
Development:
- Storybook for interactive component documentation
- Chromatic for visual regression testing
- Style Dictionary for cross-platform token generation
Workflow:
- DesignKit tools — automate repetitive design tasks like batch exports and data population
Building a design system is a marathon, not a sprint. Start with what hurts the most, solve it well, and expand from there.