In this article
- What a design system is, and what it isn’t
- How much system you need at each stage
- Decide first: adopt, adapt, build or repair
- Scope the product before you scope the system
- Inventory what already exists, in design and in code
- Fix broken UX before you standardise it
- Lay the foundations as tokens
- Tokens in practice: themes, dark mode and more than one brand
- Build the repeated primitives first
- Prove the system on real screens
- Make design and code the same system
- Document decisions, not just parts
- Who builds and runs a design system
- Govern without turning the system into a bottleneck
- Moving a live product onto the system
- How to tell whether it’s working
- Fusion: the component library in a real product
- Examine the components, then scope the system
Your team should not spend every sprint debating which button, modal or error state is the real one. Those inconsistencies multiply handoff questions, interface bugs and rework as the product grows. Buying a bigger UI kit simply gives everyone more conflicting parts to choose from.
ANODA connects the system to the workflows your business needs to ship: we identify duplicated decisions, repair broken patterns and define reusable foundations and states that designers and engineers can carry into the next release. You get a product that feels coherent and a team that can extend it without starting over.
A design system connects reusable foundations, components and patterns with the guidance and ownership that keep a product consistent as it grows. Build its first scope around real workflows, use it on real screens, and plan how design and engineering will maintain it.
What a design system is, and what it isn’t
The simplest way to understand a design system is as a language. Tokens are the alphabet. Components are words. Patterns are sentences. The guidelines are the grammar. And like any language, it only works if the people using it agree on the meaning and actually speak it, in design and in code.
A useful design system usually includes:
- Foundations. The basic decisions everything else is made of: colour, typography, spacing, sizing, corner radius, elevation and shadows, motion, iconography, grid and layout. These are usually stored as design tokens, named values that design tools and code can both use.
- Components. Reusable interface building blocks: buttons, inputs, selects, checkboxes, tables, modals, toasts, tabs. Each has defined variants, sizes, states and behaviour.
- Patterns. Proven ways of combining components to solve a recurring problem: a form with validation, an empty state, a filter bar, a confirmation step, onboarding, error recovery.
- Content guidelines. How the product talks: voice, tone, terminology, how to write labels, buttons and error messages.
- Accessibility rules. Contrast, focus, keyboard behaviour, screen-reader labels, target sizes, motion preferences, built into the components rather than bolted on.
- Documentation. Where to find all of this, when to use what, and what not to do.
- Code. The implemented components, which is where the system becomes real for users.
- Governance. Who owns the system, how changes are proposed and approved, how versions are released and old parts retired.

Notice what is missing from that list: size. A design system is not defined by how many components it has. A small product can have a perfectly good design system with a dozen components and a clear set of tokens. A large one can have hundreds of components and still not be a system, because nobody agrees on which to use, and the code does something else.
Design system, UI kit, style guide, pattern library
These terms get mixed up constantly, which is part of why teams buy the wrong thing.
- A style guide describes the visual brand: logo, colours, typefaces, imagery, tone. It tells you what the brand looks like. It doesn’t tell you how a date picker behaves.
- A UI kit is a collection of interface components in a design tool. Useful for drawing screens quickly. On its own, it has no code, no rules and no process for change.
- A component library is a set of implemented components in code. It is where the interface actually runs.
- A pattern library documents how components combine to solve common problems.
- A design system connects all of these with shared foundations, documentation and governance, so design and code describe the same thing and change together.
If what you have is a UI kit in a design file and a separate, different set of components in code, you don’t have a design system. You have two dialects of the same language, drifting further apart with every release.
How much system you need at each stage
The right size of design system changes as a product grows. Trying to jump straight to the end is how teams end up with a library bigger than their product.
Before and around launch. Keep it minimal. A small set of tokens, a mature component library as the base, the handful of components your first screens need, and a short list of rules. The priority is shipping and learning, and the system’s job is to stop the interface drifting while you do it.
After launch, while growing. This is when a system starts to pay for itself. More screens, more features, perhaps more designers and developers. Consolidate what has diverged, add the patterns you now meet repeatedly, connect the design library to code properly, and name an owner.
At scale, across products or teams. Now a larger system, with dedicated people, versioning, a contribution process and thorough documentation, is justified. The cost of inconsistency across several teams is higher than the cost of running the system.
At each stage, the test is the same: does the system make the next feature faster and the product more consistent, today? If it mostly produces work for itself, it is too big for where you are.
Decide first: adopt, adapt, build or repair
Not every product needs a custom design system. Plenty of products pay for one they never needed.
Think of it as buying transport. Adopting an existing foundation — Material, a headless component library, a well-maintained open-source kit — is buying a reliable car. Adapting one is the same car with your paint, a roof rack and a tow bar. Building custom is designing a car from scratch, which makes sense for a racing team and very little sense for a trip to the shops. Repairing is admitting you already own a car. It just has four different tyres.

