_Engineering Path - Introduction to Tokens

Introduction

In the first chapter, Where to Begin, we introduced you to the design-tokens repository where we store our design tokens. The repository acts as a single source of truth for out tokens and connect the tokens used in Figma by the designers to the tokens used in the core components of the Mews Design System. In this chapter we will go more in depth about our design tokens explaining how we keep the single source of truth and how other developers can use the tokens when building part of a product or a new component.

Why we use tokens

When we build and style any of our core components we use various styling values like font size, background colour and border radius that are decided and defined by our designers. Those values have been carefully picked and are part of a system and follow multiple criteria. We could just inspect a piece of design and copy and paste the value we can see in Figma in the styling file for the component we are working on.

The problem with this approach is that now the same value lives in two different places, in design and code, with no connection meaning if the designers change a value in a design file that will not reflect and there is has to be communicated to developers and a developer has to find where the value is used in the codebase and update it.

As you can see this is not scalable, it is very prone to human error and lacks the usefulness of relying on a single source of truth system.

How we use tokens

It should be now clear what are the advantages of using tokens. Let’s go a bit more in depth and explore how we use tokens when developing our core component and how they help us staying more aligned with designers.

As said above a token can be any sort of styling values but our tokens are not the core value let’s say 8px for example but instead we have for example spacing.100 and this helps us extracting the value from the name so if in the future we end up changing our spacing scale we just have to change the value behind the name of the tokens because the name will still be valid. The same goes for a colour token, we don’t have red but instead danger as the name of the token.

The token names are created and managed by designers in Figma using a tool called Token Studio that is then connected to the design-tokens repository and published as a npm package. Contrary to the core components of the Mews Design System the tokens are accessible outside the monorepo and are available in multiple formats for different usage.

The tokens for the light theme coming from Figma

The tokens for the light theme coming from Figma

How we build tokens

As mentioned above tokens go from Figma to a npm package, but how? Because the most important aspect of tokens or any tool that is supposed to help designs and developers collaborate is to be always synchronised we developed a system that allows us to consider the design-tokens repository as our single source of truth. That means that the most up to date tokens live there and in case of conflicts with other tools the tokens in the repository should be considered the correct ones. Let’s quickly go trough the system we have in place. We store the tokens coming from Token Studio in JSON format divided by theme.

For each theme we then create the output tokens in a variety of formats for different usage. This is useful because as we said above the repository is detached from the monorepo and the tokens are used not just in mews-js for also for the mobile design system for example and potentially can be consumed by other internal projects using CSS or JSON. The conversion and creation of tokens is done just running the build script that underneath relies on Style Dictionary and token-transformer.

The tokens transformed and built in TypeScript for the light theme

The tokens transformed and built in TypeScript for the light theme

Any time new tokens are pushed from Token Studio a PR opens and use developers in the Design System team we check if everything looks as expected. In case we reject the changes or we make changes straight in code the designers will see in Token Studio an income changes and therefore they can pull the changes. In this way we can keep the designers and developers in sync while using different tools.

Once all the tokens are created we prepare a new version of the package picking the version number based on Semantic Versioning and we then push and publish the new package. Most of these tasks are automated thanks to multiple GitHub Actions. We try to make the process as straightforward as possible because the repository cannot be a bottleneck for the designers wanting to add and update tokens. Of course once a new version is published you’ll have to update the version number where you are consuming the package.

The various GitHub Actions we use for publishing the design-tokens package

The various GitHub Actions we use for publishing the design-tokens package

How you can use tokens

We have explained why we use tokens and how we build tokens, let’s focus now on tokens can be used in code for styling whatever you are building or working on in general. Unless you are building a new component from scratch, something that we are going to focus on in another chapter, you probably won’t use tokens much, unless you need to add some custom styling to your product, and even less you will contribute in terms of adding more tokens to the package.

Utils

The design-tokens package is imported and used in the Mews Design System in the monorepo. We built multiple utilities that help using the tokens and are exposed so they can be used also in other packages in the monorepo.

Let’s check the main ones quickly and see when and where you could take advantage of the utils:

  • getToken: this getter should be used anytime you want to use a token. Pass the token inside a string and you are done. If your IDE is setup correctly you should also get autocomplete so you can avoid trying to guess the name of the tokens. Just remember that number tokens usually are missing the unit that has to be added after.
  • getSpacingToken: this a subset of the more generic getToken and should be used specifically for spacing tokens that generally are related to margin, padding and so on. You can just pass the value of the spacing as string. As above don’t forget to add the unit at the end.
  • getTextTokenPreset: this getter covers everything related to typography. Pass the string of the text preset you need and it will style font size, family and weight plus line height and letter spacing. Try to avoid to style anything related to text manually but instead always relies on the these presets.
The various utilities that allow you to use tokens in your project

The various utilities that allow you to use tokens in your project

Contribute

In general we expect tokens used almost never directly and only sometimes in your project mainly leveraging the utils we just described above. If for whatever reason you find yourself in a specific situation where you are building your own components and none of the tokens available cover your specific case you should talk to your designer first and try to find out why an already existing tokens was not used. If your designer has already discussed this with the Design System team then the team itself will be responsible for adding the new token and publish the new version of the package. If this doesn’t work as expected and you don’t see the token you were expecting while using the latest version of the design-tokens package feel free to send a message to our Slack support channel.

Design

While inspecting a design you should be able to see the name of the token used and that will be very useful when you are then moving into the code and try to understand which token you should use. As said above if your designer has used a custom value instead of a token try to speak with them and understand why this is happening. Specially if you are just using a component you should almost never overwrite the value or replace the tokens used with others. The only difference present between tokens in Figma and in GitHub is that designers use dot case format while in code we rely on Pascal Case.

Outro

In this chapter we introduced you to the concept of design tokens explaining why they are extremely useful and how we have structure our pipeline in order to connect design and code and have the tokens always in sync. We expect you to use tokens through components instead of a direct usage but we understand that sometimes custom styling is needed and that’s why we told you a bit more about the various utilities you can use. Also if are building a new component you are going to use tokens a lot and you should avoid at all cost using value not connected to tokens. In case you need new tokens we are here to support you, tokens have been picked and structure in a very meticulous way so new tokens have to be added follow a specific criteria.

Where next