Specify VS Style Dictionary
Tags: designtokens, devops, tooling, tutorial
Published: 2022-10-25 09:57:15

I'm often asked: "What's the difference between Specify and Style Dictionary?". My answer is always the same: "Yes, they look alike, and Specify is not meant to replace Style Dictionary: it actually enhances it.".

Let's see why together.

This article helps you understand:
- differences between Specify and Style Dictionary
- how to couple them to generate design tokens and assets

Style Dictionary and Specify are both design tokens generators, and you can use them to generate design tokens and assets respecting your company standards.

## What is Style Dictionary?
Created by Danny Banks in 2017, Style Dictionary is a build system that allows you to generate styles for any platform from static design tokens in an agnostic format (e.g., JSON).

For instance, you can feed Style Dictionary with raw colors in JSON and configure it to generate colors in specific formats for different platforms like Android (e.g., Kotlin), iOS (e.g., Swift), or Web (e.g., Sass).

![How Style Dictionary generates design tokens](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jg4tb348ov2yitevhdzb.jpg)

Style Dictionary is open source and available through a CLI or a node module.

### Style Dictionary generates design data

Style Dictionary provides out-of-the-box [transforms functions](https://amzn.github.io/style-dictionary/#/transforms) to help you create and transform design tokens. Transforms are functions that range from converting colors to `HSL`, converting dimension design tokens from `rem` to `dp`, or even converting an image in `base64`.

In short, Style Dictionary helps you transform your design tokens to make them compatible with your company standards.

### But Style Dictionary doesn't sync your design data

Keeping design data up-to-date at scale means transforming your design tokens for target platforms **every time a design token is updated**.

![Design tokens used by Style Dictionary need to be updated](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/68ulw37yigqkc2rjjlx5.jpg)

Style Dictionary helps with the transformation part, but you still need to run it every time your design tokens get updated.

### See for yourself
First of all, let's install Style Dictionary in our directory: `yarn add style-dictionary`.

Now, let's generate our design tokens, shall we!

{% embed https://www.loom.com/share/3f3e5f4855bd4557bca0a970c5c7b186 %}

```
yarn run style-dictionary init basic
```

This command generates:
1. A `tokens` folder containing agnostic colors and sizes
2. A Style Dictionary configuration file: `config.json`
3. Our design tokens in Swift, Objective C, XML, Kotlin and SCSS in a `build` folder
4. A `README.md` file describing us what this configuration is doing


#### Want to know more about this command?
Check out [the official examples projects](https://github.com/amzn/style-dictionary/tree/442a5eccf5eb18edae7877ff96712d189316a6dd/examples) provided by Style Dictionary. In our case, we just used the `basic` example 👍

Style Dictionary helps you generate and transform your design tokens. But **you still need to run Style Dictionary every time they get updated**.

## Why Specify and Style Dictionary make the perfect match

Specify is a Design API that helps you collect design data from Figma and distribute it in the right format, in the right project, at the right time, and to top it all: automatically.

Let's focus on the "distribution" part. Like Style Dictionary, Specify helps you generate design data for any target platforms.

By default Specify returns design data in JSON but thanks its [open source parsers](https://github.com/Specifyapp/parsers/) you can transform your design data in any formats. I repeat, in **any formats**.

Are you starting to see where I'm going here?

Specify can generate design tokens compatible with Style Dictionary. The same ones you feed Style Dictionary with. And as good things come in pairs, Specify automatically detects updates coming Figma and updates agnostic design tokens consumed by Style Dictionary.

![Specify syncs your design tokens so Style Dictionary can transform them afterwards](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b3x0x4jn78rzuvm6t3h7.jpg)

## Working example
This example project will help you understand how to use Specify and Style Dictionary together.

Please make sure you already have synchronized design tokens in a Specify repository. Want to learn more about this? [Watch this 3min tutorial](https://www.youtube.com/watch?v=ylKuC8uJdRk) 🎬

From there, we will:
1. Pull design data from Specify and generate agnostic design tokens compatible with Style Dictionary
2. Run Style Dictionary and generate design tokens for iOS, Android, and Web

Specify and Style Dictionary are both flexible and powerful generators. However, we must configure them so they understand what to generate for us.


### From Specify to Style Dictionary
Let's start by pulling our design data from Specify in our project. The "project" I'm referring to is a directory called `your-project`.

We will use the Specify CLI to pull design data programmatically from a local directory.

![Specify generates design tokens for Style Dictionary from your Specify repositories](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i6lppstlfre9dmd8vtlp.jpg)

Let's install it by running in the terminal: `yarn add @specify/cli`.

If things went well you should have the following help menu displayed after running the following command: `specify`.

![Specify CLI main commands](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nnv6alk7ne74fp30hnpd.jpg)

Instead of manually configuring Specify, we will ask Specify to generate a working [configuration designed for Style Dictionary](https://specifyapp.com/templates/style-dictionary-for-android).

Under the hood, this configuration is mostly using the [to-style-dictionary](https://github.com/Specifyapp/parsers/tree/master/parsers/to-style-dictionary) parser.

Here's a short video showing how Specify can generate design tokens compatible with Style Dictionary:

{% embed https://www.loom.com/share/42354190c3b247d8b600bf98df3a5d28 %}


Let's break down what we just did here:
1. We created a Specify configuration file tailored for Style Dictionary with the command `specify init`
2. We finalized the configuration by updating the Specify repository and our `personalAccessToken`
3. We pulled our design tokens and assets with the command `specify pull`.

Which generated the following files:
```bash
🗂 output
├── 🗂 tokens
|   ├── 🗂 color
|   |   └── base.json
|   └── 🗂 asset
|       └── font.json
|       └── icon.json
└── 🗂 assets
    ├── 🗂 fonts
    └── 🗂 vectors
```

What now? Now we've generated agnostic colors, icons and font files, it's time to transform them with Style Dictionary.


### From Style Dictionary to target platforms

Here's the following workflow we want to setup:

![Style Dictionary generates design tokens to target platforms from agnostic design tokens](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/83wuq037kmqgqjc1s7jx.jpg)

Now we have agnostic design tokens at hand let's configure Style Dictionary to transform them.


#### Remove example tokens and use the ones coming from Specify

Instead of writing our configuration from scratch we'll update the one Style Dictionary generated for us with the `init` command. We want Style Dictionary to run our config against tokens located in the `output/` folder Specify generated.

#### Update the Style Dictionary config file

Our `config.json` file becomes:
```json
{
  "source": ["output/**/*.json"],
  "platforms": {
    "scss": {
      "transformGroup": "scss",
      "buildPath": "build/scss/",
      "files": [{
        "destination": "_variables.scss",
        "format": "scss/variables"
      }]
    },
    "android": {
      "transformGroup": "android",
      "buildPath": "build/android/",
      "files": [{
        "destination": "font_dimens.xml",
        "format": "android/fontDimens"
      },{
        "destination": "colors.xml",
        "format": "android/colors"
      }]
    },
    "compose": {
      "transformGroup": "compose",
      "buildPath": "build/compose/",
      "files": [{
        "destination": "StyleDictionaryColor.kt",
        "format": "compose/object",
        "className": "StyleDictionaryColor",
        "packageName": "StyleDictionaryColor",
        "filter": {
          "attributes": {
            "category": "color"
          }
        }
      },{
        "destination": "StyleDictionarySize.kt",
        "format": "compose/object",
        "className": "StyleDictionarySize",
        "packageName": "StyleDictionarySize",
        "type": "float",
        "filter": {
          "attributes": {
            "category": "size"
          }
        }
      }]
    },
    "ios": {
      "transformGroup": "ios",
      "buildPath": "build/ios/",
      "files": [{
        "destination": "StyleDictionaryColor.h",
        "format": "ios/colors.h",
        "className": "StyleDictionaryColor",
        "type": "StyleDictionaryColorName",
        "filter": {
          "attributes": {
            "category": "color"
          }
        }
      },{
        "destination": "StyleDictionaryColor.m",
        "format": "ios/colors.m",
        "className": "StyleDictionaryColor",
        "type": "StyleDictionaryColorName",
        "filter": {
          "attributes": {
            "category": "color"
          }
        }
      },{
        "destination": "StyleDictionarySize.h",
        "format": "ios/static.h",
        "className": "StyleDictionarySize",
        "type": "float",
        "filter": {
          "attributes": {
            "category": "size"
          }
        }
      },{
        "destination": "StyleDictionarySize.m",
        "format": "ios/static.m",
        "className": "StyleDictionarySize",
        "type": "float",
        "filter": {
          "attributes": {
            "category": "size"
          }
        }
      }]
    },
    "ios-swift": {
      "transformGroup": "ios-swift",
      "buildPath": "build/ios-swift/",
      "files": [{
        "destination": "StyleDictionary+Class.swift",
        "format": "ios-swift/class.swift",
        "className": "StyleDictionaryClass",
        "filter": {}
      },{
        "destination": "StyleDictionary+Enum.swift",
        "format": "ios-swift/enum.swift",
        "className": "StyleDictionaryEnum",
        "filter": {}
      },{
        "destination": "StyleDictionary+Struct.swift",
        "format": "ios-swift/any.swift",
        "className": "StyleDictionaryStruct",
        "filter": {},
        "options": {
          "imports": "SwiftUI",
          "objectType": "struct",
          "accessControl": "internal"
        }
      }]
    },
    "ios-swift-separate-enums": {
      "transformGroup": "ios-swift-separate",
      "buildPath": "build/ios-swift/",
      "files": [{
        "destination": "StyleDictionaryColor.swift",
        "format": "ios-swift/enum.swift",
        "className": "StyleDictionaryColor",
        "filter": {
          "attributes": {
            "category": "color"
          }
        }
      },{
        "destination": "StyleDictionarySize.swift",
        "format": "ios-swift/enum.swift",
        "className": "StyleDictionarySize",
        "filter": {
          "attributes": {
            "category": "size"
          }
        }
      }]
    }
  }
}
```

#### Generate tokens for target platforms-
Now if we run `yarn run style-dictionary build` we see our colors, vectors and font files transformed for our target platforms.

{% embed https://www.loom.com/share/9027f543c19f40c6b5aee2e8c698efd7 %}

Did you see the magic happen here?

The `config.json` is composed of two main properties:
1. The `source` property tells Style Dictionary where to look for design tokens (in our case the `output` folder)
2. The `platforms` property tells Style Dictionary how to transform our design tokens

## Let's sum things up

![How Specify and Style Dictionary work with each other](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qps2bcpf7mbtfjlvz77d.jpg)

We just saw how Specify generates design tokens for Style Dictionary while keeping them up-to-date.

Specify helps you generate design tokens that are always updated so you can transform them with Style Dictionary. Specify doesn't replace Style Dictionary. It enhances it.

In our working example we used the Specify CLI and executed Style Dictionary in a local directory. However, you could totally set this workflow in a GitHub repository thanks to a GitHub Action. But this is for another blog post.

Cheers ✌️