> ## Documentation Index
> Fetch the complete documentation index at: https://docs.livry.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Build-Time Tokens with Style Dictionary

> Fetch the DTCG document in CI and generate whatever your platform needs — with no runtime dependency on Livry at all.

If you already run a token pipeline, Livry can just be its source. Fetch the DTCG document in CI,
generate what your platforms need, and ship the output — **your app has no runtime dependency on
Livry at all.**

**Theme integration required:** a pair whose library is `Build-time tokens (Style Dictionary)`. It
builds `tokens.dtcg.json`, `tokens.json` and `tokens.flat.json`.

## Which file

<Warning>
  **Use `tokens.dtcg.json`, not `tokens.json`.**

  `tokens.dtcg.json` keeps aliases as written — `{color.brand}`. Style Dictionary and every other
  DTCG tool resolve references themselves, and that is where their whole reference-graph feature set
  lives: outputs that preserve the relationship, per-platform reference resolution, warnings about
  broken links.

  `tokens.json` has every alias already flattened to a value. Feeding it to a DTCG tool throws away
  the relationships it was built to use.
</Warning>

## 1. Fetch in CI

```bash theme={null}
# Before the build.
mkdir -p tokens
curl --fail --silent --show-error \
  "https://cdn.livry.dev/{environmentID}/{themeID}/{variantID}/7/tokens.dtcg.json" \
  -o tokens/theme.tokens.json
```

<Note>
  **Pin the version.** `/7/` rather than `/latest/`: a build should not change because somebody
  published while it was running, and two builds of the same commit should produce the same bytes.

  Bump the number as a deliberate commit, like any other dependency.
</Note>

`--fail` matters — without it curl writes the error body to your tokens file and the build continues
with garbage.

## 2. Configure Style Dictionary

```js theme={null}
// style-dictionary.config.mjs — Style Dictionary reads DTCG ($value, $type) natively.
export default {
  source: ["tokens/theme.tokens.json"],
  platforms: {
    css: {
      transformGroup: "css",
      buildPath: "dist/",
      files: [{ destination: "tokens.css", format: "css/variables" }],
    },
    js: {
      transformGroup: "js",
      buildPath: "dist/",
      files: [{ destination: "tokens.js", format: "javascript/es6" }],
    },
  },
};
```

```bash theme={null}
npx style-dictionary build --config style-dictionary.config.mjs
```

## Many brands

A build-time pipeline generates **one output per brand**, so loop:

```bash theme={null}
for VARIANT in northwind contoso fabrikam; do
  curl --fail --silent --show-error \
    "https://cdn.livry.dev/$ENV/$THEME/$VARIANT/$VERSION/tokens.dtcg.json" \
    -o "tokens/$VARIANT.tokens.json"
done
```

```js theme={null}
import StyleDictionary from "style-dictionary";

const brands = ["northwind", "contoso", "fabrikam"];

for (const brand of brands) {
  await new StyleDictionary({
    source: [`tokens/${brand}.tokens.json`],
    platforms: {
      css: {
        transformGroup: "css",
        buildPath: `dist/${brand}/`,
        files: [{ destination: "tokens.css", format: "css/variables" }],
      },
    },
  }).buildAllPlatforms();
}
```

<Warning>
  **This is the trade-off.** A build-time pipeline means a new brand needs a build and a deploy — you
  have given up the runtime brand switch that makes Livry's stylesheet integration instant.

  If you onboard brands frequently, consider using `tokens.css` at runtime and keeping the build-time
  pipeline only for the platforms that genuinely need generated output — native apps, email
  templates, design-tool sync.
</Warning>

A Theme can hold both integrations at once and build both file sets.

## Discovering brands and versions

Rather than hard-coding the list, ask the [API](/api/variants):

```bash theme={null}
VARIANTS=$(curl --fail --silent \
  "https://api.livry.dev/public/v1/environments/$ENV/themes/$THEME/variants" \
  -H "Authorization: Bearer $LIVRY_TOKEN" | jq -r '.items[].id')
```

The Theme's `servingUrls.version` is the newest published version, so "pin to whatever is newest at
build time, and record it" is a few lines.

<Note>
  The API is not yet reachable with a machine credential — see
  [Authentication](/api/authentication). Until it is, a CI integration means a user-backed token,
  which is not something to put in a shared pipeline. Hard-coding the list is the honest
  recommendation today.
</Note>

## Other DTCG tools

Anything that reads the DTCG format works the same way — fetch `tokens.dtcg.json` and point the tool
at it. `$extends` and `$ref` are the two places to be careful, because Livry preserves them without
applying them; if your tool emits either, Livry will store it faithfully and ignore it. See
[Tokens](/theming/tokens).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.