A small product with one platform, one team and no unusual interactions should almost always adopt or adapt. Reinventing the wheel is a lovely hobby. As a line item, it is a quarter of engineering salaries spent on a date picker that already exists, works and is tested by people who do nothing else. Spend that money on the screens that earn it.
Custom starts to pay its way when several products or platforms must feel like one, when your core interactions exist in no library — dense trading tables, clinical workflows, specialist editors — or when the brand has to be recognisable in the interface itself. Even then, “custom” usually means your own tokens and patterns on top of accessible primitives somebody else already hardened.
Repair is the right answer more often than anyone likes to admit. The product already has a system. It has simply drifted. You don’t need a new one. You need to find out what the old one turned into.

Scope the product before you scope the system
Start with what the product does now and what it will credibly do in the next two or three releases. Not the vision deck. The roadmap you would bet your own money on.
List the core flows — sign-up, the main job, billing, settings, whatever pays the bills — and the platforms they run on. That list is the boundary of the first release. A component no current or near-term flow needs doesn’t get built yet. Designing a carousel “because we might need one” is biting off more than you can chew, then paying someone to maintain what you bit off.
Scoping is also where you decide who is in the room. A system built by design alone becomes a poster. One built by engineering alone becomes a component library with no opinions. The scope conversation needs a designer, a front-end lead and whoever owns the roadmap, together, from day one.
Inventory what already exists, in design and in code
Before anyone draws a new component, count the old ones. Capture every key screen, open the design files and — the step everybody skips — search the codebase. The design file tells you what someone intended. The code tells you what users get.
It’s like moving house. You have no idea you own four can openers until you empty every drawer.

Sort what you find into three piles: duplicates to merge, gaps to fill, and inconsistent states — the loading, empty, error and disabled versions nobody designed on purpose. Each duplicate is a small tax. Together they are death by a thousand cuts: every new feature opens with a debate about which of the five modals is the real one, and every debate is billable hours.

The inventory ends in one screen redrawn with a single set of decisions. It is the first proof that the system will make the product calmer, not just the file tidier.

Fix broken UX before you standardise it
Here is the trap. The inventory shows a pattern used on forty screens, so the team crowns it the official component. Nobody checks whether the pattern works.
Standardising unresolved UX is putting a cast on a broken arm before anyone sets the bone. It heals. Crooked. Permanently, and now on every screen. A dialog that says “Are you sure? Cancel / OK” becomes the system’s official way to lose a customer’s data, complete with documentation and a version number.

So before a pattern becomes a component, test it against its hardest real case: the long name, the destructive action, the error, the empty account, the person on a phone with one free thumb. If it fails, fix the UX first and standardise the fix. If nobody can say what happens after the user clicks, that is a product question, and no component will answer it for you.

Lay the foundations as tokens
Foundations are the decisions everything else is made of: colour, typography, spacing, radius, elevation, motion, breakpoints. Tokens are those decisions with names, stored once and read by both the design tool and the code.
Hard-coded values are prices written on every tin with a marker. Change the price and someone walks the aisles with a pen for a week and still misses half a shelf. Tokens are the barcode: change it once at the till and every tin is right.
Tokens work best in layers. Primitive tokens hold raw values: a specific blue, a 16-pixel step. Semantic tokens say what a value is for: the colour of a primary action, the text of an error. Component tokens, where you need them, bind those meanings to specific parts. Rebrand, add dark mode or ship a white-label version, and you change the mapping instead of hunting through the codebase.


