May 7, 2023 · 5 min read

Building Mística tokens

Simplifying Design Token Management for Mística, Telefónica's Design System.

Mística is a multi-brand design system. When a global design token in the system needs to be added or changed, the change must be replicated across all the supported brands. However, reviewing these changes can be time-consuming and prone to errors.

Mística currently supports 6 different skins:

  • Movistar
  • O2
  • Vivo
  • Blau
  • Solar-360
  • Telefónica

The process starts in the repository where design tokens are stored. Each brand has its own skin, which is a JSON file that stores all the design decisions for that brand. Tokens Studio is used to pull these tokens into Figma, and the development team uses these files as the source of truth.

Proccess flow of the token changes

Fig. 1 - The journey of a design token in Mística (Simplified):

To change a token value, a PR must be created in the skin JSON file to update the tokens in the Figma libraries and development repositories.

We are automating the process of fetching tokens from the development repositories to reduce the time developers spend updating the skin files.

Reviewing design token changes

Whenever we need to review token changes, it's done over a plain JSON, which can be tedious and error-prone.

  • Go to Figma

  • Change the branch that Tokens Studio is pointing

  • Create a branch in the libraries of each brand

  • Fetch the changes

Tokens have to be written in a specific format so Tokens Studio and the ongoing workflow for development repositories can extract the value correctly. When reviewing changes in a JSON file over 1800 lines long, it's easy to miss a token with the wrong format.

Another way to review changes is to create a branch in the web repository, manually copy and paste the new tokens/token values, and create a PR that automatically triggers a build of Storybook.

We asked ourselves two questions:

  • How can we make the review process more reliable and help designers detect format errors before submitting the PR?

  • How can we improve the review process by giving a visual example of the changes that are generated automatically?

The solution

Our solution was to create a tool called Mística tokens that would:

  • Fetch the JSON files of a specific branch of the repository.

  • Display all the available tokens in different tables depending on the token type and add a detail of the token value in each brand.

  • Display format errors in a user-friendly way so it's easy to understand what changes need to be made in the JSON.

  • Add automatically a comment in the PR pointing to the token list in the branch that we're merging into production.

I'm going to dive into the details of how the tool works in case it can be of any help to someone that's facing the same problems we do.

The JSON structure

The whole structure of each of the current JSON skin files looks like this:

"light": {
"dark": {
"global": {
    "palette" : {
"radius": {
"text": {

In the case of color tokens, they are defined by referencing a palette key.

A color type token definition:

"background": {
    "value": "{palette.white}",
    "type": "color",
    "description": "white"

And the palette color the token is referencing background:

"white": {
    "value": "#FFFFFF",
     "type": "color"

A JSON schema validates the tokens, both for Visual Studio and as a check of the PR itself, but it only validates that the semantic tokens should exist for all brands and the values these tokens exist on the palette.

Colors are the most complex token by far since their value can also be defined like this:

"backgroundOverlay": {
      "value": "rgba({palette.darkModeGrey}, 0.8)",
      "type": "color",
      "description": "darkModeGrey"

Extracting valuable information

The most important objective of the tool was to help designers to avoid the maximum of errors possible when submitting a PR with token changes.

The most important error that the JSON schema was unaware of was:

  • The token value is referencing a palette key that doesn't exists.

There are some warnings that we wanted to display too:

  • The token value and the description doesn't match.

  • The palette token is not being used in any token value.

Displaying format errors in a user-friendly way helps designers make changes more efficiently.

Token value not found

This means that the reference to the palette in the color token is not correct.

// Get the palette key from the token value

  function getPaletteKey(color) {
    const match = color?.match(/{palette.([^}]+)}/);
    return match ? match[1] : null;

// Get the color value from the palette

  function getColorValue(color, palette) {
    if (color.type === "color") {
      const paletteKey = getPaletteKey(color.value);
      if (paletteKey) {
        return palette[paletteKey]?.value || undefined;
      } else {
        return color.value;
    } else {
      return undefined;

When a token value cannot be found, the system displays the count of undefined token values. Additionally, an error message is displayed in the row containing the token with an undefined value.

Token value not found

Fig. 2 - Displaying the token not found error.

Now is easier for designers to visualize the problems before requesting a review and for the reviewers to spot potential problems.

Token description mismatch

This means that the description of the token doesn't match the palette key.

// Check if the palette reference matches the description

  function checkDescription(color) {
    const paletteName = getPaletteKey(color.value);
    return paletteName === color.description;

If a description doesn't match, a warning and a tooltip with information about the current description value are displayed.

Token value and description mismatch

Fig. 3 - Displaying the Token value and description mismatch warning.

Unused palette token

The palette token is not being used in any token value.

// Check if the palette reference matches the description

  const getMatchingCount = (paletteValue, colors = ["light", "dark"]) => {
    let matchingCount = 0;
    colors.forEach((colorType) => {
      const colorPalette = colorType === "light" ? lightColors : darkColors;
      Object.keys(colorPalette).forEach((key) => {
        const color = colorPalette[key];
        const colorValue = getColorValue(color, palette);
        if (colorValue === paletteValue) {
    return matchingCount;

If matchingCount === 0 a warning is displayed since that palette token is not being used.

Token value and description mismatch

Fig. 4 - Displaying the warning of palette values being unused.

This warning helps to remove the unused palette values that maybe in the past were referenced by a token and now continue living in the JSON without purpose.


It only took one day to create the entire tool using AI and GitHub Copilot. As a designer, it feels incredibly empowering to achieve this without a deep knowledge of Javascript or React.

With Mística Tokens, designers and developers can save time and effort in managing design tokens, making the update process more efficient and reliable.

In addition, the tool's user-friendly interface now enables non-technical roles to review token changes, making collaboration across teams easier and more inclusive. Overall, Mística Tokens has the potential to streamline the design token management process and bring more efficiency to design and development workflows.