Table of Contents
1 | Introduction to Design Tokens
2 | Managing and Exporting Design Tokens With Style Dictionary
3 | Exporting Design Tokens From Figma With Style Dictionary
4 | Consuming Design Tokens From Style Dictionary Across Platform-Specific Applications
5 | Generating Design Token Theme Shades With Style Dictionary
6 | Documenting Design Tokens With Docusaurus
7 | Integrating Design Tokens With Tailwind
8 | Transferring High Fidelity From a Design File to Style Dictionary
9 | Scoring Design Tokens Adoption With OCLIF and PostCSS
10 | Bootstrap UI Components With Design Tokens And Headless UI
11 | Linting Design Tokens With Stylelint
12 | Stitching Styles to a Headless UI Using Design Tokens and Twind
What You’re Getting Into
A continuation of my series on design tokens. I recommend reading the previous article for context.
This is a very detailed explanation of how to use Style Dictionary to manage and export design tokens. I’ll explain what Style Dictionary is, what it does, and the technical details on how it’s implemented.
This is more of an explanation than a tutorial. A tutorial on implementing a style dictionary from a design file will be the next article in this series.
The Benefits of Managing and Exporting Design Tokens With a Management System
In my previous article, we defined design tokens as key-value pairs that represent the specs of a design system. I also alluded to the existence of tooling that can manage our design tokens and export them in a preferred format for the consuming platform and technology.
This tooling is impactful for three reasons.
First, by serving as a management system of design tokens, it serves as the source of truth for the coded implementation of specs. Whenever there is a translation from design documentation to code, there is the chance of making an error. By using a management system for design tokens, the translation from design documentation to code only occurs once. Without this tooling, the translation from design documentation to code would happen for every platform.
Second, not only does this tooling prevent errors, but it means that designers and developers can look to the management system of design tokens to determine what styles are being used across all applications (as opposed to having to check multiple places). This elevates the measure of trust in the quality and consistency of designs across applications.
Finally, it makes the design to code handoff much more efficient. If there is a change in the design system, there only needs to be a change in the management system of the design tokens. The applications that consume the exported design tokens of the management system will get the updates for free. Also, the tooling allows for auto-insertion of design tokens from design files (Sketch, Figma, etc.) and into the management system. 🎉
Pretty cool, huh?!
Let’s dive into getting started with a management system for design tokens.
What is a style dictionary?
In this article, I’ll show how we can use Amazon’s tool Style Dictionary for managing and exporting our design tokens.
I really like the term “style dictionary” because this captures both the technical and illustrative meaning of what we’re trying to achieve with a management system for design tokens.
If you’re familiar with a language like C#, then you’ll understand how “dictionary” has a technical significance. A dictionary is a collection of keys and values. In JavaScript, an object is the collection of keys and value, or “dictionary.” In fact, Style Dictionary manages your design tokens in JSON files.
If you’ve ever played Scrabble, you’ll know that a dictionary is very valuable. A dictionary, in human terms, is a collection of words and can settle whether that arrangement of Scrabble letters on the game board is a valid word or not.
Likewise, “dictionary” connotates the illustrative meaning that a style dictionary is a collection of design tokens representing the valid design specs and providing a single source of truth.
Managing and Exporting Design Tokens With Style Dictionary
Let me expand on how it is used for “managing” and “exporting” our design tokens.
How Does Style Dictionary “Manage” and “Export” Design Tokens?
At a minimum, it “manages” our design tokens by organizing them into collections of JSON files. Let’s look at an example. However, a style dictionary is even more powerful than just organizing the collections of JSON files. It also has the power to add a visual display on top of those JSON files to generate design documentation. This means by organizing our design tokens, we can generate a documentation website for a design system that can be referenced by both designers and developers.
Technically, you could also start with adding design tokens into the style dictionary and have it generate a design file. However, my hunch would be that the normative process would be to start with a design file in something like Sketch and Figma and then auto-import those styles into the style dictionary.
As for how the style dictionary “exports” our design tokens, I mean that it transforms them into the platform and technology-specific deliverables. Style Dictionary labels the defined “exports” as “transform groups.” The reason exports are labeled as “transform groups” is because under the hood, there are several transformations, or “transforms” as Style Dictionary labels them, that have to occur to transform design tokens into the deliverables. I’ll unpack the technical details of these transforms later on in this article.
Style Dictionary exposes pre-defined transform groups that will generate certain deliverables. Some of these pre-defined transform groups map directly to the name of a platform such as the “web”, “android” and “ios” groups. Others are deliverables that are tailored for a given platform but map to a specific technology within that platform such as the “css”, “scss”, and “less” groups that are used for the web platform.
This is very cool because it shows how a style dictionary stays platform and technology agnostic in its organization but doesn’t sacrifice the power of a given platform in its execution.
Not only does Style Dictionary expose pre-defined transform groups, but it also allows you to register custom transform groups by cherry-picking a chain of transforms you want to perform to create a deliverable. Even the transforms themselves can be custom-made! This makes Style Dictionary very powerful and flexible for the future, a big advantage over alternatives.
The Technical Implementation Behind Managing and Exporting Design Tokens With Style Dictionary
Ok, so I’ve provided a high-level overview of Style Dictionary. Namely, that it manages and categorizes design tokens via JSON files, and performs a chain of transforms to those JSON files (called a “transform group”) to export a deliverable.
Let’s unpack the technical details of each of those steps.
Managing and Categorizing Design Tokens With JSON Files
Each design token is a key-value pair representing a style, or a “spec.”
Now, these key-value pairs could be flat (there is no nesting):
"margin-small": "0.15"
If we transformed this token to JavaScript, we would get:
const MARGIN_SMALL = "0.15"
However, Style Dictionary recommends that you use nesting in a JSON object as a means of categorizing the design token.
They suggest using the “Category/Type/Item” (CTI) for structuring your object:
In this graphic, they include the optional “sub-item” and “state” properties in the hierarchy. We’ll get to that later. But as far as the “CTI” structure/hierarchy, I tend to think of it as reading a CSS class right-to-left.
Let’s say we have some CSS for a button with a background color of
white
:
button {
background-color: white;
}
If we read this class left-to-right minus the value (so to speak), we would get:
button --> background --> color
Notice, the order is the opposite of the “CTI” hierarchy shown in the graphic above.
If we read this class right-to-left, we would get:
color --> background --> button
The optional “sub-item” and “state” then come after the item,
button
in this case, giving us:
color --> background --> button --> primary --> active
“Sub-item” can be thought of as the “variants” of an item based on style and/or functionality and not a UI state.
For example, Material Design’s buttons have different variants, or sub-items of the button component, that serve different purposes:
“States” refer to the UI states of a component, such as “hover”, “disabled”, “focused”, and “normal”:
Following, the CTI hierarchy, we are eventually lead to a value. In our basic
example above, the button’s background color leads to a value of
white
. This entire hierarchy that leads to a
value, as represented in a JSON object, is our design token.
Style Dictionary labels them as “properties” but calls out “design token” as a synonym. I’ll continue to call them design tokens.
Since the recommended CTI structuring is a hierarchy and involves the nesting of properties, it is more of a chain of keys that lead to value rather than a simple key-value pair. Another way to think of it might be a list of descriptions leading to a value. I will continue to just call our design tokens a key-value pair to make it easier but I want to call to your attention how that is overly simplistic and maybe confusing when first seeing the CTI structure.
Let’s write out a JSON file with the CTI structure to define a design token to get more familiar.
Ok, we need to write some JSON to represent a design token we can derive from this design documentation:
Here is
Material Design’s definition of a “Raised Button”
that is a variant of a button. We’ll write a design token for the “focused”
state as opposed to the other states (“normal”, “pressed”, and “disabled”).
The value will be for the color of the text, the value being
gray
.
There are two ways we can go about this.
One, you can try to reference the CTI hierarchy graphic shown above and piece it together based on my description.
Or, if you’re a web developer, it might be natural to additionally use the right-to-left technique to get the category, item, and type and then tack on the sub-item and state.
Since most of the audience of this post are web developers, I’ll go with the second approach.
To do this, I’ll start off writing the CSS class without the sub-item and state:
button {
color: gray;
}
Reading right-to-left (minus the value), I’ll go left to right in my JSON nesting:
{
color: {
text: {
button: {
}
}
}
}
Adding the value may be a bit confusing at first. The value is represented like this:
{
"color": {
"text": {
"button": {
"value": "gray"
}
}
}
}
Referencing the CTI hierarchy graphic, I now insert sub-item and state
descriptions, or chain of keys, after the
text
and leading to the
value
:
{
"color": {
"text": {
"button": {
"raised": {
"focused": {
"value": "gray",
}
}
}
}
}
}
I recommend practicing creating these design tokens represented as JSON using the CTI structure. You could do this by referencing the Material Design “guidelines” for a component and deriving the spec (as we did in our example).
Keep in mind, however, that Style Dictionary has tooling that will generate these design tokens for us from a design file. We’ll do just that in the next article.
For now, let’s continue explaining the technical implementation of Style Dictionary by unpacking the concept of “transforms.”
Exporting Design Tokens With “Transforms”
Recall, Style Dictionary has the concept of “transforms” and “transform groups.” Transform groups are essentially the type of export you define for your design tokens. You export your design tokens into a platform deliverable (something an application on a given platform prefers to consume).
I tend to think of this as defining how you want to export images in a tool like Sketch:
By choosing a transform group, I’m saying “transform my design tokens into ___”. Just like I’d say in Sketch, “transform my images into JPGs.”
The transform group then performs “transforms” to transform your design tokens into ___.
For example, there is a pre-defined transform group for the JavaScript platform.
The documentation lists the transforms it performs to generate the platform deliverable.
First, it performs the
attribute/cti
transform which
adds a category, type, item, subitem, and state attribute based on
the nesting of our JSON file (as we just went over):
Second, it performs the
name/cti/pascal
transform which turns that
CTI attributes into a Pascal case name:
Third, it performs a size/rem
transform which
adds “rem” to the value in the design token if the category is size.
{ "value": "10" } --> "10rem"
Finally, it performs a color/hex
transform
which converts the value of the design token to a 6-digit hex if the category
is a color:
{ "value": "white" } --> "#ffffff"
If we ran this js
transform group against the
JSON object we created earlier, we would an output that looks something like
this:
export const COLOR_TEXT_BUTTON_RAISED_FOCUSED = '#808080';
Sweet! 🎉
Given the large list of pre-defined transforms and transform groups, there is so much potential and flexibility as far as what platform deliverables you can create using Style Dictionary.
I recommend reading the official documentation to get a sense of what we might be export.
Conclusion
So far, we’ve gotten a detailed explanation of what Style Dictionary works and what the technical details of its implementation are.