Don’t overdo it. A token for every value is painting yourself into a corner: nobody can change anything without renaming half the file. Name the decisions the product actually makes. Add more when a real screen needs them.
Tokens in practice: themes, dark mode and more than one brand
The layered token structure pays off most when the product needs more than one look.
Dark mode is the classic example. If components use semantic tokens like “surface.default” and “text.default”, dark mode is mostly a second set of values for those tokens. If components use raw colours, dark mode becomes a hunt through every component for every hard-coded white, and something always gets missed: a white card on a dark background, invisible text, a border that disappears. We have found more dark-mode bugs caused by hard-coded values than by any design decision.
A few rules make themes work:
- Components never use primitive tokens directly. They use semantic or component tokens, so the theme can change the meaning without touching the component.
- Every semantic token has a value in every theme, even if it is the same value.
- Contrast is checked in every theme, not just the default one. Dark themes fail contrast in different places from light ones.
- Images, illustrations and shadows are considered too. A shadow that works on white can vanish on dark grey; an illustration with a white background becomes a glowing rectangle.
More than one brand follows the same logic. A company with several products, or a platform that white-labels its product for clients, can share components and patterns while each brand supplies its own set of token values. The button is the same component. Its colour, radius and type come from the brand’s tokens. That is far cheaper than maintaining a separate component library for each brand, and it keeps behaviour and accessibility identical everywhere.
Density is a quieter case. Data-heavy products often need a compact mode for expert users and a comfortable one for occasional users. Spacing and sizing tokens make that a theme, not a rebuild.
The lesson in all three is the same: decide early which things are allowed to vary, give them tokens, and keep everything else fixed.
Build the repeated primitives first
With foundations in place, build in the order of how often something appears and how much it costs when it’s inconsistent. Buttons, inputs, selects, checkboxes, links, type styles, icons, basic layout: the parts on almost every screen. Then the patterns your product lives on: tables, forms, modals, navigation, notifications, empty and error states.
You teach a puppy to sit before you teach it to fetch the newspaper. The rare, shiny component — the 3D chart, the onboarding carousel — waits until the boring ones hold up under real load.

Each primitive ships with its states designed on purpose: default, hover, focus, pressed, disabled, loading, error. A first release that nails ten common parts beats one that sketches ninety. Ninety sketches is a mood board with a changelog.
Design systems
Custom build, adaptation or a repair job? Find out before you fund one.
We go through your screens, design files and existing code, show where the duplicates and broken patterns are, and scope the smallest system release your team can actually use.
Prove the system on real screens
Components that look perfect on their own page are ingredients tasted one at a time. The flour is fine. The eggs are fine. You still don’t know whether it’s a cake.
Pick a handful of representative screens — the busiest table, the longest form, the most important flow on mobile — and rebuild them only from system parts, with real data. Real client names are long. Real amounts have six figures. Real statuses say “Partially paid · overdue”, not “Active”. This is where the table row that looked elegant with “Acme” falls apart.

Check responsive behaviour at the widths people actually use, not just the three breakpoints in the file. Then check accessibility at two levels, because they are not the same thing.
Primitives can be built to meet criteria from WCAG 2.2, the W3C Recommendation — for example, a 4.5:1 minimum contrast for normal text and pointer targets of at least 24 by 24 CSS pixels or the spacing and other exceptions defined in WCAG 2.2. Automated checks help detect some failures; task walkthroughs check the interaction. That gives you accessible parts. It does not give you an accessible product. A fire door is rated to hold back a fire; wedge it open with a chair and the rating is decoration. Focus order, error announcements, keyboard traps inside a modal, a flow that makes sense to a screen reader: those surface only when someone tries to finish a real task.


Make design and code the same system
A system that exists twice — once in the design library, once in code — is keeping two sets of books. They match on the day you publish. Six months later the design button has an 8-pixel radius, the production one has 6, and every handoff opens with an argument about which book is true.


Designers and developers have to work together at four moments at minimum: when tokens are named, when a component’s API and states are defined, when representative screens are validated, and when anything is changed or deprecated. Between those moments they can work in parallel. At those moments, working apart is how you get two systems with one name.
The goal is one source of truth per decision: tokens generated from one place, coded components that match the design library property for property, and a visible status on each — in design, in code, stable, deprecated — so nobody builds a feature on something that exists only as a drawing. That feature gets rebuilt later, and you pay for it twice.
Document decisions, not just parts
Documentation that lists the parts but never says when to use them is a script with all the lines and no stage directions. Everyone knows what to say. Nobody knows when to walk on. So people grab the nearest part, and a modal turns up where a toast belonged.
Good documentation is short and opinionated. For each component: when to use it, when not to, which variants exist and why, content rules — how to word the button, how long an error can be — accessibility behaviour, the code reference and its current status. Show one right example and one wrong one. Keep it next to the code, so it changes when the code does.

