Specify VS Style Dictionary

chuckn0risk

Louis Chenais

Posted on October 25, 2022

Specify VS Style Dictionary

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

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 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

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!


yarn run style-dictionary init basic
Enter fullscreen mode Exit fullscreen mode

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 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 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

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 šŸŽ¬

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

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

Instead of manually configuring Specify, we will ask Specify to generate a working configuration designed for Style Dictionary.

Under the hood, this configuration is mostly using the to-style-dictionary parser.

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

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:

šŸ—‚ output
ā”œā”€ā”€ šŸ—‚ tokens
|   ā”œā”€ā”€ šŸ—‚ color
|   |   ā””ā”€ā”€ base.json
|   ā””ā”€ā”€ šŸ—‚ asset
|       ā””ā”€ā”€ font.json
|       ā””ā”€ā”€ icon.json
ā””ā”€ā”€ šŸ—‚ assets
    ā”œā”€ā”€ šŸ—‚ fonts
    ā””ā”€ā”€ šŸ—‚ vectors
Enter fullscreen mode Exit fullscreen mode

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

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:

{
  "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"
          }
        }
      }]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

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.

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

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 āœŒļø

šŸ’– šŸ’Ŗ šŸ™… šŸš©
chuckn0risk
Louis Chenais

Posted on October 25, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Specify VS Style Dictionary
designtokens Specify VS Style Dictionary

October 25, 2022