Working with design tokens

XD Community ENG
13 min readDec 17, 2024

--

The concept of design tokens was first mentioned by Salesforce in 2016. The approach they proposed allowed to concentrate all static (raw) values and references to them in the so-called “Source of the Truth” file of their Lightning Design System. The variables stated in it were later used at all levels of design, starting from the smallest components and ending with finished pages. Since then, many existing products have already managed to adopt this practice and fully switched to supporting tokens in their design systems.

Given the constantly growing popularity of this topic and its practical relevance, it would not be superfluous to understand what design tokens are, when they are needed, and how a designer should work with them. Let’s go! 🤘

So what is a design token?

Traditionally, let’s start with the definition of the term. Individual articles do not fully reveal it, so I suggest the following option:

A design token is the smallest named unit of a design system that stores a value responsible for the visual description of an object (or its spatial placement relative to other objects) and can be inherited when building more complex design elements.

Phew, it came out too complicated, so let’s try to explain.😅 If we resort to the atomic design principle, the design token lies at the basis of the structure of any component. I’m not sure what name would be appropriate precisely from the point of view of the molecular level, but the point is that the appearance of an atom is determined by the set of values of its tokens.

The place of design tokens according to the atomic design principle

For clarity, let’s consider the well-known atom — a button. As one can easily find out, there are quite a few possible design tokens even for such a simple component:

The minimum list includes:

  • Background color
  • Padding
  • Font-family
  • Font weight
  • Font size
  • Font color
  • Line height

Possible additional tokens:

  • Border radius
  • Border color
  • Border width
  • Shadow: separate tokens for vertical, horizontal offsets, blur size, and color
  • Icon size

To some extent, designers have already been using design tokens when naming their color styles like primary, surface, text…, perhaps not even fully realizing it. To start doing so, it is enough to analyze other’s work or familiarize yourself with how well-known design systems approach this, particularly Material. This naming of styles will help us solve two main tasks:

  1. Have a rough idea of what it is needed for;
  2. Update the saved value of the style in one place. Plugins like Make Color Styles or Automate Color Styles also allow you to automate the process of creating and assigning the necessary styles based on the current design, if this was not done initially.

However, as practice shows, using only styles has its drawbacks:

  1. Because styles have generalized names, their frames of use become blurry. If you’ve created everything yourself, you can still more or less cope with this. Problems usually arise when you act as a new designer on an already existing project. For example, you may not know what makes the style with the name “accent” different from “primary”, which of the 5 shades of the base color is better to use or when to create a new style where it would be unnecessary. This is partly solved by documentation, but it is not always present or is presented at a very basic level.
  2. It’s difficult for us to control what undergoes changes in the event of a styles update. They can affect what we would like to skip or vice versa — not be applied to the items we need.
  3. There are attributes that we cannot save as styles. Limiting only what can be set at the style level, the designer should remember all the other elements that directly affect the consistency of the design.

In the case of color, you can, of course, level the first two problems, by creating separate styles for each separate component (and you will become a real star if you do so 🤩). At the same time, it’s also necessary to consider all states in which the color needs to change. And now think about what if, in addition to this, you will have a design version for the dark theme or several color themes at once… It’s obvious that such a system becomes harder to maintain and update because changes will have to be made in several places, and there can be a lot of those.

I’m saying all this because the use of design tokens allows designers and other team members to:

✅ Better understand the “use-case” of a specific value of color, font, margin, etc;

✅ Maintain the design consistency even better, going beyond components and design patterns;

✅ Make both granular and global changes that will be cascaded in all places where one token refers to the value of another;

✅ Simplify the support of a design developed for different platforms, sizes, and color themes;

✅ Facilitate communication with developers thanks to the use of precise names that describe the same things;

✅ Reduce the risk of mistakes for design system contributors.

We will talk in more detail about how to properly structure and name design tokens, and also examine how it works on examples prepared by me.

Design token levels

It should be noted that the division of tokens into the levels listed below is relevant solely for colors. As a rule, this is what most often needs to be “tokenized” and, at the same time, requires the most time. Creating such a token begins with defining its hierarchy level. In fact, there are three of such levels:

  1. Global tokens / primitives: The basic type of token that assigns a name to a static color value. Is relevant for:
  • Grayscale palette
  • Primary and/or secondary palettes
  • System color palettes
  • Any other additional palettes, the main tone of which is different from the previously listed.

Examples: $blue-500, $gray-900, $green-100. The numbers after the hue name indicate the level of brightness of its shade (in descending order as this number is larger).

2. Alias Tokens: Its value is a reference to a global token and the name that adds additional context to it. This can include:

  • Semantic tokens: The system palette that we attributed to the first group is often used to encode green 🟢: success, yellow 🟡: warning, red 🔴: error, blue🔵: information
  • Groups of colors used for data visualization based on the colors of the main and / or additional palettes.
  • Colors indicating interactivity (buttons, links, text fields) or state (selected: checkbox, radio button, switch; active: menu item or tab)

