Design, UI, UX, Insights
How to Build Design Systems that Scale with Your Team
The pocket guide to how to build design systems for agencies and growing teams. We cover tokens, Figma components, libraries, handoff workflows, governance, and common mistakes.
When your team grows, design rarely breaks all at once and instead, you start noticing small inconsistencies. You’ll see buttons that feel “almost” the same but aren’t or new features that take longer because you keep double-checking decisions you’ve already made before.
At first, these issues feel manageable, but over time, they slow everything down, and you gradually cross the line between design debt and system thinking.
When you’re dealing with design debt, you solve problems one screen at a time, such as tweaking values and relying on what feels right in the moment. When you shift to system thinking, however, you stop making isolated decisions and start relying on shared rules. This is why I wrote this guide to explain the basics of how you can build that system step by step, with examples for real teams.
What does a design system include?
Before we start, let’s not confuse design systems, UI kits, and style guides. These do overlap, but they serve very different purposes.
Design system vs. UI kit vs. style guide
The style guide defines visual rules ( What does this brand look like?) and you use it to answer questions like:
- What colors can you use?
- Which fonts are allowed?
- How should the logo appear?
Your UI kit gives you ready-made components and screens (What can you place on a page right now?), so you use it when you want to quickly assemble layouts using prebuilt pieces.
And, finally, the design system connects rules, components, and usage logic into a single source of truth. It explains what exists, when and why you should use it.
It answers the question of how does our product stay consistent as the team grows?
If you’re running a small SaaS product with three designers and a handful of developers, for example, a UI kit might be enough at first. But as soon as multiple teams start shipping features in parallel, you will need a design system to keep everyone aligned.
The core parts of a design system (the short version)
Every working design system relies on the same four building blocks at a practical level:
- Tokens (raw values like colors, spacing, font sizes, etc.)
- Components (reusable UI parts such as buttons, inputs, cards, etc.)
- Patterns (common layout or interaction solutions)
- Documentation (rules and examples that explain how everything should be used)
And each of those parts solves a specific problem:
- Tokens prevent visual drift by locking decisions into named values
- Components save time because they eliminate repeated work
- Patterns reduce decision fatigue as they standard solutions
- Documentation eliminates misunderstandings
Basically. this is what a design system looks like for a smal Saas team:
- One shared Figma library
- Design tokens mapped directly to code variables
- Core components that cover everyday UI work
- Short usage notes explaining when and why to use each component
As you can see, your system should support current work, not imaginary scenarios such as some edge cases for hypothetical features, or future-proofing for ideas that don’t exist yet.
What are design tokens?
These are one of the most practical tools you can introduce, because each represents a decision.
For example, instead of choosing “blue #0055FF”, you choose something like primary action color that becomes reusable across screens, and future updates.
When you decide to change any brand color, you won’t need to do so through dozens of files, but you only update the token once, and the change flows everywhere.
Most teams can cover 90% of their UI work with a small set of tokens:
- Colors for brand, text, background, feedback states
- Typography for font family, size, weight, line height
- Spacing for padding, margins, layout gaps
- Radius and elevation for corner rounding and surface depth
How do tokens connect design and code?
In Figma, a color token connects to a style (hex value). In code, that same token maps to a CSS variable.
As a designer, you apply primary-500. Your develoiper, on the other hand, references --color-primary-500. Both of you are pointing to the same decision, just in different tools.
How to structure your token for scale?
Token chaos shows up faster than most teams expect. You start with a few color styles, add spacing, then suddenly no one knows which token to use anymore. This is why you need to set up early rules.
Global vs semantic tokens
When you structure tokens for scale, you’re really separating values from meaning.
Global tokens store raw values. These are things like blue-500, space-16, or font-size-14, that hold numbers.
Semantic tokens, however, describe purpose. For example, instead of referencing a color directly, you use names like background-surface, text-primary, etc.
This is very important to know! When you build components, you always reference semantic tokens, not global ones.
Here’s an example. If your primary background color changes from blue to green, you need to update the semantic token once. Every component using background-primary updates automatically. If components referenced blue-500 directly, you’d be touching each one individually.
Naming logic
Token names should read like intent, so when you look at a token and immediately understand why it exists, the name is doing its job. button-background-primary tells you exactly where and how it’s used. blue-500 does not.
This matters most when you revisit the system months later, a new designer joins the team or when your developers search for the right variable in code.
A common, scalable structure looks like this:
Global colors: Color / Blue / 500
Semantic tokens: Color / Text / Primary or Color / Background / Surface
So when you apply a color to a button label, you’re choosing text-on-primary, not blue-500. The component stays stable even if the brand evolves.
When does token depth start to hurt?
If you notice designers hesitating because they’re unsure which token path to pick, your structure has gone too far. You can simplify it easily, though, just flatten paths, merge rarely used tokens, and focus on what’s actually used in production.
What are reusable Figma components?
Components sit at the center of your design system so you can assemble consistent screens quickly.
Every reusable component earns its place by repetition.
For example, if you’ve drawn the same UI element three times, this element qualifies to become reusable. Such elements are usually buttons, inputs, dropdowns, alerts, and badges, because they show up everywhere.
If something only appears once or depends heavily on a specific layout (a custom pricing table designed for a single landing page), it’s not worth turning it into a component, because this only adds maintenance without giving you real benefit.
Strong components share a predictable internal structure:
- Base (the default layout and styling)
- Variants (visual differences like type or emphasis)
- Properties (toggles for things like icons, states, or labels)
This keeps everything inside a single component instead of spawning near-duplicates. You need to edit once, and every instance will stay in sync.
For example, a practical button component usually has these:
- Variants (primary and secondary)
- Sizes (small, medium, large)
- States (default, hover, disabled, loading)
When you have that, and you need to design a new screen, you don’t have to redraw buttons, only switch properties. Then, the developers can build the same button in code, just by mirroring those exact options.
Be careful not to overbuild!
The most common mistake is adding options too early. For example, five button styles sound useful until no one in your tean remembers when to use each one.
It would be much better to just start with what the product genuinely needs today. Then, if you see real repetition across multiple features or teams, you can add a new variant. In short, let usage justify complexity, not the other way around.
Component libraries across projects
Once you start working on more than one product or client, how you structure your libraries matters equally as much as how well you’ve built your components.
Single library vs. shared core library
If you’re working on a single product, one library is usually enough. Respectively, if you support multiple products or multiple clients, you will need a share core library, that holds your design tokens, base components and foundational patterns.
This way, each product or client then gets their own project-level library that adds only what’s different (brand colors, layout variations, etc.), and you can fix bugs and improve components once, so you won’t need to edit every project individually.
Reuse without Copy-Paste
When you paste a component instead of linking it to a library, that copy stops receiving updates. Inevitably, over time, small differences can appear and you may end up with variations of the same button with slightly different padding each, different hover states and basically confusion about which button is the correct one.
Shared libraries keep fixes centralized!
In this case, you only have to update your component in one place, publish the change, and every connected project will benefit the update.
For example, if you’re handling several SaaS clients, you will maintain one core library with spacing tokens, typography tokens, and core components like buttons, inputs, and modals.
Then, each client gets a lightweight library that overrides only color and font tokens.
Buttons, forms, and modals will remain structurally identical across clients. This way the brand will still feel unique because the tokens change, but the system underneath stays the same and you don’t have to redesign the same components over and over.
Documentation
Good documentation answers questions quickly, then gets out of the way. When someone opens a doc page, they’re usually asking when should they use a component, when not, and also, what breaks if they bend the rules.
And that’s all you need to document. Also, stick to short text blocks, and visual examples (and maybe a few edge cases) that cover most real-world needs.
Anything else that requires deep explanation, belongs in code comments, or internal notes.
Let’s say you document a form field component.
Explain where do labels go, how do errors appear and how spacing behaves in different contexts.
From there on, every product will reference that page.
Handoff between design and development
Tokens become the shared language.
You define values once in design. Developers reference the same logic through variables. Components rely on tokens instead of hard-coded numbers.
This creates a clean flow:
Design defines decisions > Code consumes those decisions >Components stay consistent across screens and platforms
Figma, Storybook, and Code Alignment
Figma holds the source of truth for visual intent and storybook shows how components actually behave in code.
The alignment happens when both tools rely on the same token names, component variants and state logic. This way designers will see real output instead of mock behavior, and developers will trust the design specs because they match what’s already in code.
When things are working well, the design shares a component update and the code already understands it. For example, let’s say your spacing tokens include space-8 and space-16.
In Figma, you select those values when setting padding or layout gaps. In code, developers apply the same tokens as CSS variables.
Then, anytime spacing rules change, you can update the token and the pages will stay consistent across features and future updates.
Who owns what?
Design systems need ownership, but there’s a specific balance you need to consider so it works properly. You’re aiming for enough structure to keep things stable, but not so much that teams stop using the system.
Ownership models for small and mid-size teams
If you’re on a small team, you typically have:
One design owner responsible for structure and consistency
One development owner responsible for implementation and code alignment
When your teams grows, this model starts to strain and you’ll do better with a small group, usually designers and developers, who review system changes on a regular cadence.
Here, everyone should know:
- Who can approve changes
- Where decisions get documented
- How to propose updates
- How do changes get reviewed
You need quick, documented decisions.
A typical review includes:
- Why is the change needed?
- Which tokens or components does it affect?
- What impact does it have on existing work?
That’s it.
What happens when everyone edits everything?
When anyone can edit anything, you will sooner or later start noticing components changing without notice or tokens shifts meaning, or other issues to the point you stop trusting the system and start working around it.
This is why governance should include the following three in order to stay healthy:
- Clear owners for tokens and components
- Visible change logs so teams can track updates
- Limited edit access with open contribution paths
FAQ about design systems
What does a minimum viable design system look like?
If you’re just starting, your system should stay small with a minimum setup, that usually includes core tokens (color, spacing, typography), a few essential components, and short usage notes. Note that buttons, inputs, spacing, and text styles cover most product work, so anything beyond will often slow your progress instead of speeding it up.
When does a system need to grow?
A system should grow in response to pain signals. For example, if you notice that your designers overriding styles frequently or the developers patch UI inconsistencies after release, you need the repetition before it starts costing you time or introduce bugs.
How many components are enough?
“Enough” means your most common screens reuse the same parts. Dashboards, forms, and navigation should all pull from shared components. If new screens constantly rely on custom UI, your system has gaps that need filling.
Should every edge case live in the system?
Absolutely not. Your design system exists to support patterns that appear often. Rare layouts or one-off flows should stay local to the feature.
Can a design system be too small?
Yes, but only when inconsistency starts slowing you down. If design reviews focus on visual mismatches instead of product logic, your system probably lacks depth and you need to expand it.
When does simplicity beat completeness?
Simplicity is best when your team need to move fast. Clear tokens and flexible components always beat massive libraries that few people understand. You’ll know you’ve hit the right balance when your system gets used daily without issues, the design decisions happen quickly and when the code output is predictable.
What are the common mistakes you can make?
Most design system problems come from building the right things at the wrong time or optimizing for polish instead of usefulness.
[Mistake No.1] You start with visual instead of rules
Visual polish feels productive early on and you will often see quick wins. The problem is that without underlying rules, that polish cracks almost immediately.
If you haven’t defined tokens, naming logic, and usage intent, every visual decision becomes a one-off. It gets even worse when your product grows, because those early choices don’t scale and you end up repainting instead of building.
Start with rules first, because visuals become easier to adjust later.
[Mistake No.2] You create components before token logic
It’s tempting to jump straight into components (and, personally, I’m very very guilty of it). Unfortunately, when your components rely on raw values like hard-coded colors, spacing, or font sizes, you will lock yourself into future refactors and later every visual change becomes a component rewrite.
If you define token logic first, your components will be stable. This way you can change the token, instead of the entire structure.
[Mistake No.3] You treat the system as a one-time task
One of the most common beginner mistakes is to treat your design system as a project and move on. Instead, it should always reflect the current state of your product, so when the product changes it will change with it too.
Healthy systems get small, regular updates that match real product shifts to stay relevant.
[Mistake No.4] You copy systems from large companies
Large companies design their systems to solve large-scale problems, so they include layers for localization, accessibility at scale, platform parity, and governance across dozens of teams. Small and mid sized companies don’t need that complexity, so if you copy these systems you’ll only add weight without value.
A smaller system made specifically for your team will always be better than one of those first class systems that no one fully understands.
And there you have it!
Your goal is to build something that your team relies on every day. When you start creating your design system, start with clear token definitions, consistent naming logic, and a small set of core components to create a foundation that supports most real product work. This way, your designers and developers can move faster without constantly revisiting past decisions.
You can safely delay rare patterns, highly specialized variants, or deep documentation for edge cases.
Before you go, don’t forget to check out our other awesome UI/UX design articles! We’ve got loads of tips and inspiration to help you create awesome designs.