← Back to all posts

Building a design system from scratch.

I've built three design systems from the ground up. Two of them failed. The one that survived wasn't the most comprehensive — it was the one the team actually used. Here's what made the difference.

Organized color swatches and design components laid out on a desk

The first design system I built had 40 components before we shipped a single feature with it. It had variants for everything, a gorgeous Storybook, and a Figma library that could rival any design agency. Nobody used it. The product team kept writing their own buttons because ours didn't quite fit their use cases, and the system slowly became a museum of good intentions.

The second attempt was more measured but still failed — this time because we built it in isolation, without enough input from the teams who were supposed to adopt it. The third time, we started differently. We started with the product.

Why most design systems fail

They're too ambitious. A team locks themselves in a room for three months and emerges with a comprehensive component library that solves every conceivable interface problem. The trouble is, it doesn't solve the actual problems the product teams are facing right now.

Design systems fail when they're built as platforms before they're proven as products. Build for your product first. Solve the real, repeated UI problems your team encounters every sprint. Only then should you start abstracting for the broader organization. A design system that ships with five components your team actually reaches for beats one with fifty that collect dust.

Start with tokens, not components

Before you build a single button, define your design tokens. Colors, spacing scales, typography, border radii, shadows — these are the atoms of your system. Get these right and components almost design themselves, because every decision starts from a shared vocabulary.

Use CSS custom properties. They cascade, they're runtime-modifiable, and they make theming trivial. A well-structured token system is worth more than twenty components, because tokens compound across every page, every view, every component — even the ones you haven't built yet. When a developer writes var(--space-4) instead of 16px, they're participating in the system without even thinking about it.

The first five components

Button. Input. Card. Modal. Toast. Build these first. They cover roughly 80% of interfaces in most applications, and each one teaches you something important about your API patterns — how you handle variants, how you manage state, how you compose elements together.

Resist the urge to build speculatively. Don't build a data table until someone asks for it three times. Don't build a date picker until you've exhausted the native one. Every component you ship is a component you maintain, and maintenance is where design systems go to die. Start small, ship fast, and let real usage tell you what to build next.

API design for components

Components are developer-facing products. Props are the API. And like any good API, the best component interfaces share three qualities: they're small (fewer than eight props), predictable (they follow platform conventions), and composable (they work with children, not configuration objects).

Consider the variant versus className approach. A variant prop gives you control and consistency — variant="primary" always looks the same. A className prop gives you flexibility but sacrifices consistency. The right answer is usually both: expose variants for the common cases and allow className overrides as an escape hatch. But make the escape hatch feel like an escape hatch, not the front door.

Documentation is adoption

If it's not documented, it doesn't exist. This isn't a platitude — it's literally how developers discover and evaluate tools. Storybook or an equivalent interactive documentation site is not optional. It's the storefront of your design system.

Include do/don't examples. Show the component in context, not just in isolation. The best documentation answers "when do I use this?" not just "how do I use this." A developer looking at your Button docs should walk away understanding not just the props, but when to use a ghost button versus a primary button, when a link is more appropriate, and what the loading state looks like in a real form.

A design system with 12 well-documented components that everyone uses beats a system with 80 components that nobody trusts.

Closing thought

A design system is a conversation, not a deliverable. It evolves with the product, with the team, with the users. The measure of success isn't component count — it's how many times a developer reaches for the system instead of writing custom CSS. It's how many design reviews end with "that's already in the system" instead of "we need to build that."

Build less. Document more. Listen to the teams who use it. The system that survives isn't the most complete — it's the most trusted.


↳ Keep reading

More from the blog.

— Stay in the loop

Like what you read?

Get an email when I publish something new. Roughly monthly, never spam.