Examples: $feedback-success-bg, $action-primary-bg

3. Component level tokens (component-specific tokens): There can be many examples here, for understanding here are just a few of the possible ones:

  • Background of the main button
  • Tooltip color of the text field
  • Visited Link

Examples: $btn-primary-bg, $text_input-placeholder, $text_link-visited

Such an organization allows the designer to achieve the necessary level of specificity while having the ability to quickly change the required token value. Updates will be cascaded to all lower-level tokens as long as their value (variable name) matches what we are changing.

Naming tokens

Correctly naming a token that will accurately describe it may not be an easy task. It is extremely important that the names you choose are well understood by all participants who will be responsible for developing and using the design system. The name of the design token can include such components as:

  1. Category (only the main ones are listed):
  • Color ($color-action-primary)
  • Font ($font-size-heading-1)
  • Distance ($spacing-xl)
  • Shadow ($shadow-elevation-8dp)
  • Animation ($animation-duration-fast)
  • Size ($button-sizing-l)
  • Rounding ($border-radius)

2. Magnitude:

  • Numbered ($font-heading-level-1)
  • Ordered ($color-core-blue-500)
  • Proportional ($spacing-2x, where x is the base pixel grid size)
  • Relative ($spacing-mobile-xl)

3. Context:

  • Global ($color-core-blue-500)
  • Semantic ($color-semantic-success)
  • Component ($color-button-primary-fill-default)

4. Attribute (the set of possible attributes is determined by the category of the design token):

  • Color ($color-text, $color-background, color-border …)
  • Font ($font-size, $font-style, font-line-height …)
  • Shadow ($shadow-elevation, $shadow-color, $shadow-blur)
  • Animation ($animation-duration, $animation-delay)
  • Rounding ($border-radius-top-left, $border-radius-bottom-right)
  • Distance ($toast-min-width, $button-height)

5. Variant:

  • Primary / secondary ($color-component-button-primary-fill-default, $color-text-secondary)
  • Active/disabled ($color-checkbox-enabled-selected-text, $color-tab-unselected-icon)

6. State:

  • Default ($color-btn-primary-default-bg)
  • Hover ($color-btn-primary-hover-bg)
  • Pressed ($color-btn-primary-pressed-bg)
  • Focus ($color-text_input-focus-outline)
  • Disabled ($color-checkbox-disabled-bg)
  • Visited ($color-text_link-visited)
  • Error ($color-text_input-error)

7. Mode (theme):

  • Light ($color-surface-on-light)
  • Dark ($color-primary-on-dark)
  • High contrast / accessibility mode ($color-text-high-contrast)

8. Brand ($color-ocean-primary, $color-amber-surface)

9. Platform ($spacing-watch-xl)

10. Breakpoint ($font-heading-size-media-query-s)

As can be understood from the list above and the examples I mentioned, it is not only important what is included in the name of the design token but also the appropriate order of its components. Guided by it, a designer can describe any token as accurately as possible.

Naming Tokens in Design Systems: Terms, Types and Taxonomy to Describe Visual Style

What does working with design tokens look like in practice

Until the advent of tokens as part of the basic functionality of Figma and similar tools, the only way a designer could work with them was through plugins. Among the most popular of them are Tokens Studio for Figma (Figma Tokens). If you have not heard of it before (or have heard but not used it), I recommend reviewing the official documentation before starting work. This way, you can quickly understand the basics of work and the capabilities of this plugin. Finished? Then let’s move on. 🙂

You may ask, “Why this plugin and not the variables feature?” Having tried both, I came to such a conclusion because:

  1. Unlike variables, the Figma Tokens plugin contains all possible design tokens that you will ever need.
  2. The plugin allows you to create the necessary number of collections (sets), as well as apply one or several of them at the same time. In the case of variables, first, you are limited to only one mode on the free tariff. Secondly, you do not have the ability, for example, to apply one color theme, replacing the font or somehow dividing colors into groups within a specific theme.
  3. You can export design tokens in JSON format for transfer to developers or download an existing file containing token values. When working with variables, you will have to additionally use the variables2ccs or variables2jsonplugin for this. It will be necessary to additionally check the output file, because there were cases when the names of the variables were incomplete and had to be corrected manually.
  4. Further conversion and synchronization of tokens with Token Studio into variables are possible (*on the paid tariff). In case you have already created variables or styles for your project, you can also import into the plugin using Styles & Variables — Import Variables / Import Styles.

Design token creation algorithm

Okay, now in more detail about what should be the designer’s action algorithm during work with tokens. Let’s do this on the example of the Token Studio plugin I liked (and now I hope you too 😃):

  1. Determine the set of required collections (sets)

