Shipping a design system your whole team can use
Plenty of design systems are beautiful in Figma and irrelevant in the codebase within a quarter. The failure is almost never the design work. It's that the library and the product were never actually connected.
Drift is the default outcome
A Figma library and a component library are two descriptions of the same thing, maintained by different people under different deadlines. Without a mechanism holding them together, they separate — quietly, one urgent fix at a time, until nobody trusts either.
The mechanism that works is shared tokens. Colour, spacing, radius and type scale defined once, consumed by both. When they come from one source, the two can't disagree about what "accent" means.
It's worth being precise about why drift is so hard to reverse once it starts. Each individual divergence is trivial — a one-off hex value under deadline, a slightly different padding because the component didn't quite fit. None of them is worth stopping the sprint for. But the moment a designer opens the product and sees something the library doesn't contain, the library has stopped being the source of truth, and every subsequent decision gets made against the product instead. The system doesn't collapse; it just quietly becomes documentation of a past state.
Start with tokens, not components
A design system implementation that begins with components has already skipped the part that does the work. Components are where the two sides differ most; tokens are where they can be made identical.
What's worth tokenising
Colour, spacing, type scale, radius, border weight, shadow and motion duration. That list is close to complete for most products, and the discipline is to keep it that way — every token you add is one more thing two teams have to agree on forever.
Name them for their role, not their appearance. A token called `accent` survives a rebrand; one called `blue-500` becomes a lie the first time the brand colour changes, and nobody will rename six hundred usages to fix it. The same logic applies to `space-4` over `16px`: the name should describe the decision, not the current value of it.
Make one side generate the other
Two hand-maintained lists of the same values will diverge, however careful everyone is. Export tokens from the design tool, or define them in code and have design consume them — the direction matters much less than the fact that only one of them is edited by a human.
This is unglamorous plumbing, and it is the single highest-leverage thing in the whole exercise. Once it exists, an entire category of inconsistency stops being possible rather than being something people have to remember.
Build the components people reach for
The instinct is to start with a full inventory — every button variant, every input state, every card. Most of it goes unused while the thing someone needs on Tuesday isn't there.
We start from the screens actually being built. Buttons, inputs, and whatever pattern the product repeats most. A system of eight components people use beats forty they work around.
In practice the first set is almost always the same: button, input and its label and error state, select, modal, table, empty state, and whatever card or list row the product repeats on every screen. Getting those genuinely right — every state, keyboard behaviour, focus handling — is worth more than a broader library where each piece is nearly finished.
Then let real screens pull the next component into existence. If a pattern appears twice it's a coincidence; three times and it belongs in the system. Building ahead of that produces abstractions shaped by a guess about future usage rather than by actual usage, and those are the ones people quietly work around.
Document decisions, not just usage
Most documentation says what a component does. The useful part is when to use it and what to use instead. "Secondary buttons pair with a primary; never put two primaries in one view" prevents more inconsistency than any prop table.
That's also what makes a system survive its authors. A team that knows why a rule exists can extend it. A team that only knows the rule will break it the first time it's inconvenient.
Keep it next to the code. Documentation in a separate tool goes stale on a predictable schedule, because updating it is a second task that nobody's sprint accounts for. A page rendered from the components themselves can't describe a version that no longer exists.
And write down the rejections. "We don't have a tertiary button, here's what to use instead" answers a question that will otherwise be asked every few months and answered differently each time.
Someone has to own it
A design system with no owner is a shared folder. The failure isn't dramatic — it's that a component needs a change, no one is responsible for making it, so the change happens locally in one product instead, and the system is now behind.
It doesn't need a dedicated team. It needs a named person who reviews additions, and a contribution path so that a product engineer who needs a new variant can add it in a day rather than waiting a quarter. If contributing is slower than working around it, people will work around it — and they'll be right to, because they have a deadline.
This is usually where an outside design partner earns their fee, and it's how we approach design systems work: build the tokens and the first components with your team rather than for them, so ownership is already internal by the time we leave.
How you know it's working
The measure is not how complete the library looks. It's what percentage of new screens are built from it without modification, and how often someone drops to raw markup because the system didn't have what they needed.
Track the second number in particular — every workaround is a bug report about the system, and a cluster of them in one area is telling you which component is wrong. A system nobody works around is finished enough, however small it is.
When not to build one
Below roughly a dozen screens, a design system is overhead. You'll spend longer maintaining the abstraction than you'd spend duplicating the markup, and you'll lock in patterns before you know whether they're right.
We say so when it applies. The point of a system is leverage, and leverage needs something to lift.
The same reasoning applies to most early architecture decisions — build for the constraint you can name, not the one you can imagine. We go through that in how we pick the right foundation for your product, and through the version that applies to multi-tenant products in choosing the right backend for a new SaaS build.
SYS — Common questions
How long does a design system implementation take?
The useful first version is a few weeks, not a quarter: shared tokens wired into both the design tool and the codebase, plus the six to eight components the product actually repeats. Anything presented as a six-month design system project is usually building inventory ahead of demand — the parts that create leverage arrive early, and the rest should follow real screens.
Should we use an off-the-shelf component library instead?
Often yes, especially early. An unstyled, accessible component library handles the genuinely hard parts — focus management, keyboard behaviour, screen reader semantics — and you apply your tokens on top. Building those primitives from scratch is a large amount of work with a high chance of subtle accessibility bugs, and almost never what makes a product distinctive.
Who should own the design system?
A named person, not a committee, and usually not a separate team until the organisation is large. What matters more than the title is that additions get reviewed quickly and a product engineer can contribute a new variant in about a day. If contributing is slower than working around the system, people will work around it.
SYS — Keep reading
How we pick the right foundation for your product
Frameworks change less than you'd think. What matters is picking tools your team can still run in three years — here's how we decide.
8 min read
Choosing the right backend for a new SaaS build
How we decide what a SaaS product actually needs before committing to an architecture — and which decisions are genuinely expensive to reverse.
7 min read
Building an internal dashboard people actually use
Most internal dashboards get built, demoed, and quietly abandoned. What separates the ones teams open every morning from the ones nobody misses.
7 min read
