Always Twisted

A Design Tokens Workflow (part 1)

Getting Started With Style Dictionary

  1. Getting Started With Style Dictionary – You are here
  2. Outputting to Different Formats with Style Dictionary
  3. Beyond JSON: Exploring File Formats for Design Tokens
  4. Converting Tokens with Style Dictionary
  5. Organising Outputs with Style Dictionary
  6. Layers, referencing tokens in Style Dictionary
On This Page:

What are Design Tokens

Design Tokens have become a widely-adopted method to store design decisions (such as colours, typography, spacing, border-radius, and other visual properties) across products, applications, and websites.

They help create a shared language between design and development (and beyond), ensuring consistency across a digital product’s design and implementation.

By converting these design decisions into platform-specific formats (like CSS variables for the web or XML for Android), design tokens ensure that your visual guidelines are accurately applied no matter where they are used.

To do this efficiently, we can use tools that automate the process. Style Dictionary is one popular open-source tool that can be used to take Design Tokens in a .json format and generate relevant, specific files for your needs. There are also other tools, such as Theo, Thing1, Thing2, and Thing3.

In this tutorial, and for future ones, I’ll be using Style Dictionary. I have created a git repository that will include the end results.

Initial setup

To get started, you’ll need to install Style Dictionary. It can either be installed globally:

Code languagebash
npm install -g style-dictionary

Or it can be installed as a dependency of your project. It is most likely that you would install Style Dictionary this way:

Code languagebash
npm install -D style-dictionary

We can create a new folder (project) and open it with our text editor to get started.

As we will be using npm we will need to initialise this in the project and fill out any relevant questions posed in the terminal.

Code languagebash
npm init

We should then have a new package.json and package-lock.json file. The package.json file could look something like this:

Code languagebash
{
  "name": "style-dictionary-starter",
  "version": "0.1.0",
  "devDependencies": {
    "style-dictionary": "^4.1.4"
  }
}

Creating a build script

To get Style Dictionary to create the files we need we need to create a build script. To start with in this series we are going to have a small set of example Design Tokens in .json that we are going to use to create a CSS file of CSS custom properties.

Here's the full build script:

Code languagejs
import StyleDictionary from 'style-dictionary';
const myStyleDictionary = new StyleDictionary({
source: [`src/tokens/**/*.json`],
platforms: {
css: {
transformGroup: 'css',
buildPath: 'build/',
files: [
{
destination: 'variables.css',
format: 'css/variables',
},
],
},
},
});
await myStyleDictionary.buildAllPlatforms();

Let's go through this, line by line to see what the script is doing.

Code languagejs
import StyleDictionary from 'style-dictionary';

Imports Style Dictionary to process tokens.