Before starting to add tokens, it’s essential to understand what collections you need. Each collection should have a separate token category assigned to it (colors, indents, font styles, etc.). The approach of storing all possible tokens within one set is incorrect, as in the case of creating additional themes we add extra work related to updating duplicate tokens.

If you understand this too late, it can’t be fixed. This plugin, like variables, does not allow you to move tokens (or their groups) from one collection to another. Therefore, the only way out of this situation will be to manually delete and add in a new one. I really hope that such a possibility will appear sometime 🙏, but for now, we try to come to the correct organization the first time.

In my case, it looked like this:

  • core: base color tokens of the first level. They are in no way dependent on the color theme.
  • light-cb & dark-cb: colors that define a particular theme, in my case — the basic theme of the interface;
  • mapped-light & mapped-light: component-level color tokens for light and dark themes respectively.
  • rounded: tokens that store rounding values;
  • spacing: tokens that store indentation values.
Dividing colors into separate sets depending on the token level simplifies support and updates.

2. We mark the necessary collections as “Treat as source”

For me to be able to refer to external tokens within the mapped-light, mapped-dark collections, the light-cb and dark-cb palettes must be marked as “Treat as source.” The same applies to core.

The ability to use links to tokens from an external set through the Treat as Source setting.

3. Apply tokens to design elements

We select the required design element and perform a left click on the required token. In the case of colors, the token, by default, is applied as a fill. Right-click allows us to choose from other attribute options; they will be different depending on the specific category. In the case of color, only fill and border are relevant.

Applying a token and choosing between fill and border

It is worth noting here that, unlike styles and variables, there is no binding visible in the right panel, and colors will still be displayed in hex values. The fact that the token was applied will only be understood after launching the plugin due to the frame around the token or in the Inspect tab. This means that in dev-mode or when transferring layouts to a third-party inspection tool, such as, for example, Zeplin, the token names you used will not be visible. This needs to be taken into account.

4. View the design for an external theme

To do this, we “turn on” the pre-created sets that define the theme and click “Apply to selection”. If you, for example, want to update the theme within the entire page or document, this can also be done by selecting “Apply to page” or “Apply to document”. Of course, this will only work if all the necessary tokens are already linked.

View the design for light and dark themes
Example of implementing an external color theme

Not bad, huh? 😏 Similarly, you can also create several sets with separate font pairs or store separate indentation values depending on the device or screen size.

5. We export

When you are satisfied with the result, export your design tokens in JSON format for transfer to developers. To do this, go to Tools — “Export to File / Folder”. If we want to export all existing sets, we additionally set the “All token sets” checkbox. All tokens can be combined into one file (“Single file”) or divided into separate ones according to the set (“Multiple files”).

Personally, I prefer separate files. This way, we can divide collections between those that will always be repetitive (like mapped and core) and those that depend on a specific theme. As a result, this allows you to separately connect the necessary files in the code when replacing one theme with another.

Exporting tokens and their separate sets to a JSON file

Documenting tokens

Finally, I have a few recommendations on how you can document your design tokens:

  1. Quick creation of annotations

The “Debug & Annotate” function, which you can find in the “Inspect” tab of the Token Studio plugin, creates design token annotations for your chosen element. This is great for describing the tokens used for a specific part of the layout or components.

2. Sync updates made through the plugin to design documentation

The Documentation Tokens feature allows you to link the token name and its value to the corresponding descriptive part and thus always keep it up to date. Combined with the Automator plugin’s Create Documentation for Figma Tokens macro, this setup process can be automated for all tokens in your library with one click.

3. Use an external documentation tool

Design system documentation tools include functionality for both manual creation of design tokens and their import via styles or JSON file. Regarding the latter, be prepared that the structure and name of the fields may not meet the tool’s requirements, making it impossible to playback correctly (example: Zeroheight Tokens Manager JSON file requirements). But don’t get upset, JSON syntax is quite simple, so the designer should have no trouble figuring out what’s what and make the necessary updates.

Conclusion

In this article, I tried to convey my thoughts on the difficulties that you and your team may encounter while maintaining a design system, and how tokens can help with this.

At the same time, it is important to understand when their implementation is most timely. You should not move on to adding tokens when you do not yet envision what your final design will look like. Otherwise, you will just start focusing on what is less important now. The benefit of tokens may not be perceptible here and now, but it is noticeable in the long-term perspective of product development. Just as the possible dividends from the shares you have bought are not paid out immediately. That’s such an analogy from me.

I hope that what I shared will be helpful to you and now you will feel more confident in working with design tokens. 😎 💪

Join our social networks:

--

--

XD Community ENG
XD Community ENG

Written by XD Community ENG

We are designers, analysts, managers, and other kinds of IT experts from different companies. Join us, and let’s grow together.

No responses yet