npm package: @quartzds/style-dictionary-extensions
Description: Style Dictionary extensions and helpers for the Quartz design tokens
Latest version: 2.1.1

---
SPDX-FileCopyrightText: © 2025 Schneider Electric

SPDX-License-Identifier: Apache-2.0
---

# Style Dictionary extensions for the Quartz design tokens

[![CI Status][ci-badge]][ci-status] [![NPM Package][npm-badge]][npm-link]
[![License][license-badge]][license]
[![REUSE status][reuse-badge]][reuse-status]

## 💡 Overview

This package provides extensions and helper functions to transform Quartz design
tokens into resources for developers using [Style Dictionary][]. Those design
tokens are edited using the [Tokens Studio Figma plugin][].

### Prerequisites

- A hierarchy of JSON files produced by the [Tokens Studio Figma plugin][] in
  the "legacy" format (do **not** enable the DTCG format in the Figma plugin).
- node `^18.0.0 || >=20.0.0`

### Token transformation rules

Translating design tokens into platform-specific assets requires rules. Quartz
uses
[specific rules](https://github.com/quartzds/general/wiki/Tokens-transformation-rules)
based on its own conventions. The goal of this library is to package all those
transformation rules into a convenient API for [Style Dictionary][].

### Supported platforms

- CSS

Experimental support:

- Android
- Swift
- XAML

Coming later:

- JavaScript
- TypeScript

## 💿 Installation

```bash
npm install @quartzds/style-dictionary-extensions
```

## 📖 Usage

Create a build script that will configure and run [Style Dictionary][] to output
tokens to several formats, using the helpers provided by this package. See the
[Transformation rules][docs] page for the list of transformations provided for
each target format.

The general algorithm is as follows:

1. Create a base `StyleDictionary` object, pre-configured with Quartz's custom
   transforms.
2. For every token set you want to export (desktop, tablet, mobile, dark, light,
   etc.):
   - create a Style Dictionary `Config` object using the helpers from this
     package
   - call the `extend(config)` method of the base `StyleDictionary` object to
     get a new instance from a specific configuration
   - let that Style Dictionary instance generate the files using the
     `buildAllPlatforms()` function

### Get a base `StyleDictionary` object

The `getPresetStyleDictionary()` function registers Quartz extensions and
returns a fresh [Style Dictionary][] instance to use as the base to export to
one or more formats:

```ts
import { getPresetStyleDictionary } from '@quartzds/style-dictionary-extensions'

const baseSD = await getPresetStyleDictionary()
```

### Create Style Dictionary configurations

This package provides [transform groups][] for supported target formats, as well
as helper functions to help you set up Style Dictionary configuration objects.

Use the `get<Format>PlatformConfig(sourceType, destination, options?)` functions
to get ready-made `PlatformConfig` objects to use in your Style Dictionary
`Config` object:

```ts
import {
  getAndroidPlatformConfig,
  getCSSPlatformConfig,
  getSwiftPlatformConfig,
} from '@quartzds/style-dictionary-extensions'

const sdConfig = {
  platforms: {
    android: getAndroidPlatformConfig(...),
    css: getCSSPlatformConfig(...),
    swift: getSwiftPlatformConfig(...),
  },
  ...other config properties...
},
```

### Run Style Dictionary generation

Finally, let Style Dictionary build all the platforms for your configuration
objects:

```ts
var sd = baseSD.extend(desktopConfig)
sd.buildAllPlatforms()

sd = baseSD.extend(lightThemeConfig)
sd.buildAllPlatforms()

// etc.
```

## 📓 Simple example

This example assumes the following structure of design tokens files generated by
the [Tokens Studio Figma plugin][]:

```text
src/
└── tokens
    ├── private.json <-- don't export these tokens (internal bindings)
    ├── platform
    │   ├── desktop.json
    │   └── mobile.json
    └── theme
        ├── dark.json
        └── light.json
```

We want to transform these tokens into the following platform-specific assets:

```text
dist/
├── platform
│   ├── desktop.css
│   ├── desktop.swift
│   ├── desktop.xml
│   └── mobile.css
│   └── mobile.swift
│   └── mobile.xml
└── theme
    ├── dark.css
    ├── dark.swift
    ├── dark.xml
    └── light.css
    └── light.swift
    └── light.xml
```

Here is the script to achieve that:

```ts
import {
  getAndroidPlatformConfig,
  getCSSPlatformConfig,
  getPresetStyleDictionary,
  getSwiftPlatformConfig,
  SourceType,
} from '@quartzds/style-dictionary-extensions'
import type { Config, FileHeader } from 'style-dictionary/types'

const baseSD = await getPresetStyleDictionary()

const copyrightFileHeader: FileHeader = (defaultMessage, options) => (...)

const lightThemeConfig: Config = {
  platforms: {
    android: getAndroidPlatformConfig(
      SourceType.theme,
      `dist/theme/light.xml`,
      {
        fileHeader: copyrightFileHeader,
      },
    ),
    css: getCSSPlatformConfig(
      SourceType.theme,
      `dist/theme/light.css`,
      {
        fileHeader: copyrightFileHeader,
        selector: '.qds-theme-light',
      },
    ),
    swift: getSwiftPlatformConfig(
      SourceType.theme,
      `dist/theme/light.swift`,
      {
        fileHeader: copyrightFileHeader,
        className: 'Light',
      },
    ),
  },

  include: [`./tokens/private.json`],
  source: [`./tokens/theme/light.json`],
}

const darkThemeConfig: Config = {
  /* ... */
}

const desktopConfig: Config = {
  /* ... */
}

const mobileConfig: Config = {
  /* ... */
}

const allConfigs = [
  lightThemeConfig,
  darkThemeConfig,
  desktopConfig,
  mobileConfig,
]

for (const config of allConfigs) {
  const sd = StyleDictionary.extend(config)
  sd.cleanAllPlatforms() // Optional
  sd.buildAllPlatforms()
}
```

## ⚖️ License

See the [LICENSE][] file for license rights and limitations.

[Style Dictionary]: https://amzn.github.io/style-dictionary/
[Tokens Studio Figma plugin]: https://tokens.studio/
[transform groups]:
  https://styledictionary.com/reference/hooks/transform-groups/
[ci-badge]:
  https://github.com/quartzds/style-dictionary-extensions/actions/workflows/ci.yml/badge.svg
[ci-status]:
  https://github.com/quartzds/style-dictionary-extensions/actions/workflows/ci.yml
[npm-badge]:
  https://img.shields.io/npm/v/@quartzds/style-dictionary-extensions?logo=npm
[npm-link]: https://www.npmjs.com/package/@quartzds/style-dictionary-extensions
[license-badge]:
  https://img.shields.io/npm/l/@quartzds/style-dictionary-extensions?logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCI+PHBhdGggZD0ibTIzLjkgOS43LTMuNTQtNy44OS0uMDA1LS4wMWEuNTQyLjU0MiAwIDAgMC0uMDQxLS4wNzZsLS4wMTQtLjAxOGEuNTMzLjUzMyAwIDAgMC0uMTIyLS4xMjJsLS4wMTUtLjAxMWEuNTI4LjUyOCAwIDAgMC0uMDgtLjA0NGwtLjAyNC0uMDA5YS41MjcuNTI3IDAgMCAwLS4wNjctLjAybC0uMDI4LS4wMDdhLjUyNC41MjQgMCAwIDAtLjA5Ni0uMDFoLTYuODVjLTEuMDItMS41Mi0xLjAyLTEuNTQtMiAwaC02Ljg2YS41NDMuNTQzIDAgMCAwLS4wOTYuMDFsLS4wMjguMDA3YS41MTYuNTE2IDAgMCAwLS4wNjcuMDJsLS4wMjQuMDFhLjUzNy41MzcgMCAwIDAtLjA4LjA0M2wtLjAxNS4wMTFhLjUxLjUxIDAgMCAwLS4wNTcuMDQ3bC0uMDIuMDJhLjU0My41NDMgMCAwIDAtLjA0NS4wNTVsLS4wMTQuMDE4YS41MjIuNTIyIDAgMCAwLS4wNDEuMDc1bC0uMDA1LjAxdi4wMDFMLjExNiA5LjcyYS41MzEuNTMxIDAgMCAwLS4wOTYuMzA0YzAgMi4yOCAxLjg2IDQuMTQgNC4xNCA0LjE0czQuMTQtMS44NiA0LjE0LTQuMTRhLjUzLjUzIDAgMCAwLS4wOTYtLjMwNGwtMy4yNS02LjM3IDYuMDctLjAyM3YxOC4yYy0yLjU1LjI5NC03LjAxLjM4MS03IDIuNWgxNmMwLTIuMDMtNC40OC0yLjI3LTctMi41di0xOC4xbDUuNjktLjAyLTIuOTIgNi40OWMwIC4wMDIgMCAuMDAzLS4wMDIuMDA1bC0uMDA2LjAxOGEuNTQ1LjU0NSAwIDAgMC0uMDIzLjA3NWwtLjAwNS4wMmEuNTI0LjUyNCAwIDAgMC0uMDEuMDkydi4wMDhjMCAyLjI4IDEuODYgNC4xNCA0LjE0IDQuMTQgMi4yOCAwIDQuMTQtMS44NiA0LjE0LTQuMTRhLjUyOC41MjggMCAwIDAtLjEyLS4zMzJ6IiBmaWxsPSIjZmZmIj48L3BhdGg+PC9zdmc+
[license]: LICENSE
[reuse-badge]:
  https://api.reuse.software/badge/github.com/quartzds/style-dictionary-extensions
[reuse-status]:
  https://api.reuse.software/info/github.com/quartzds/style-dictionary-extensions
[docs]: docs/transformation-rules.md