Who builds and runs a design system
A design system is a product with its own users: the designers and developers who build with it. It needs people who treat it that way.
In a small team, that might be one designer and one front-end developer who spend part of their time on the system and the rest on features. That is often the healthiest setup, because the people maintaining the system are also its users and feel every gap immediately.
As the organisation grows, the roles become clearer:
- A system designer who owns the foundations, components and patterns in the design library.
- A system engineer who owns the implemented components, the token pipeline and the component workshop.
- A content designer or writer who owns the content guidelines, at least part-time.
- An accessibility specialist, internal or external, who checks the system rather than each feature.
- Contributors from product teams, who propose new components and patterns based on real features.
What doesn’t work is a design system with no engineering involvement, or one owned by a team so separate from the product that it builds what it finds interesting rather than what product teams need. The fastest way to kill adoption is a system team that never ships features.
Govern without turning the system into a bottleneck
Design systems die in two ways. With no rules, every team adds its own version and you are back to the inventory you started with. With too many rules, every new need waits weeks for a committee, so teams quietly build around the system and you get the duplication anyway, plus resentment.
It’s refereeing. A referee who whistles every touch kills the game. No referee, and it’s a brawl by half-time. Governance is deciding which fouls matter.
The practical version fits on one page:
- Contribution. Anyone can propose a component or a change. The first question is always whether something existing already does the job, or could with a variant.
- Exceptions. A team can ship a one-off when a real flow needs it, as long as it is logged and reviewed on a date. Exceptions that keep coming back are the plan for the next release.
- Versioning. Releases carry version numbers and release notes, so product teams upgrade on purpose instead of waking up to a different button.
- Deprecation. Old components get a replacement, a date and a migration note before they disappear. Removing things is part of the job, not a failure of it.
- Ownership. A named person or team owns the system, with real time in their week for it. Everybody talks about the design system, but nobody does anything about it — until somebody’s job description says so.

It is still herding cats. Governance just makes sure the cats are heading roughly the same way.
Moving a live product onto the system
For a product that already exists, the hardest part is not building the system. It is moving the product onto it without stopping feature work.
Big-bang migrations, where the whole interface is rebuilt at once, rarely go well. They freeze delivery, surprise users with a completely different product overnight, and usually run out of budget before they are finished. A gradual approach is safer:
- New work uses the system from day one. Every new feature and every redesigned screen is built with system components.
- High-traffic screens move first, because that is where consistency and quality improvements reach the most users.
- Replace duplicates as you touch them. When a team works on a screen for any reason, it swaps old components for system ones in the same change.
- Track what’s left. Keep a simple list of screens and old components still to migrate, and review it regularly.
- Retire old components on a schedule, with a replacement and a date, so the old versions don’t live forever.
This takes longer than a single rebuild on paper. In practice it finishes more often, because the product keeps moving while the system spreads through it.
How to tell whether it’s working
A design system is an investment, so it should be measured like one. The useful signals are about the product, not the library:
- Adoption: how much of the product’s interface actually uses system components, and how often designers detach or override them.
- Speed: whether new screens and features take less design and development time than before.
- Consistency: whether the number of duplicate components and one-off styles is falling.
- Quality: whether interface bugs and accessibility issues are going down.
- Onboarding: how quickly new designers and developers become productive.
Pick a few, measure them before and after, and look at them honestly. If adoption is low, the system probably doesn’t fit what teams need, or it is too hard to use. That is a signal to fix the system, not to write a stricter rule.
Fusion: the component library in a real product
In our Fusion dating-app design, the same reaction buttons appear in the UI kit and on the discovery card. The kit defines button sizes and default, focused, pressed and disabled states; the handoff includes the component library and screen map. A new matching mode can use the existing components instead of starting a separate visual language.
That is the practical connection between a library and a product: document the repeated decision, use it on real screens, and hand over the states engineering needs. Our design systems service covers the inventory, foundations, components and adoption plan; a coded component library can be scoped alongside frontend development.
Examine the components, then scope the system
For variants, states, content rules and design-to-code mapping, read our practical guide to design system components. Stop paying to solve the same interface decisions in every sprint. Scope your design system with ANODA and turn the components your team uses into a coherent product foundation.