Code languagejs
const myStyleDictionary = new StyleDictionary({

Creates a new instance of StyleDictionary using a configuration object which will handle the processing and building of the design tokens based on the provided settings.

Code languagejs
source: [src/tokens/**/*.json],

Specifies the location of the design token files. The pattern **/*.json tells Style Dictionary to look for any .json files in the directory and its sub directories.

Code languagejs
platforms: {

Begins the configuration for different platforms. Each platform defines how and where the design tokens should be transformed and outputted to.

Code languagejs
css: {

Defines a platform named css. This platform will transform the design tokens into a format suitable for CSS usage.

Code languagejs
transformGroup: 'css',

Specifies the transform group css. This group tells Style Dictionary to use a set of predefined transforms that convert tokens to CSS-compatible values.

Code languagejs
buildPath: 'build/',

Sets the output directory to build/. The processed files generated by Style Dictionary will be placed in this directory.

Code languagejs
files: [
{
destination: 'variables.css',
format: 'css/variables',
},
],

This array defines the files that will be generated. Each object in this array represents a separate output file. This specific object configures a file named variables.css:

Code languagejs
destination: 'variables.css',

Sets the file name.

Code languagejs
format: 'css/variables',

This tells Style Dictionary to convert the design tokens into CSS custom properties.

Code languagejs
await myStyleDictionary.buildAllPlatforms();

Asynchronously builds the design tokens for all defined platforms. In this example, it processes the tokens and generates the variables.css file in the build/ directory based on the configuration provided.

Updating our package.json

We can then add a "build": "node build.js" to the package.json to allow us to use the command npm run build to run Style Dictionary and build out the files specified.

Code languagebash
{
"name": "style-dictionary-starter",
"version": "0.1.0",
"type": "module",
"scripts": {
"build": "node build.js"
},
"devDependencies": {
"style-dictionary": "^4.1.4"
}
}

Creating some tokens

Running npm run build now runs the build.js code but we do not get a variables.css file in the build folder because we haven't created any .json files.

Here is an example to demonstrate how to structure Design tokens in .json.

Code languagejson
{
"color": {
"$type": "color",
"primary": {
"$value": "#007bff"
},
"secondary": {
"$value": "#6c757d"
}
},
"spacing": {
"$type": "spacing",
"none": {
"$value": "0"
},
"small": {
"$value": "0.5rem"
},
"medium": {
"$value": "1rem"
}
},
"typography": {
"font": {
"family": {
"$type": "fontFamily",
"body": {
"$value": "Roboto, sans-serif"
}
},
"size": {
"$type": "fontSize",
"base": {
"$value": "1rem"
},
"lg": {
"$value": "1.25rem"
}
}
}
}
}

In this example we are defining tokens for colour, spacing and typography. Style Dictionary will traverse the file and create CSS custom properties following the tree in the .json.

You will notice that I am including a $type for each, or each group of tokens. Using $type tells Style Dictionary what kind of value it is dealing with allowing it to apply any built-in transformations (for example, a color token can undergo a conversion from the HEX value that is written to an RGB value if instructed to). Adding $type can also create consistent formatting across platforms, it can be used in validation and error handling, it can also be used if you define any custom transformations, like converting the fontWeight from 400 to regular if you needed it to.

When running npm run build which runs the build.js file Style Dictionary will create --color-primary: #007bff; from the following.

Code languagejson
{
"color": {
"$type": "color",
"primary": {
"$value": "#007bff"
}
}
}

The full variables.css file will be outputted to this:

Code languagecss
/**
* Do not edit directly, this file was auto-generated.
*/
:root {
--color-primary: #007bff;
--color-secondary: #6c757d;
--spacing-none: 0;
--spacing-small: 0.5rem;
--spacing-medium: 1rem;
--typography-font-family-body: Roboto, sans-serif;
--typography-font-size-base: 1rem;
--typography-font-size-lg: 1.25rem;
}

Generating Sass Variables

Now that we have this working, we can add another platform for Style Dictionary to generate code from. Let's get it to create Sass variables in a new .scss file. We need to add some more code to the build.js to get this to work.

Code languagejs
scss: {
transformGroup: 'scss',
buildPath: 'build/',
files: [
{
destination: '_variables.scss',
format: 'scss/variables',
},
],
}

So the full build.js code will look like this:

Code languagejs
import StyleDictionary from 'style-dictionary';
const myStyleDictionary = new StyleDictionary({
source: [`src/tokens/**/*.json`],
platforms: {
css: {
transformGroup: 'css',
buildPath: 'build/',
files: [
{
destination: 'variables.css',
format: 'css/variables',
},
],
},
scss: {
transformGroup: 'scss',
buildPath: 'build/',
files: [
{
destination: '_variables.scss',
format: 'scss/variables',
},
],
},
},
});
await myStyleDictionary.buildAllPlatforms();

Running npm run build will now generate the variables.css file as well as a new _variables.scss file that will look like this:

Code languagescss
// Do not edit directly, this file was auto-generated.
$color-primary: #007bff;
$color-secondary: #6c757d;
$spacing-none: 0;
$spacing-small: 0.5rem;
$spacing-medium: 1rem;
$typography-font-family-body: Roboto, sans-serif;
$typography-font-size-base: 1rem;
$typography-font-size-lg: 1.25rem;

Where we're at, and where can we go to

We have explored the basics of setting up Style Dictionary to generate CSS custom properties and Sass variables from design tokens. Covering how design tokens help maintain consistency across platforms by acting as a shared source of truth for your design decisions.

In automating the conversion of tokens into platform-specific formats, Style Dictionary streamlines workflows, reduces errors, and ensures that design guidelines can be implemented accurately and efficiently.

Using a tool like Style Dictionary to automate the process of generating styles means you can be confident that your design tokens will always be up-to-date across all platforms. It can simplify the collaboration between designers and developers by providing a unified, consistent source of truth for visual properties, leading to a more cohesive and polished final product.

Now that we’ve seen how to get started with Style Dictionary, there’s much more you can explore. In future articles, we’ll dive deeper into more advanced configurations.

I encourage you to check out the Style Dictionary documentation to learn about its extensive capabilities. You can also explore the example code on my GitHub repository to see the end results and experiment with your own setups.

Need to integrate design tokens into your build tools or component libraries?

I’ll integrate tokens into your build process and component libraries for smooth workflows.

get in touch!