How To Leverage Component Variants In Penpot
With component variants, design systems become more flexible, letting you reuse the same component while adapting its look or state with ease. In this article, Daniel Schwarz demonstrates how design tokens can be leveraged to manage components and their variations using Penpot, the open-source tool built for scalable, consistent design.
- Daniel Schwarz
- Nov 4, 2025
- 0 comments
How To Leverage Component Variants In Penpot
- 9 min read
- Design Systems,
Design,
About The Author
Designer, dev, editor, writer, and nomad.
More about
Daniel ↬
*Weekly tips on front-end & UX.
Trusted by 182,000+ folks.*
With component variants, design systems become more flexible, letting you reuse the same component while adapting its look or state with ease. In this article, Daniel Schwarz demonstrates how design tokens can be leveraged to manage components and their variations using Penpot, the open-source tool built for scalable, consistent design.
This article has been kindly supported by our dear friends at Penpot, whose mission is to provide an open-source and open-standards platform to bring collaboration between designers and developers to the next level. Thank you!
Since Brad Frost popularized the use of design systems in digital design way back in 2013, they’ve become an invaluable resource for organizations — and even individuals — that want to craft reusable design patterns that look and feel consistent.
But Brad didn’t just popularize design systems; he also gave us a framework for structuring them, and while we don’t have to follow that framework exactly (most people adapt it to their needs), a particularly important part of most design systems is the variants, which are variations of components. Component variants allow for the design of components that are the same as other components, but different, so that they’re understood by users immediately, yet provide clarity for a unique context.
This makes component variants just as important as the components themselves. They ensure that we aren’t creating too many components that have to be individually managed, even if they’re only mildly different from other components, and since component variants are grouped together, they also ensure organization and visual consistency.
And now we can use them in Penpot, the web-based, open-source design tool where design is expressed as code. In this article, you’ll learn about variants, their place in design systems, and how to use them effectively in Penpot.
Step 1: Get Your Design Tokens In Order
For the most part, what separates one variant from another is the design tokens that it uses. But what is a design token exactly?
Imagine a brand color, let’s say a color value equal to hsl(270 100 42) in CSS. We save it as a “design token” called color.brand.default so that we can reuse it more easily without having to remember the more cumbersome hsl(270 100 42).
From there, we might also create a second design token called background.button.primary.default and set it to color.brand.default, thereby making them equal to the same color, but with different names to establish semantic separation between the two. This referencing the value of one token from another token is often called an “alias”.
This setup gives us the flexibility to change the value of the color document-wide, change the color used in the component (maybe by switching to a different token alias), or create a variant of the component that uses a different color. Ultimately, the goal is to be able to make changes in many places at once rather than one-by-one, mostly by editing the design token values rather than the design itself, at specific scopes rather than limiting ourselves to all-or-nothing changes. This also enables us to scale our design system without constraints.
With that in mind, here’s a rough idea of just a few color-related design tokens for a primary button with hover and disabled states:
| Token name | Token value |
| --- | --- |
| color.brand.default | hsl(270 100 42) |
| color.brand.lighter | hsl(270 100 52) |
| color.brand.lightest | hsl(270 100 95) |
| color.brand.muted | hsl(270 5 50) |
| background.button.primary.default | {color.brand.default} |
| background.button.primary.hover | {color.brand.lighter} |
| background.button.primary.disabled | {color.brand.muted} |
| text.button.primary.default | {color.brand.lightest} |
| text.button.primary.hover | {color.brand.lightest} |
| text.button.primary.disabled | {color.brand.lightest} |
To create a color token in Penpot, switch to the “Tokens” tab in the left panel, click on the plus (`+`) icon next to “Color”, then specify the name, value, and optional description.
For example:
- **Name**: `color.brand.default`,
- **Value**: `hsl(270 100 42)` (there’s a color picker if you need it).
*[Creating a color token in Penpot]*
*Creating a color token in Penpot. (Large preview)*
It’s pretty much the same process for other types of design tokens.
Don’t worry, I’m not going to walk you through every design token, but I will show you how to create a design token *alias*. Simply repeat the steps above, but for the value, notice how I’ve just referenced another color token (make sure to include the curly braces):
- **Name**: `background.button.primary.default`,
- **Value**: `{color.brand.default}`
*[Creating a design token alias in Penpot]*
*Creating a design token alias in Penpot. (Large preview)*
Now, if the value of the color changes, so will the background of the buttons. But also, if we want to decouple the color from the buttons, all we need to do is reference a different color token or value. Mikołaj Dobrucki goes into a lot more detail in another Smashing article, but it’s worth noting here that Penpot design tokens are platform-agnostic. They follow the standardized W3C DTCG format, which means that they’re compatible with other tools and easily export to all platforms, including web, iOS, and Android.
In the next couple of steps, we’ll create a button component and its variants while plugging different design tokens into different variants. You’ll see why doing this is so useful and how using design tokens in variants benefits design systems overall.
### Step 2: Create The Component
You’ll need to create what’s called a “main” component, which is the one that you’ll update as needed going forward. Other components — the ones that you’ll actually insert into your designs — will be copies (or “instances”) of the main component, which is sort of the point, right? Update once, and the changes reflect everywhere.
Here’s one I made earlier, minus the colors:
*(Large preview)*
To apply a design token, make sure that you’re on the “Tokens” tab and have the relevant layer selected, then select the design token that you want to apply to it:
*[Applying a design token in Penpot]*
*Applying a design token in Penpot. (Large preview)*
[...]
---
*[Original source](https://smashingmagazine.com/2025/11/how-leverage-component-variants-penpot/)*