TL;DR: Most design systems fail because they're designed in isolation. Build design systems that ship by designing backwards — start with constraints, build from code, measure shipping velocity.
The Problem Nobody Talks About
I've worked on three design systems. The first one never shipped. The second one shipped six months late. The third one is still shipping today.
The difference wasn't the design quality. It wasn't the tool we used (Figma, Storybook, whatever). It was who owned the system.
When Product Designers own a design system, they optimize for design. When Engineers own it, they optimize for infrastructure. When nobody owns it (the worst case), it optimizes for nobody.
As a Design Engineer, I learned something different:** design systems should optimize for shipping.**
Not shipping once. Shipping continuously.
The Design Engineer Perspective
Here's the core insight: most design systems are built top-down.
Designers create components → Engineers build them → Product teams use them
The problem? By the time engineers build what designers designed, the real constraints are already baked in. Engineers want to refactor, simplify, or restructure. Designers want to preserve the visual system. Nothing ships smoothly.
Design Engineers work bottom-up:
Understand constraints → Build primitives → Compose components → Design on top
This means:
- We design with the constraints of code, not despite them
- We build the smallest possible primitive first
- We don't over-architect "future flexibility"
- We ship fast and iterate
The result? Shipping velocity increases 2-3x.
The Framework: Build Design Systems That Ship
Here's the framework I use. It has four phases.
Phase 1: Start with Constraints (Week 1)
Before you design a single component, ask:
- What are we building? (Product type: SaaS, marketplace, enterprise tool?)
- What's the data we're designing for? (Real numbers: 100 users or 1M? Simple or complex?)
- What's the team structure? (One designer? 5? 50?)
- What's the shipping velocity target? (Sprint-based? Continuous deployment?)
These constraints define everything.
Example from my work: I built a design system for an enterprise CMS handling 50,000+ daily transactions. The constraint was real-time updates and massive data tables.
This immediately ruled out:
- Massive component library (bloat)
- Fancy animations on every interaction (performance)
- Highly customizable components (maintenance nightmare)
It required:
- Virtualized lists for data tables
- Constraint-based spacing (fixed token set, not infinite options)
- Primitive-first architecture (build small, compose big)
- Action: Document your 3-5 core constraints on a single page.
Phase 2: Design the Design System (Week 2-3)
Now design the system itself, not the components.
Start with design tokens, not components.
// tokens/spacing.ts
export const spacing = {
xs: '4px',
sm: '8px',
md: '16px',
lg: '24px',
xl: '32px',
} as const;
// tokens/typography.ts
export const typography = {
display: { fontSize: '32px', lineHeight: '1.2', fontWeight: 600 },
heading: { fontSize: '24px', lineHeight: '1.3', fontWeight: 600 },
body: { fontSize: '16px', lineHeight: '1.5', fontWeight: 400 },
caption: { fontSize: '12px', lineHeight: '1.4', fontWeight: 400 },
} as const;
// tokens/colors.ts
export const colors = {
primary: '#4F4E7B',
accent: '#EA7060',
neutral: '#F5F5F5',
text: '#1A1A1A',
} as const;
Why tokens first?
- They're the source of truth for every design decision
- Engineers can implement them in 1 day
- Changes scale across 100 components instantly
- Designers can iterate in Figma without rework
In Figma, build your token system first:
- Create Figma Variables (color, spacing, typography)
- Enforce constraints (no arbitrary values)
- Connect them to styles
- Use in components Action: Create token files and Figma Variables. Don't touch components yet.
Phase 3: Build Primitives, Not Components (Week 3-4)
Now build the smallest possible building blocks.
Most teams build components like this:
Button, Input, Card, Modal, Dialog, Drawer, Popover, Tooltip, Badge, Chip, Tag, ...
Too many. Build primitives instead:
Box, Text, Button, Input, Icon, Flex
Example: A Modal is just:
<Box role="dialog" aria-modal="true" {...overlayProps}>
<Flex direction="column" spacing="md">
<Text variant="heading">Title</Text>
<Box>{children}</Box>
<Flex gap="sm">
<Button>Cancel</Button>
<Button variant="primary">Confirm</Button>
</Flex>
</Flex>
</Box>
Benefits:
- 6 primitives scale to 100+ user-facing components
- Maintenance burden drops 90%
- New designers/engineers ramp up in days, not weeks
- Shipping velocity stays high indefinitely
Action: Define 5-8 primitives. Build them in React. Wire them to tokens.
Phase 4: Document + Iterate (Week 5+)
Now document. Not exhaustively—just enough.
For each primitive:
1.One-line description (what it does)
2.Usage example (copy-paste ready)
3.Token props (what it accepts)
4.Edge cases (what breaks, how to fix)
Use Storybook:
// Button.stories.jsx
export default {
title: 'Primitives/Button',
component: Button,
};
export const Primary = { args: { variant: 'primary', children: 'Click me' } };
export const Secondary = { args: { variant: 'secondary', children: 'Click me' } };
export const Disabled = { args: { disabled: true, children: 'Disabled' } };
export const Loading = { args: { loading: true, children: 'Loading...' } };
Ship this. Use it in real products. Then iterate.
After 2-4 weeks of real usage, you'll see:
Components that need tweaking
Tokens that aren't working
Patterns nobody's using
Fix those. Iterate fast.
How to Actually Ship This
Timeline:
- Week 1-2: Design tokens + Figma variables
- Week 2-3: Build primitives in React
- Week 3-4: Wire to Storybook + docs
- Week 4+: Use in a product, iterate
Team size:
- Solo: 4-6 weeks
- 2 people (designer + engineer): 2-3 weeks
- 3+ people: 1-2 weeks (parallelize)
The key: Ship incomplete > perfect. Ship real usage > hypothetical.
Why This Works
Design systems fail when they're:
1.Too ambitious (500 components, perfect documentation)
- *Designed in isolation *(not used by real products)
- Over-flexible (every use case covered, nothing is simple)
This framework avoids all three:
- Ambitious scope, small MVP: Tokens + 6 primitives can ship 80% of UI
- Built for real products: You use it immediately
- Constraint-driven: "What do we actually need?" beats "what could we need?"
Real-World Example: The Gas Cylinder CMS
I built a design system for an enterprise CMS handling 50,000+ daily transactions. Here's what shipped:
Week 1-2: Tokens
- 8 spacing values (4px, 8px, 16px, 24px, 32px, 48px, 64px, 96px)
- 5 typography levels (display, heading, body, small, caption)
- 4 colors (primary, accent, neutral, text)
- 2 border radius values (4px for small, 8px for large)
Week 2-3: Primitives
- Box (layout container)
- Text (typography)
- Button (action trigger)
- Input (form field)
- Table (data display, virtualized for performance)
- Flex (flexbox wrapper)
Week 3-4: Storybook + deployment
- 40 stories (variants of primitives)
- Published to team
- Ready to use
- Result: Shipped the first version of the product in 6 weeks. Without the design system, estimate was 12-14 weeks.
Why You Should Build This Way
- Speed: Tokens + primitives >> components-first
- Consistency: Token-driven design enforces constraints
- Scalability: Primitives scale to 100+ components
- Maintenance: 6 primitives to maintain, not 100 components
- Onboarding: New team members learn 6 things, not 100
Next Steps
If you're building a design system right now:
- Document constraints (data size, team size, shipping velocity goal)
- Define tokens (spacing, typography, color)
- Build 6 primitives (Box, Text, Button, Input, Flex, Icon)
- Ship to Storybook (don't wait for perfect)
- Use in a real product (iteration starts when it's used)
If you're joining a design system project:
Ask: "What are the constraints?" If the answer is vague, you're starting from the wrong place. Push for clarity.
Let's Talk
What's your design system pain point?
Are you:
- Building from scratch? (Start with tokens)
- Maintaining a bloated system? (Refactor to primitives)
- Trying to scale across teams? (Document ruthlessly)
- Shipping slow? (Cut scope, ship faster) Drop a comment. I read every one.
Also: Check out my portfolio for real-world design systems I've shipped. Examples include design token automation pipelines and component libraries that actually scale.
Resources
- Storybook: storybook.js.org — great for primitive documentation
- Figma Variables: figma.com/design-system — official guide
- Design Tokens: designtokens.org — spec and community
- Primitives approach: Phoebe Frontagé's "Design Systems That Ship" — original inspiration
About Me
I'm a Design Engineer who ships design systems in code. I specialize in Figma-to-React workflows, constraint-based design, and building systems that scale. Currently working on design systems for startups and enterprises.
Want to chat about design systems, design engineering, or shipping products? Hit me up on LinkedIn.
Have you built a design system that shipped fast? What did you do differently? Comment below — I'd love to hear your framework.
Top comments (0)