Tool review6 min read

Style Dictionary 5 for React Native and web teams: our review

What Style Dictionary does well, where it still lags the 2025.10 token spec, a working config for CSS variables plus a React Native module, and when we would pick something else.

A neat grid of small cubes shading from white to graphite, with a single lavender cube near the top.
Generated for Ainur Design

Most teams that ship a React Native app next to a web product end up with the same problem: the same blue lives in a CSS file, a TypeScript theme object and a Figma library, and the three drift apart within a quarter. Design tokens fix that only if something turns one source file into the code each platform actually uses.

Style Dictionary is the tool we reach for first for that job. It started at Amazon, now lives in its own open-source GitHub organisation, and is one of the reference implementations named when the W3C Design Tokens Community Group (DTCG) published its first stable format. This review covers the current major version, 5, from the point of view of a team shipping React Native plus web.

What it does

Style Dictionary reads token files (JSON, JSON5 or JavaScript), merges them into one tree, resolves references such as {color.blue.500}, and then runs each platform in your config. A platform is a list of transforms (change a token's name or value, for example camelCase names or px to rem) and one or more formats (write the result as CSS variables, an ES module, Swift, Kotlin and so on).

That model is the reason it has lasted. The core does very little that is opinionated; nearly everything is a named hook you can swap or extend. The built-in catalogue covers CSS, SCSS, Less, JavaScript, TypeScript declarations, Android XML, Jetpack Compose, iOS Swift and Flutter, plus a react-native transform group.

What changed in v4 and v5

If your last look at Style Dictionary was v3, the API you remember is gone. Version 4 (June 2024) was a rewrite, and version 5 (May 2025) tightened it further. The changes that matter in practice:

ChangeVersionWhat it means for you
ES modules onlyv4Your build script is an .mjs file or lives in a "type": "module" package. CommonJS projects need a dynamic import().
Class and async APIv4new StyleDictionary(config), then await sd.buildAllPlatforms(). Hooks can be async too.
Hooks renamed and groupedv4Custom code goes under hooks.transforms, hooks.formats and friends; transformer became transform, matcher became filter.
First-class DTCG formatv4$value, $type and $description work out of the box, and $type set on a group is inherited by its tokens.
No more CTI dependencyv4Built-in transforms read the token's type instead of guessing from a category/type/item path.
Node 22 minimumv5CI images and local machines need Node 22 or newer.
Stricter referencesv5References must point at a token, not at a group or a sub-property, and the { } syntax is fixed to match the DTCG spec.
2025.10 colour objectsv5.3Colour transforms accept { colorSpace, components, alpha, hex } across all 14 DTCG colour spaces, with new color/oklch, color/p3 and similar outputs.
2025.10 dimension objectsv5.4Dimension tokens can be { value, unit } objects, and the CSS shorthand transforms for shadow, border and typography handle them.

A config that produces CSS variables and a React Native module

Here is the smallest setup we would actually ship. One token file in DTCG 2025.10 syntax: a primitive blue, a semantic alias that points at it, and a spacing pair.

{
  "color": {
    "$type": "color",
    "blue": {
      "500": {
        "$value": { "colorSpace": "srgb", "components": [0.15, 0.39, 0.92], "hex": "#2663eb" }
      }
    },
    "action": {
      "primary": { "$value": "{color.blue.500}", "$description": "Main call-to-action fill" }
    }
  },
  "space": {
    "$type": "dimension",
    "md": { "$value": { "value": 16, "unit": "px" } },
    "card": { "$value": "{space.md}" }
  }
}

The build script defines one custom transform, because React Native styles take plain numbers rather than 16px strings. Everything else is built in. Note there is no usesDtcg flag: Style Dictionary detects the $value syntax on its own.

// build.mjs (run with Node 22+)
import StyleDictionary from 'style-dictionary';

// React Native wants unitless numbers (density-independent pixels).
StyleDictionary.registerTransform({
  name: 'size/rn-number',
  type: 'value',
  filter: (token) => token.$type === 'dimension',
  transform: (token) => {
    const v = token.$value;
    return typeof v === 'object' ? v.value : parseFloat(v);
  },
});

const sd = new StyleDictionary({
  source: ['tokens/**/*.json'],
  platforms: {
    css: {
      transformGroup: 'css',
      buildPath: 'dist/web/',
      files: [{
        destination: 'tokens.css',
        format: 'css/variables',
        options: { outputReferences: true },
      }],
    },
    rn: {
      transforms: ['name/camel', 'color/hex', 'size/rn-number'],
      buildPath: 'dist/native/',
      files: [
        { destination: 'tokens.js', format: 'javascript/es6' },
        { destination: 'tokens.d.ts', format: 'typescript/es6-declarations' },
      ],
    },
  },
});

await sd.buildAllPlatforms();

Running node build.mjs against Style Dictionary 5 gives this output (file banners trimmed). The CSS keeps the alias chain as var() references because of outputReferences, which makes theme overrides cheap. The React Native module gets resolved values and a .d.ts file typing the colours as string and the spacing as number.

/* dist/web/tokens.css */
:root {
  --color-blue-500: #2663eb;
  --space-md: 16px;
  --color-action-primary: var(--color-blue-500); /** Main call-to-action fill */
  --space-card: var(--space-md);
}

// dist/native/tokens.js
export const colorBlue500 = "#2663eb";
export const colorActionPrimary = "#2663eb"; // Main call-to-action fill
export const spaceMd = 16;
export const spaceCard = 16;

We deliberately do not use the built-in react-native transform group for spacing. Its size/object transform turns 10px into an object with original, number, decimal and scale keys, which is flexible but means every style has to reach into .number. A three-line custom transform gives engineers the value they expect.

Where it is strong

  • Extensibility without forking. Transforms, formats, filters, parsers, preprocessors and actions are all plain functions. When a platform needs something odd (a NativeWind theme, a Tailwind preset, an Android colors.xml), we write a format, not a fork.
  • Reference handling. outputReferences keeps aliases as CSS custom properties, so a dark theme can override the semantic layer only. Few tools get this right.
  • Breadth of outputs. One config can cover web, React Native, native iOS and Android, which matters when a client later adds a native widget or watch app.
  • Typed output. The TypeScript declaration formats mean a renamed token breaks the build instead of silently falling back to undefined.
  • It is the default. Tokens Studio, Figma exports and most token tutorials assume Style Dictionary, so new hires have usually seen it.

Where it is weak

  • Themes are your problem. Light/dark and multi-brand builds are usually one Style Dictionary instance per theme, driven by a loop in your build script. It works, but you design the folder layout and the merge rules yourself until resolver support lands.
  • Composite tokens on native. The CSS shorthand transforms for typography and shadow are good. On React Native you still write your own format to turn a typography token into a style object and a shadow into platform-specific shadow props.
  • Migration cost. v3 to v4 touched every custom hook; v4 to v5 is described in the docs as close to drop-in, but the reference rules changed. Pin the major version and read the migration guide before upgrading.
  • Node 22 requirement. Fine for most teams in 2026, but it bites on older CI images and on design tooling that bundles its own Node.

Alternatives worth knowing

ToolWhat it isPick it when
Tokens Studio + sd-transformsA Figma plugin for managing tokens, plus @tokens-studio/sd-transforms, a package of Style Dictionary transforms and a preprocessor for its export (version 2 targets Style Dictionary 5).Designers already manage tokens in Tokens Studio and you want Style Dictionary to read that export without hand-written glue.
TerrazzoA DTCG-native token build tool (CLI tz, config in terrazzo.config.ts) with plugins for CSS, JS/TS, Sass, Tailwind, Swift, Vanilla Extract and more. Its 2.0 release (March 2026) claims full DTCG 2025.10 support, including resolvers.Your source of truth is strict DTCG files with resolver-based themes, and your outputs are mostly web. Check the plugin list for the native outputs you need.
A hand-written scriptFifty lines of Node that read JSON and write a TS object.You have under a hundred tokens, one theme and one platform. Graduate to a real tool the day a second platform or theme appears.

Verdict

For a team shipping React Native and web from one set of tokens, Style Dictionary 5 remains our default. The hook model covers every output we have needed, outputReferences makes CSS theming clean, and adding a React Native module costs one small transform.

The one place we hesitate is themes. If your design system leans on DTCG resolvers for many brands and modes, try Terrazzo first and compare the output side by side. For one product with light and dark modes, Style Dictionary plus a small theme loop is the safer bet today.

  • Pin the major versionstyle-dictionary@^5 in package.json, and read the migration guide before any major bump.
  • Write tokens in DTCG syntax$value, $type, $description. It costs nothing now and keeps your options open if you switch tools.
  • Commit the generated files or build them in CI, not bothPick one so reviewers know whether a token diff is source or output.
  • Add a custom number transform for React NativeKeep spacing, radius and font sizes as plain numbers in the native module.
  • Keep broken references fatalStyle Dictionary throws on a broken reference by default (log.errors.brokenReferences). Leave it that way, and use log: { verbosity: 'verbose' } while setting up.

Sources

  1. Style Dictionary: Design Tokens Community Group format · Style Dictionary
  2. Style Dictionary: v4 migration guidelines · Style Dictionary
  3. Style Dictionary: v5 migration guidelines · Style Dictionary
  4. Style Dictionary: predefined formats · Style Dictionary
  5. Style Dictionary v5.3.0 release notes · GitHub
  6. Tokens Studio sd-transforms · GitHub
  7. Terrazzo documentation · Terrazzo
  8. Design Tokens Format Module 2025.10 · Design Tokens Community Group

Keep your place in the app

Save this story, pick up where you left off and follow Jonas.

Coming soon onGoogle PlayComing soon onApp Store