< back to all blog posts

Life of a design token

I woke up this morning feeling like I was Sir David Attenborough ( the renowned British broadcaster that’s made nature documentaries for decades)… so if you’re interested in learning more about design tokens, here’s the lifecycle of design tokens (imagining him reading this is optional).

It’s here, the natural environment of a design system where we can explore one of the shyest and yet most potent parts of the design system ecosystem, the humble design token. Often nestled in between visual design, UX, code and documentation, this innocuous creature is actually a key part of this environment. It has no natural prey and prefers to seek out collaboration.

Let’s find out more about them from conception, their relationships, to their eventual decay. By learning more about them, perhaps we can nurture them and support them to grow and fulfil their potential. We see how they occupy the space between design and development, expressing visual properties in form of code.

The birth of a token

A single token can be conceived in many ways… from the union of brand and UX, visual design and code, their creation itself is often an act of collaboration and an attempt to communicate clearly for others to benefit. If we start our journey by following a single color token, we can see not just what it is but a hint of what is to come.

Our token is best represented through JSON, which is a JavaScript object and so easy to pass between different kinds of code; this format, while visually stark, embodies one of the core qualities of a token, that of reuse. Our single embryonic token example is a color, one of our core brand colors.

{
  “colors”: {
    “example color”: {
        value: “​​#f63e7c”
    }
  }
}

Already, one wonders what it should be called; what name might express its purpose and intent? “example color,” while perfectly fine at its birth often needs a clearer name for the next stage of its journey. Names for tokens, unlike our own are often the center of much debate as the community around it awards the token with one that is suitable. Referring to Nathan Curtis’ article might give you some inspiration for naming conventions for your own system. In this instance, this only child doesn’t yet have siblings or a sense of its wider family of tokens, so assumptions are made; the community aware that as more information comes to light, that its name may change.

{
  “colors”: {
    “brand”: {
      “primary”: {
        value: “​​#f63e7c”
      }
    }
  }
}

Now awarded a name and greater context, the community around the token looks to the emerging guidance to better equip this young token. In this case, we can add some additional information and some formatting so that it has the best chance of being useful in the many scenarios it may come across in future (noting that at the time of writing, this format is not used by Figma Tokens or other plug-ins, strip out the dollar signs for current usage).

{
  “colors”: {
    “brand”: {
      “$description”: “Collection of colors from our brand guidelines”,
      “primary”: {
        “$value”: “​​#f63e7c”,
        “$decription”: “This is our brand’s most important color”,
        “$type”: “color”
      }
    }
  }
}

Housed in a file we’ve called tokens.json, it has everything a growing token needs to go out into the wild and yet we’re not yet putting it to use. Here we have many options, through either using that value directly in some kind of code, importing it into our design tool (where available, e.g., Figma Tokens plugin), exporting it from the design tool to code or transforming it into something different altogether through a tool like Style Dictionary. The latter gives us the ability to express this token’s value in a huge amount of ways and, if we want, transform the value into something different altogether.

Of course, as their abilities are not yet fully formalized, we may over time need to express multiple values for a single token (as a composite token), or include additional properties to explain a token’s purpose (when using Style Dictionary).

We can now consider our use cases, what kind of output and processes to create something tangible that can be consumed by other parts of our ecosystem. This could be CSS, Sass, CSS variables…our original value is clear but provides us options of how we might choose to use it, which may change over time. More than using what’s already available to us, we can also create our own methods or transforming this token, creating something bespoke to our needs without dramatic changes to our workflow.

Our token has only just got started and we’ve seen:

  • How we can be clear on its purpose
  • Find a suitable name for it
  • Revise how we explain it in JSON based on what we know
  • Look at the emerging spec for Design Tokens to see what may be coming
  • See if Style Dictionary (or similar tools) can help transform our token values into a format we can easily consume

It now becomes part of something bigger

Far from being a lone wolf, our design tokens as innately part of something larger; their power comes in the ways they make relationships and challenge preconceptions we might have of other entities we call components.

Following our example so far, there isn’t much additional context provided aside from the hierarchy of it being a color and in a group called ‘brand’. It’s at this stage that we can already begin to consider how we explain what the purpose of the token actually is. While we gave our token a description, we can revisit that field but consider its wider context of use. What use cases should it have? How does this relate to other color values? In terms of a brand color – are there brand personality traits more resonant in this color than another? Whether you use zeroheight or any other method of documentation, capturing this at the point of making decisions or as we store them in tokens gives them clarity and longevity.

Being the early days of design tokens, they’re not yet fully defined and able to be easily integrated into our design tools, though the W3C community group around them has that as part of their goal – true interoperability across tools and code. For now, Figma has third-party plugins such as Figma Tokens that can use these values and make them available in our designs, edit them and return those changes back to our raw token file(s).

The relationship between tokens and components is an enduring one but not always consistent. If we look at a simple button component, we can start to look at some of the ways this relationship might manifest.

Here we see that the relationship here is very direct. The button component is consuming the brand color from our token as its background. There’s nothing inherently wrong with that, but as the systems grows and matures, this relationship may be tested.

To allow some flexibility in the relationship between our tokens and components, we may choose to create a semantic token to represent the intent of the use of color. Our use of the primary brand color may turn out to be circumstantial and change over time. In the way, we build in some flexibility to assign another color value to match that use case. We might for example call this color ‘action’ as prescribe a use case that it is to be used on elements that a user would interact with. Some might call this an alias token as it refers to another value

This reference allows us to change our current value to either a new color value or a reference to another token and yet the token remains something we can use with a great many components. We can go a stage further with making more component-specific tokens to describe properties of a component. In this way, we begin to systematize more of our design and UI estate, the tokens embodying the design decisions that we’ve made along the way.

