Introduction
When people talk about design systems, it can sound like you need to build this massive, polished library with hundreds of components before you can even call it a system. The truth is, the best systems usually start small and grow over time. The magic is in setting a foundation that’s flexible, not perfect.
Whenever I start a design system in Figma, I begin with the basics: the foundations. Think of these as the soil your system grows from, things like color, typography, spacing, and grids. Without them, you’re just arranging elements without consistency, and every new project ends up reinventing the wheel.
Color Palette
Usually, the first building block I focus on is the Color variables. In Figma, variables and styles play a key role in creating a design system that’s both consistent and scalable. These are often grouped into two main categories:
Primitives
Primitives are the fundamental building blocks of a design system things like color, spacing, and sizing. They form the foundation, but they typically aren’t applied directly to components or layouts.
Semantic
Semantic variables provide context for how a value should be used. For example, a variable such as color-background-warning immediately communicates its intended purpose by suggesting urgency or caution.
When working with color, I like to begin with a base palette that reflects the brand. I create evenly stepped tones from light to dark, including a few tints and shades, plus some supporting hues. Tools like Supa Palette (💸) make this much easier, but there are great free alternatives such as Maketintsandshades and Colorfont Shade Generator, which conveniently preview colors in UI examples.
My process usually starts with establishing Common colors, white, black, and transparent before moving on to Primary (50–900) and Secondary (50–900) scales. The number of steps can vary: some systems use 10 increments (50–900), while others prefer 12 (25–950). From there, I define the feedback or state colors: Info, Error, Warning, and Success. Finally, I work on Neutrals, often adding a few extra shades to ensure better flexibility and contrast in the future.
Before moving into semantic variables, I adjust the scope of the primitive variables to prevent them from being used accidentally in designs. These colors should only be referenced through the Semantic collection.
Once that’s set, it’s time to create the Semantic layer. Within Figma Variables, I set up a new collection I normally called it Theme and within I create two main groups, one for Semanthic and other for Components and offocuse I don't foorguet to add two columns: one for the Light Theme and another for the Dark Theme. From there, theming almost becomes effortless. In Figma I’ll add there remaining semanthing variables, I map each primitive color to a semantic counterpart, keeping the same structure and naming, then I create the common colors such as Background, Text, Border and Overlay. Each one of them I like to have at least 5 levels of colors starting with lightest, lighter, main, darker, darkest. The key step is to carefully invert the values for the dark theme and verify contrast in both themes as you go.
Figma Variables Collections
When I toggle between modes, the whole design updates instantly. That’s the moment when we realize how much time a system can save you.
In summary each Semantic color gets mapped back to the primary palette, and I keep them organized in a collection. So if the brand decides tomorrow that our “Primary” should shift from blue to purple, I don’t have to rebuild anything. I change the primary values, and the whole system follows. That's what makes Figma is variables so powerfull.
Typography is one of the pillars of a strong design system. When done well, it enhances hierarchy, clarity, and consistency across platforms. But typography also needs to be responsive The same concept that I used on colors we can apply to Typography and Spacing. This way the UI should scale gracefully from desktop to tablet to mobile without manually adjusting font sizes for every breakpoint.
I normally create a Collection, lets called Responsive Modes. Within this collection I then create the 3 columns each one corresponding to a screen size: Desktop, Tablet & Mobile.
From there I start adding values for each category. Here is an example:
| Responsive Modes | Desktop | Tablet | Mobile |
|---|---|---|---|
| ▽ Typography | |||
| ▽ Size | |||
| ▽ Headings | |||
| ↳ H1 | 48 | 36 | 36 |
| ↳ H2 | 36 | 32 | 32 |
| ↳ H3 | 32 | 30 | 30 |
| ... | ... | ... | ... |
There a few plugins or websites that may help you defining the typography scaling. Here are some that I like to use.
Responsive Spacing
Responsive spacing
Same concept I apply into the Reponsive modes collection to create the responsive Spacing & Border Radius. As the Primary Spacing collection is already created is a question of connecting the "dots" in this case the variables for each responsive mode (each column). Here is an example:
| Responsive Modes | Desktop | Tablet | Mobile |
|---|---|---|---|
| ▽ Spacing | |||
| ↳ spacing-01 | 2 | 1 | 1 |
| ↳ spacing-02 | 4 | 2 | 2 |
| ↳ spacing-03 | 8 | 4 | 4 |
| ... | ... | ... | ... |
| ▽ Border Radius | |||
| ↳ pill | 9999 | 9999 | 9999 |
| ↳ sharp | 0.2 | 0 | 0 |
| ↳ small | 2 | 1.5 | 1.5 |
| ↳ medium | 4 | 3 | 3 |
| ... | ... | ... | ... |
| ▽ Typography | |||
| ▽ Size | |||
| ▽ Headings | |||
| ↳ H1 | 48 | 36 | 36 |
| ↳ H2 | 36 | 32 | 32 |
| ↳ H3 | 32 | 30 | 30 |
| ... | ... | ... | ... |
| You may find many different ways of applying the values, I personally can work with any one but I prefer to choose a spacing scale that doesn't include odd numbers as it can be difficult to align elements in odd spacing. |
Components
With the foundations in place, I move on to the first set of components. I don’t try to build everything at once. Instead, I ask: what are the elements this product actually needs to function day to day? Usually that means buttons, inputs, maybe a card or modal. I build those, but I make them smart: each one is wired to the semantic variables, and each one uses variants to cover its states like default, hover, or disabled. The result is a component that can adapt to different themes and contexts without duplicating work.
Here is an example of my Figma components variables:
Organization
Organization is just as important as the components themselves. In Figma, I keep a the pages in groups: Foundations, Components, Templates and Pages. I like to use emojis to easly find pages like 📃Changelog, 📸 Thumbnail and most important to define status, example I start building a new component and set the trafic light colors for their status 🔴for WIP, and🟡 for Testing.
The last piece of the puzzle is documentation. A design system without guidance is just a pile of files. I like to add on the sides of the components a bit of information like a sentence or two per component explaining when to use, or how text should contrast against its background it makes a world of difference. It’s not about writing a rulebook, it’s about giving just enough direction that anyone on the team can pick up the system and run with it.
And here’s the key: I never try to make the system perfect on day one. I share it early with my team, publish the library, and get feedback. People will quickly tell you what’s missing, what’s confusing, or what’s working beautifully. Then I iterate. Over time, the system becomes less about my vision and more about the team’s shared language.
In the end, a design system isn’t just about consistency it’s about freeing up creativity. When the basics are standardized, designers and developers can spend their energy on solving problems, not matching hex codes or redrawing buttons. Starting small, building intentionally, and letting the system evolve is what makes it powerful.
I hope you have found this article insigtfull, have fun creating design systems.
PS - Here is a example of GOV.UK Design System I updated using all these tips.