Back
Sunday, November 7th, 2021

Creating design systems based on design tokens with Figma Tokens

A guide on how to build design systems that scale easily.

Figma is great. It's focus on design systems has allowed teams to collaborate better than ever before. One area that Figma lacks in though, is design tokens. Figma has Color Styles, but lack the ability to create semantic references. It has Text Styles, but it lacks the ability to define their values as atomic design decisions such as a common font family or font size scales.

When working in a multi-brand or multi-theme design system, having an abstraction that encapsulates all decisions of a theme is a lifesaver. When updating color references becomes as easy as the switch of a lever the creation of new themes or brands is just a matter of changing connectors.

Figma Tokens is a plugin that helps maintainers create scalable design systems with the help of semantic aliases, the use of math and a theme system that is as flexible as it gets.

With the recent addition of a GitHub sync feature it's the missing link between design and development, allowing designers to define their decisions in code without ever leaving their design tool. So, how do we create a multi-theme design system in Figma? Let's explore that.

Building the basics of a multi-theme design system in Figma

We want to create a system that is adjustable at it's core while flexible at the same time. We can do that by creating different layers of abstraction. Start by defining your foundational colors. These can range from a color palette that contains just a few basic colors to a foundation that contains a wide range of different colors. What's important is that you have a few colors to choose from.

Create a foundation

  1. Create new color tokens for black and white, call them something like colors.black and colors.white. For the value of the tokens, make sure to use hex, rgb(a) or hsl(a) values, like #000000 for black.
  2. Create some more tokens, this time some variations of grey and a blue. If you already have some existing Color styles you can speed up this process by pressing Import, which will import all the color styles from this file.

Next up is the definition of a theme-level design decision. We'll start with a Light theme. What you want to do is to create abstractons that your other decisions can use. For example, our backgrounds will be white, and the foregrounds will be black. We could also create some additions such as a muted color for secondary text. By doing this your design decisions become readable and easy to understand. Plus, we're able to swap out our decisions when we need to create a dark theme.

Create a light theme

  1. Create a new token set, choose any name you want (e.g. light) by pressing the plus button next to the global theme.
  2. Select this set and create a new token called something like fg.default and set it's value to {colors.black} - this will tell the plugin that this is a reference to the color named colors.black.
  3. Create more tokens in this set, creating semantic design tokens for the foreground and background colors.

Create a dark theme

We previously created a foundation and a Light theme. Let's create a second theme in the plugin that will serve as the basis for our dark theme.

First off, duplicate all content of the Light theme. To do that, go to the JSON tab, select all, copy - create a new token set named dark, paste contents and then Save & Update. Now what you need to do is change the references so you get a new theme. For example, the background tokens that were prevously referenced to colors.white should now be referenced to colors.black as we want our backgrounds to be dark. Do that for all the references that you think need changing.

Connecting to GitHub

Now that you've created your light and dark themes based on your foundation it's time to connect the plugin to GitHub. Doing this has so many advantages. First off, your tokens are now under version control. You can go back any time. Also, you get branching, which is a allowing you to create a new exploration first without locking it in.

To get started with the GitHub sync, read the guide in the plugin docs. It will tell you how to create a repository and how to get your access token, both things you will need.

Once you've set up sync it's time to start pushing your tokens to GitHub. Click Push to GitHub to push your design tokens to the repository. If you're pushing to a repository that your engineers use as well I'd recommend to push to a new branch so you can review your changes in a pull request.

As you've now pushed your tokens to GitHub you can consume these tokens in other files, in code or on GitHub itself, which is the perfect basis for the next chapter.

Creating color libraries based on our themes

Creating a light theme file

Now it's time to connect the dots. We want to create one library per theme, so let's start with the one we're in. First toggle the token sets you want active in that file. In your case that's the global and light set, make sure to not check the dark set we just created. Hit the Create Styles button and the plugin will create styles based on all checked token sets. Now name this file Light theme and publish it.

Creating a dark theme file

Let's proceed with the Dark theme. Create a new file in your team, start the plugin again. This time, go to the Sync tab and apply the GitHub credentials you've stored previously. This will pull your tokens stored on GitHub again. Again, check token sets that you want exposed - this time global and dark. Create Styles again, followed by a publish of this library.

You've just created two libraries, way to go!

Note
The plugin will create styles for all checked token sets, including the checked global one. You can either delete the styles you don't want in this library after creating, or you can rename the tokens in the global set by prefixing them with a `_`. This will tell the plugin to skip these.

Use and Swap libraries

You're now good to go to use these libraries in your Figma file! Simply import the Light library and apply some styles to your designs. Once you've done that you can start trying out Figma's Swap libraries feature. Go to the Assets tab, click Libraries, select the Theme you're using in a file, and select Swap library. Now choose the Dark library you've previously created.

Nice! All Styles that were previously Light are now Dark.

By using the plugin this way your designers don't have to use the plugin at all, they can keep using Color styles like they did before. But your library files are now much easier to maintain, have a source of truth outside of Figma, and you'd be able to create a new theme in a matter of seconds. You can do the same thing with Text styles where your designers could just keep using styles, but you'd create them atomically.

The plugin also allows you to use design tokens like border radii or spacing units for AutoLayout. This requires you to apply the tokens via the plugin UI, though. I usually recommend teams just getting started to stay to color and text styles as the Apply part of the plugin requires it to be open all the time (and is a little hacky compared to just using Styles).

Recap

Congratulations, you've just laid the basis for a multi-brand design system. You could go one step further and start doing something with the tokens stored on GitHub. You could create a GitHub Action to transform tokens to css variables using Style Dictionary or to a JSON being consumed by TailwindCSS.

I'm super curious what you'll create with this. Let me know in the Figma Tokens Slack where we exchange new ideas and workflows using the plugin.

Some examples of GitHub repositories using the tokens file as a single source of truth that then automatically transform these with Style Dictionary to css variables or even something like TailwindCSS:

Further reading

Creating themeable design systems, Brad Frost

Sign up and get informed about updates & new launches.

I'm currently building a mailing list for all people interested in following along any updates and new releases, once or twice a month, tops!