How to build a design system
July 16, 2025
What problem are we trying to solve?
Imagine a mid-size company with 200+ employees, 10+ different teams, and 5+ different technologies, including web and mobile applications. Each environment has its own legacy and practices in terms of style implementation. Each team can work in any environment depending on the project. There is a dedicated designer for each team. This organization allows each team to focus on a specific mission rather than a specific technology but it makes it difficult for engineers to adapt to each different environment's legacy code and best practices.
The consequences, in terms of styling, are:
Unmaintainable styles with hardcoded values
Redundant code – engineers avoid reusing components or values for fear of breaking other parts of the application
Inconsistent design and components across platforms
In three words: tech debt increases.
The root cause is the lack of a shared, authoritative source of truth for styling.
Each environment has solved styling in its own siloed way. There’s no global strategy. No unified vision.
Stage 0: The Variables
CSS and associated frameworks have gone a long way. They offer a lot of flexibility and power. How many engineers have had a deep feeling of accomplishment when replacing hard-coded values with CSS variables? It feels good, it looks better, and you can now change a value everywhere with one change. But very quickly, new variables are added, engineers are reluctant to change existing variables' values because it's beyond the scope of their task and they are unsure of the consequences. Variables' power will cause their downfall. They will multiply and become unmanageable.
These variables only exist in code; their names are very often the arbitrary creation of one engineer. In most cases, you will see some variations appear: blue1 will follow blue, and primary-light will follow primary. Watch them grow into primary-lighter or blue1-darker.
The problem is that these variables are not shared. They are not part of a design system. They are not part of a shared vocabulary. They are not part of a shared understanding. They are not part of a shared culture. They are not part of a shared language.
The problem is that these variables are not shared. They are not part of a design system. They are not part of a shared vocabulary. They are not part of a shared understanding.
Stage 1: The Guidelines
This is usually the first attempt at solving the chaos. Courageous engineers comb through codebases and documentation in an effort to define cross-environment styling guidelines. They consult with engineering leads and code owners to understand existing patterns and challenges. They come accross the many variables and try to establish naming conventions.
They write documentation. But the reality is, guidelines aren’t enough. They help standardize practices within a team or repository—but they do not prevent divergence across environments.
In the absence of a Design System, guidelines are often too vague to be useful or too detailed to be followed.
At this point, engineers begin to realize the scope of the problem. It’s not just technical—it’s organizational. Solving this problem seems like a herculean task that cannot be owned by engineering alone.
Stage 2: A holistic approach
We need to understand the problem from a holistic perspective. We won't be able to systematize styling if we don't understand the styles life cycle:
How it is created
How it travels from designers to engineers
How it is used in production
Designers are producers, they produce styled UI elements. Understanding their tools, feedback cycles, and creative expectations is critical if we want to systematize styling implementation.
Designers will be consumers and co-owners of the system, therefore it cannot be built without them.
Stage 3: Building the Styling Dictionary
The first meaningful step is creating a styling dictionary: a shared, structured collection of design values expressed as tokens. This is a collaborative effort between design and engineering. Together, we define:
Base tokens: raw values like colors, spacing, font sizes (#000, 8px, 1.5rem)
Semantic tokens: named purpose-driven values like primary-text, surface-background, action-hover
Component tokens: scoped tokens like card-padding, button-radius, form-border
The naming system is inspired by utility-first frameworks like Tailwind—predictable, human-readable, and scalable.
But here’s the balance you must strike:
Designers need enough expressive vocabulary to stay creative
The system must stay opinionated and systematic—if everything is allowed, it’s not a system
If everything is allowed, it’s not really a system anymore, is it?
It's not just about building tooling for developers - it's about formalizing how designers express intent.
Stage 4: Aligning Workflows
A dictionary alone won’t solve anything if teams don’t use it. The next step is aligning workflows:
How do designers use these tokens in Figma or Sketch?
How are these values surfaced to engineers?
How are updates proposed and approved?
How do tokens move from idea → prototype → production?
Expose the design system in ways that are native to both disciplines: Designers see tokens in Figma plugins or tools like Supernova, Engineers consume them through theme files, constants, or utility classes.
Stage 5: Implementation Across Platforms
You don’t need to build a full platform to get started. In fact, you shouldn’t. Start with the simplest, most portable format: a structured JSON file.
This JSON object becomes the source of truth for tokens. Any platform—web, native, server-rendered—can consume it.
Every team has access to consistent values
The system is immediately useful in any environment
You can evolve tooling around it without breaking things
Stage 6: Scaling the Outputs
Once the JSON-based dictionary is working and trusted, you can expand:
Generate a Tailwind config from the dictionary
Export MUI themes mapped to token categories
Generate native token objects for iOS or Android
Build a central icon registry as part of the system
This isn’t about adding complexity—it’s about scaling one coherent system across multiple platforms.
Stage 7: Adoption Through Enablement
If you want this system to be adopted, there’s only one strategy that works: Make it easier than not using it.
Run workshops
Pair with engineers
Demo how quickly you can build consistent UIs using the dictionary
Let designers see how their naming gets used 1:1 in production
Once people realize it reduces friction, they’ll adopt it on their own. The system succeeds because it helps them do their job better.
Stage 8: Evolving with Change
Designers iterate. They change their mind. A lot. And that’s a feature, not a bug. The system must accommodate this reality:
Updating tokens should be collaborative and traceable
The source of truth must allow flexibility with structure
Tools like Supernova or Specify can enable designers to edit token values without touching code
Stage 9: Final Thoughts & What Comes Next
You've moved beyond fragmented styling and outdated documentation. You've created a shared design vocabulary, aligned workflows across disciplines, and introduced a system that scales across technologies. But building the system is only part of the journey.
Now comes the real test: proving it works. A system only justifies its existence if it brings tangible value—consistency, scalability, and increased productivity. The next step is to track adoption, measure impact, and surface wins.
In the next chapter, we’ll explore how to demonstrate the system’s effectiveness. What KPIs can you use? How do you measure consistency? How can you prove that what you’ve built makes your organization faster, more efficient, and more cohesive?