Our isolated token may of course wish to explain its intent in a number of ways, which may be apparent for other platforms – native apps. While we’re able to transform our token’s value through Style Dictionary, we may want to actually store the intended value rather than changing it programmatically. It can be argued that the token shouldn’t be bound to its output and largely remain agnostic so being too tightly bound to CSS as an example might limit its future reuse. Here we can make a choice whether we support what’s know as composite tokens. While the structure is largely the same, we assign an object containing multiple value to the value property of our token. In this example, we’ve express our colour in separate red, green, blue and alpha channels enabling us to easily output in a number of ways

{
  "colors": {
    "ui": {
      "$description": "Collection of colors with specific use cases",
      "action": {
        "$value": "{colors.brand.primary}",
        "$description": "To be used on triggers for user interactions",
        "$type": "color"
      }
    }
  }
}

We could export this as CSS as `rgba(0.96, 0.24, 0.49, 1)` or perhaps as `UIColor(red: 0.96, green: 0.24, blue: 0.49, alpha: 1.00)` for Swift or `new UIColor(red: 0.96f, green: 0.24f, blue: 0.49f, alpha: 1.00f)` for Xamarian/C# (I used UIColor.io to quickly convert btw). The token holds values that explain the color well enough that we can choose to output in ways appropriate for the platforms we want to cater for.

  • We’ve given our token a semantic name
  • Looked at what an alias token is
  • Seen how we can use composite tokens to make more of our value field

Blends in with its surroundings

From this solid structure, other abilities are revealed; that of enabling chameleon-like properties in our components through theming. This concept itself can have many interpretations so in following our single design token, we’ll refer to a theme and a distinct application of brand. It can be more than a change of color palette as it leans more into various brand personality traits.

Going to our button component example, it would seem wasteful to create a new button because our next instance needs to be rounder and use a different color. Here we begin to consider what properties from our button we might consider themeable. To keep this example small, we’ll just change the color but this process could be used for any property of a component.

We start a new token set to describe this component’s properties:

{
  "button": {
    "background-color": {
      "$value": "{color.ui.action}",
      "$description": "The background color for our primary button",
      "$type": "color"
    }
  }
}

The value our output will use is an alias for a semantic UI token, meaning that what we’ve done is explain the relationship between the background of our button and the semantic palette we’re using. Should we change the color for ‘action,’ we know that our button background will also change as it’s nothing more than a reference. So far, so familiar. If we say that this example is in ‘theme 1’ but then in ‘theme 2’ have the need to use a different token as there may be an additional semantic color token available, it may then look like this:

{
  "button": {
    "background-color": {
      "$value": "{color.ui.primary_action}",
      "$description": "The background color for our primary button",
      "$type": "color"
    }
  }
}

Depending on our structure, we now have the ability to express a theme with a different set of relationships with values or references to core/semantic tokens without changing the component in any way. This demonstrates just how powerful tokens can be when we defer the storage of our design decisions to them and look at maintaining relationships with them.

This set-up and designing of the structure and relationships of design tokens that can fuel the collaborative nature of design systems. While we express this in a code-like format, this potential source of truth considers interoperability between design and code execution. Increasingly we may see this format used directly in our design tools, bringing these specialisms closer and more able to be automated.

  • We’ve introduced the idea of themes
  • Seen how component-level token definitions might work and how they can help with themes
  • Looked at how the collaborative environment it favors works really well in this context

When its time has come

Sadly, even design tokens have their time and at some point may outlive their usefulness. Here, the process can be referred to as deprecation; flagging that our token will soon be deleted and so components using it must make new relationships.

Let’s take a scenario where our ‘action’ color is no longer expressive enough and we have ‘primary action’ and ‘secondary action.’ We lack options to enable a smooth transition. We could just flag it in the description of our token but actually, deprecating is something I want to cover in more detail in a forthcoming article.

{
  "colors": {
    "ui": {
      "$description": "Collection of colors with specific use cases",
      "action": {
        "$value": "{colors.brand.primary}",
        "$description": "[DEPRECATED] To be used on triggers for user interactions",
        "$type": "color"
      }
    }
  }
}

There needs to be some sense of managing references to this flagged token across our design tool and the output we generate. On the tech side, should it fail a build or give us a warning? Before making any changes, it needs to be clearly communicated what token should be used instead and all uses of this token migrated to this other token.

Once we’re sure that there are no references to our original ‘action’ token. We’re sure that we can delete from the design system. From its conception as a simple color value, we’re seen how we can not only describe what it is and how it should be used but how it forms relationships and can provide great power to our system. We’ve also shown that change is not only possible but desirable.

As the environment around our design tokens changes, so should our structure. Sometimes tokens themselves can meet an end and hand over their roles to others.

  • Deprecating
  • Replacing – spawning new tokens
  • Deleting

What of their future?

*cough* I can probably try and stop pretending to be David Attenborough now I’ve made it to the end *cough*

The reality is that design tokens are still in their infancy, despite it being many years since the folks at Salesforce pioneered their use. What we have is a meta space for explaining our designs that can act as a bridge between disciplines – bringing not just designers and developers together. We also have the ability to change our components massively from this one source, which is power we’ve not had before.

As a means of storing decisions that enable design and code to literally use the same source of truth, this is still very early days. The W3C Community Group is doing a great job in forming a standard around them, with contributions from many design tool vendors that feels like we’re on the cusp of getting to a really interesting place.

Beyond the basics of storing colors, there’s so much further we can take them and through that, so many challenges we haven’t yet come across!