← All essays

A design system that survives to the second project

A design system is easy to start and hard to keep. I've stood several up — and learned almost everything valuable from what didn't work.

June 10, 2026 · Roman Yakovlev

A design system is easy to start: you make a components folder, drop a button, an input and a modal into it, wire up Storybook — and there you go, it seems you have a design system. Six months later it turns out half the components are used by no one, three buttons live in the project in parallel, and the "system" itself is just a junk drawer that's unpleasant to open. I've been through this more than once, and learned almost everything valuable from what didn't work.

A design system is a product, not a folder

The main mistake is treating a design system as a component warehouse. A warehouse has no user; a product does. A design system's user is the developer who assembles an interface out of it. And if it's faster for them to write their own button than to find and understand yours, the system has lost — no matter how many components it holds.

Everything else follows from this. A product has documentation — so Storybook, or a live page with all component states, isn't a nice bonus but a survival condition. A product has feedback — so the system should grow from real usage, not from a fantasy of what might be needed someday.

A component is a unit of meaning

I hold to a simple rule: a component exists not because "we need another block of markup here" but because it owns a specific meaning — a card, a field, a loading state. This sounds banal, but it's exactly the violation of this rule that kills systems. When components are cut along a visual axis ("let's make a universal container with twenty props"), you get a monster you can neither understand nor reuse. When they're cut by meaning — the system stays readable as it grows.

A good component is honest about its states. Loading, empty, error, success — these aren't "edge cases, we'll add them later" but part of its definition. A system in which states are set explicitly isn't scary to assemble; a system where every screen reinvents error handling is scary to touch.

Where I went wrong

I built ahead of usage. The most expensive failure is designing a system "for growth", for projects that don't exist yet. An abstraction not validated by two or three real cases is almost always wrong. It's cheaper to duplicate a component twice and generalize on the third time, when you can see the real pattern, than to guess it in advance.

I underestimated the cost of maintenance. A design system is an ongoing cost, not a one-off contribution. It has to be versioned, documented, fixed, explained to the team. If there's no resource for that, it's more honest not to start: an abandoned system is worse than its absence, because people still try to use it.

I confused "built" with "adopted". Assembling the library is half the job. The other half is getting the team to believe in it and reach for it. That's work about people, not code: review, onboarding, the willingness to explain the same thing over again. A system is adopted not when it's technically good, but when it's trusted.

The sign of a healthy system

I've boiled it down to one thing for myself: it's faster for a developer to take it from the system than to make it themselves — and they know it. Everything else — Storybook, tokens, versions, documentation — is just a means of getting to that state. If a means doesn't bring you closer to it, it's excess.

A design system isn't about having lots of components. It's about an interface being assembled from understandable building blocks instead of re-coded every time. Everything else is implementation detail.