Designpixil · Design Systems
How to Build a Design System for a Startup
How to build a design system for a startup: start from existing patterns, build tokens first, structure your Figma library, and roll out to engineering.
Most teams approach building a design system the wrong way. They start by looking at other companies' design systems — Google's Material Design, Shopify's Polaris, GitHub's Primer — and try to build something at that scale from the beginning. Six months later, they have a beautiful, comprehensive, thoroughly documented system that nobody uses because the product has changed three times since they started.
The right approach is nearly the opposite: start from what already exists in your product, extract the patterns that are already working, and build the system incrementally from the ground up. Boring, methodical, and much more likely to produce something your team actually adopts.
This post walks through how to build a design system for a startup — in the right order, with the right scope, without spending months on things that won't matter.
Start From the Product, Not From Scratch
The first mistake in every failed design system project is starting with a blank canvas. Teams open a new Figma file and start designing "the perfect button" before they've looked at the fifteen button variants already in the product.
Start with an audit. Open your existing product and take screenshots or Figma captures of every distinct UI pattern you can find. Look for buttons, inputs, cards, modals, navigation, tables, badges, alerts, empty states. You will find:
- Multiple versions of the same element (three different card styles, two button sizes that aren't systematically related)
- Patterns that are consistent and working well
- One-off designs that solved a specific problem and never got generalized
Sort what you find into three piles: keep and codify, harmonize and codify, or retire. The "keep" pile becomes the foundation of your component library. The "harmonize" pile needs design decisions made before you codify it. The "retire" pile gets replaced as those parts of the product get touched.
This audit also gives you a realistic scope. You're not building from zero — you're capturing and formalizing decisions that have already been made. That framing changes the timeline and the political difficulty of the project.
What to Build First: The Right Order
There's a specific build order that works. Ignore it and you'll end up redesigning your early work.
1. Design Tokens
Tokens are the foundation. Before you build a single component, define your tokens.
Start with color. You need a color scale (the full range from light to dark for your primary, secondary, neutral, and semantic colors), and you need semantic token names mapped to the scale. The scale gives you something like blue-500. The semantic token gives you color.primary.default which points to blue-500. When you need to change your primary color, you change one mapping and everything updates.
Semantic token names matter more than the underlying values. You want:
color.primary.default/.hover/.disabledcolor.surface.default/.raised/.overlaycolor.text.primary/.secondary/.disabled/.inversecolor.border.default/.strong/.focuscolor.feedback.error/.warning/.success/.info
Then spacing. Use an 8px base grid and define tokens at space.1 (4px), space.2 (8px), space.3 (12px), space.4 (16px), space.6 (24px), space.8 (32px), space.12 (48px), space.16 (64px). Resist the urge to add arbitrary values — every addition to the spacing scale is a future inconsistency.
Then typography. Define your type scale — size, line height, and weight at each step. Define semantic names: text.body.default, text.label.sm, text.heading.xl. Not just sizes, but usage-aware names.
Then define border radius, shadow, and motion tokens. These are smaller in scope but they matter for consistency.
In Figma, use Variables (the Figma token system) to implement these. For engineering, output to CSS custom properties or your chosen platform format using a tool like Style Dictionary.
2. Primitive Components
With tokens in place, build your primitives first — the smallest components that can't be broken down further.
The primitives every SaaS product needs:
- Button (sizes: sm, md, lg; variants: primary, secondary, ghost, destructive; states: default, hover, focus, disabled, loading)
- Input (text, number, password, search; states: default, focus, error, disabled)
- Checkbox and radio
- Toggle/switch
- Select / dropdown
- Badge / tag
- Avatar
- Icon (a wrapper for your icon set, not the icons themselves)
- Spinner / loading indicator
Each primitive should be built with:
- All variants as component properties in Figma
- All states accessible through properties or interactions
- Auto-layout so it scales correctly
- Token-connected fills, strokes, and text styles (not hardcoded values)
The rule for primitives: they should never be context-specific. A button doesn't know where it lives. A badge doesn't know what it's badging. Context-specific behavior belongs at a higher layer.
3. Compound Components
Compound components are made from primitives. They have their own logic but are still reusable across the product.
Examples:
- Form field (label + input + error message + helper text)
- Search bar (input + icon + clear button)
- Modal (overlay + container + header + body + footer)
- Dropdown menu (trigger + menu container + menu items)
- Toast / notification
- Data table (header, rows, pagination)
- Empty state
These are more product-specific than primitives, but they should still be generic enough to be reused in multiple contexts. A modal doesn't know what's inside it — that's determined by the pattern layer.
4. Patterns
Patterns are how components combine to solve specific product problems. A create-entity flow. A settings page layout. A dashboard card with a title, a KPI, and a sparkline. An onboarding checklist.
Patterns are documented in the guidelines layer — often as annotated screenshots or reference designs rather than reusable Figma components. They answer "how should we handle this type of problem" rather than "here is a reusable component."
You don't need to codify patterns at the start. Document the ones that keep coming up as you design new features. They'll accumulate naturally.
Figma Component Library Structure
The way you organize your Figma library determines whether designers can find components or spend time searching for them. Get this right from the start.
Use a three-page structure in the library file:
Page 1: Foundations — Color tokens, typography scale, spacing examples, shadow examples, iconography. This is reference, not interactive components.
Page 2: Components — All your built components, organized by category. Use the slash naming convention: Button/Primary/Default, Button/Primary/Hover, Input/Default/Text. This creates nested groupings in Figma's asset panel that mirror the component hierarchy.
Page 3: Patterns — Annotated reference designs for common product patterns. Not interactive components — these are documentation.
A few structural rules that matter:
Name components like engineering names them. If your codebase has a ButtonGroup component, your Figma library should have a Button Group component, not `Button Container" or "Grouped Buttons." This makes handoff dramatically less ambiguous.
Use Figma Variables for tokens, not Figma Styles. Variables are the current token system in Figma and they support modes (light/dark, brand themes). Styles are fine for typography but tokens should live in Variables.
Keep library components clean. Never mix "working designs" with library components in the same file. The library file should only contain the components as they're meant to be published. Working designs live in separate project files that consume the library.
Figma Variables and Token Naming Conventions
Token naming is a decision that will either save you or haunt you. Here's a convention that works:
[category].[variant].[scale].[property]
Examples:
color.primary.500(base scale)color.primary.default(semantic alias)space.4(16px)radius.md(medium border radius)shadow.md(medium shadow)font.size.body(body text size)
The critical rule: your engineering token names and your Figma variable names should be identical. If your CSS has --color-primary-default, your Figma variable should be color/primary/default (Figma uses slashes as separator). This one-to-one mapping eliminates an entire category of handoff errors.
Resist the temptation to be clever with naming. Tokens that read obviously are tokens that get used correctly. color.text.disabled is immediately understood. color.interaction.state.inactive is not.
Documentation That Actually Gets Used
Most design system documentation fails because it's written for the person who built the system, not the person using it.
Write documentation from the user's perspective. The user is a designer who needs to know which component to use, or an engineer who needs to know how to implement it. Write for those questions.
Each component in your documentation needs:
- What it is — one sentence
- When to use it — the positive case
- When not to use it — this is more important than the positive case
- Variants — visual examples of each variant
- States — visual examples of default, hover, focus, disabled, error, loading
- Props / API — for engineers, the component interface
- Do / Don't examples — real product examples of correct and incorrect usage
The format matters less than the content. Storybook works well for engineering-first teams. Zeroheight or Supernova works better for design-first teams. A custom Next.js site gives you the most control. Whatever format you choose, make it searchable and keep it updated.
The failure mode is documentation that gets written once and never updated. Treat documentation updates as part of any component change. If you update the Button component, you update the Button documentation in the same pull request.
Rolling Out to Engineering
The design system only has value when engineering is using it. The rollout is as important as the build.
Don't try to migrate the whole codebase at once. Pick a new feature being built and use it as the first implementation of the system. This gives you real feedback fast, surfaces integration problems before they're widespread, and creates internal advocates who've actually built with it.
Create a migration guide — a document that maps old patterns to new system components. "Previously you were using CustomButton.tsx with these props. Now use Button from the design system with these props." Concrete, not abstract.
Set up a Storybook instance early, even if it's incomplete. Engineers need to see and interact with the components, not just read about them. Storybook with controls (knobs) lets them explore variants and states without leaving their environment.
Establish a contribution model. What happens when an engineer needs a variant that doesn't exist? They shouldn't just build it in the feature file and move on. There should be a lightweight process: propose the addition, design review, add to the system, document it. This prevents the system from fragmenting as the team grows.
What Not to Do
A few patterns I've seen repeatedly that waste months:
Building for hypothetical future requirements. "We might need dark mode someday" or "we could go multi-brand" are not reasons to build the system's entire token architecture around themes you haven't designed yet. Build for what you need now. The token architecture can support future modes — but don't build the modes until they're real requirements.
Designing every possible component before engineering builds any of them. Design and engineering should work in parallel on the system, not sequentially. Design tokens and primitives, hand those off, then design compound components while engineering builds primitives.
Treating the design system as a design team project. If engineering isn't part of the build from day one, the system won't get used. Engineering needs to co-own the component API decisions. Design needs to accept that some design decisions will be constrained by what's practical to implement.
Skipping the audit and starting fresh. This always results in building components that conflict with existing ones. Do the audit first.
Summary
Build a design system in this order: audit what exists, define tokens, build primitives, build compound components, document patterns, roll out to engineering incrementally. Keep scope tight and resist building for hypothetical requirements. The best design system is the one that your team actually uses — not the most comprehensive one.
If you're not sure whether you're ready to start, read when to invest in a design system first. If you're ready and looking for help executing it, our design subscription includes design system work as part of ongoing engagements.
Frequently Asked Questions
How long does it take to build a design system for a startup?+−
If you're extracting from an existing product (which you should be), a minimal but production-ready design system — tokens, ~30 core components, documentation for each — takes roughly 6–10 weeks of focused design and engineering effort. Building from scratch takes longer and produces worse results because you're designing without the constraints of real product usage. After the initial build, plan for ongoing maintenance.
What should I build first in a design system?+−
Design tokens first, always. Colors, typography, spacing, border radius, shadow — the atomic decisions that everything else is built from. Once tokens are defined, build primitive components (buttons, inputs, badges). Then compound components (form fields, modals, tables). Patterns come last and are often documented rather than built as reusable components. Skipping tokens and starting with components always causes painful rework.
Should the design system be in Figma or in code?+−
Both, and they need to be in sync. Figma handles the design side — components, tokens as Variables, documentation for designers. Code handles the engineering side — components in React (or your framework), tokens as CSS custom properties or JSON. The token names should be identical in both systems. Figma components should map 1:1 to code components. When they diverge, trust breaks down and the system stops being used.
What's the biggest mistake teams make when building a design system?+−
Starting from scratch instead of from the product. Teams audit competitor design systems, get inspired, and start building idealized components that don't reflect how their product actually works. The result is a beautiful system that doesn't fit the product and doesn't get used. Always start with an audit of what exists. Extract and codify the patterns that are already working. Retire the ones that aren't. Build new components only when nothing existing fits.
How do we get engineers to actually use the design system?+−
Don't migrate the whole codebase at once — start with the next new feature being built. Create a migration guide that maps old patterns to system components. Set up Storybook so engineers can explore components interactively. Establish a contribution model so engineers can propose additions through a lightweight process rather than building outside the system. Engineering buy-in requires engineering involvement from the start of the build, not just at rollout.
Work with us
Senior product design for your SaaS or AI startup.
30-minute call. We look at your product and tell you exactly what needs fixing.
Related