Design Token Kit

Introduction

Migrate from 1.x to 2.0

Move Core API integrations and token workflows from Design Token Kit 1.x to 2.0.

Migrate from 1.x to 2.0

Design Token Kit 2.0 is a major release with breaking changes in the Core API. The CLI command names remain familiar, but the validation and reader pipeline has changed underneath them.

Read this guide before upgrading an application, build script, or browser integration from 1.x.

Upgrade packages

Update both packages together when they are used in the same project:

npm install @design-token-kit/core@2 @design-token-kit/cli@2

Design Token Kit requires Node.js 20.19.0 or newer.

Validation API

The checker was renamed and its method now reflects the operation it performs.

// 1.x
import { DtcgChecker } from "@design-token-kit/core";

const issues = await new DtcgChecker().validate(sources);
// 2.0
import { TokenChecker } from "@design-token-kit/core";

const issues = await new TokenChecker().check(sources);

TokenChecker checks DTCG JSON, HRDT YAML, and DESIGN.md sources through one pipeline. Format and schema validation is performed by the reader for each format, followed by model checks and optional lint checks.

Use CheckScope.SCHEMA for format and schema checks without model checks. Use CheckScope.LINT when architecture and naming checks are needed.

import { CheckScope, TokenChecker } from "@design-token-kit/core";

const issues = await new TokenChecker({ scope: CheckScope.SCHEMA }).check(
    ["./tokens.json"],
);

Readers and writers

Readers and writers are named after their format:

1.x 2.0
DtcgJsonReader DtcgReader
HrdtTokenReader HrdtReader
DtcgJsonWriter DtcgWriter
HrdtTokenWriter HrdtWriter

Readers are created through an asynchronous factory because schema loading is part of reader setup.

// 1.x
const reader = new DtcgJsonReader();
const document = reader.parse(json);
// 2.0
const reader = await DtcgReader.create();
const result = reader.read(json);

if (!result.ok) {
    console.error(result.issues);
} else {
    const document = result.documents[0];
}

Use DtcgReader.noSchema() when the environment cannot load a schema and only the token model should be checked.

read() always returns a result with a document list. This replaces the former parse(), parseAll(), and parseRaw() methods.

Reader errors now receive the diagnostic id before the message:

new DtcgReaderError("invalid-color", "The color value is invalid.");

Removed validators

These classes were removed because every format validates itself while reading:

  • TokenValidator
  • DtcgSchemaValidator
  • HrdtTokenValidator
  • DesignMdTokenValidator

Use TokenChecker for file or source validation. Use a format reader when the content is already in memory.

Format enums

The old Format enum is split by responsibility:

import {
    PlatformFormat,
    TokenFormat,
} from "@design-token-kit/core";

const inputFormat = TokenFormat.DTCG;
const outputFormat = PlatformFormat.CSS;

TokenFormat contains readable token formats:

  • DTCG
  • HRDT
  • DESIGN_MD

PlatformFormat contains generated platform formats:

  • CSS
  • SCSS
  • TAILWIND_V4
  • SWIFT_UI
  • FIGMA_SCRIPT
  • ANDROID

The browser API exports the same two enums from @design-token-kit/core/browser.

Loading results

DtcgListLoader.load() still provides the throwing form for applications that want a failed load to stop execution.

DtcgListLoader.read() now returns a LoadResult instead of throwing TokenSyntaxError.

const result = await new DtcgListLoader().read(sources);

if (!result.ok) {
    console.error(result.issues);
    return;
}

const list = result.list;

Conversion names

Use the primary converter names in new code:

1.x name 2.0 name
DtcgTokenCssConverter CssTokenConverter
DtcgTokenScssConverter ScssTokenConverter
DtcgTailwindCssConverter TailwindTokenConverter
ColorCssSerializer CssColorValueConverter
TokenScssOutput ScssTokenOutput
createTokenCssConverter() createCssTokenConverter()
createTokenScssConverter() createScssTokenConverter()
createTailwindCssConverter() createTailwindTokenConverter()

Compatibility aliases for the older converter names remain available in 2.0, but new integrations should use the primary names.

Browser API

The browser facade keeps the same high-level workflow, but uses the split format enums:

import {
    BrowserTokenToolkit,
    CheckScope,
    PlatformFormat,
    TokenFormat,
} from "@design-token-kit/core/browser";

const input = {
    base: {
        source: "tokens.json",
        format: TokenFormat.DTCG,
        content: json,
    },
};

const toolkit = new BrowserTokenToolkit();
const issues = toolkit.check(input, { scope: CheckScope.LINT });
const [output] = toolkit.convert(input, PlatformFormat.CSS);

convert() and stats() always run the required schema and model checks. They throw BrowserTokenValidationError when errors prevent the operation. The structured diagnostics are available on error.issues.

CLI behavior

The main CLI commands remain available:

  • check validates sources.
  • validate remains an alias for check.
  • convert generates platform or token-format output.
  • showcase generates standalone HTML.
  • stats generates token statistics.

The following behavior changed:

  • missing-description is opt-in and is not run by default with --scope lint.
  • A source that fails reading or schema validation produces no partial model.
  • Invalid sources report all available diagnostics instead of stopping at the first error.
  • Theme names follow <role>[.theme].<format>.

Token file names

The first source is the base document. Additional sources are theme overrides.

tokens.dtcg.json        base document
tokens.dark.dtcg.json   dark theme
tokens.yaml             base document
tokens.dark.yaml        dark theme

The format is detected from the file name and content unless the caller forces an input format.

Migration checklist

  • Upgrade @design-token-kit/core and @design-token-kit/cli together.
  • Replace DtcgChecker.validate() with TokenChecker.check().
  • Rename readers, writers, and removed validator classes.
  • Replace Format with TokenFormat or PlatformFormat.
  • Handle ReadResult and LoadResult before accessing documents or lists.
  • Review theme file names and source ordering.
  • Decide whether lint checks should include missing-description explicitly.
  • Update browser integrations to use the new format enums.
  • Run the full token check and conversion pipeline before releasing.