How to Export DESIGN.md Tokens to W3C Design Tokens Format Module (DTCG)

Use the CLI command npx @google/design.md export --format dtcg or the DtcgEmitterHandler class to convert DESIGN.md files into standards-compliant DTCG JSON.

Design tokens defined in DESIGN.md files can be transformed into the W3C Design Tokens Community Group (DTCG) format using the export utilities in the google-labs-code/design.md repository. This process converts color, spacing, rounded, and typography definitions into the interoperable 2025.10 DTCG schema for cross-platform design system consumption.

Exporting DESIGN.md Tokens to DTCG via CLI

The fastest way to export tokens is via the command-line interface. The export command in packages/cli/src/commands/export.ts parses the DESIGN.md input, validates the syntax through the linter, and delegates to the DtcgEmitterHandler when --format dtcg is specified.

Basic CLI Usage

npx @google/design.md export --format dtcg DESIGN.md > tokens.json

This command reads the DESIGN.md file, processes the design system state, and outputs a formatted JSON file following the DTCG specification with 2-space indentation.

Exporting DESIGN.md Tokens to DTCG Programmatically

For integration into build pipelines or custom Node.js applications, import the emitter directly from the linter package. The DtcgEmitterHandler class in packages/cli/src/linter/dtcg/handler.ts implements the DtcgEmitterSpec interface and provides fine-grained control over the export process.

TypeScript Implementation Example

import { readFileSync } from 'fs';
import { lint } from '@google/design.md/linter';
import { DtcgEmitterHandler } from '@google/design.md/linter/dtcg';

// Load the DESIGN.md file
const markdown = readFileSync('DESIGN.md', 'utf8');

// Generate the design system state
const report = lint(markdown);

// Initialize the DTCG emitter
const handler = new DtcgEmitterHandler();
const result = handler.execute(report.designSystem);

if (result.success) {
  // Output formatted JSON with 2-space indentation
  console.log(JSON.stringify(result.data, null, 2));
} else {
  console.error('Export failed:', result.error);
}

The execute method returns an object with success: true and the DTCG-compliant data structure, or an error object if the conversion fails.

W3C Design Tokens Format Module (DTCG) Structure

The emitter converts internal DesignSystemState into the W3C DTCG 2025.10 schema (https://www.designtokens.org/schemas/2025.10/format.json). The handler organizes tokens into semantic groups with $type declarations and optional $description fields.

Color Token Conversion

Colors are processed through mapColors and converted using colorToValue into sRGB arrays with hex equivalents:

{
  "$schema": "https://www.designtokens.org/schemas/2025.10/format.json",
  "$description": "Heritage design system",
  "color": {
    "$type": "color",
    "primary": {
      "$value": {
        "colorSpace": "srgb",
        "components": [0.102, 0.110, 0.118],
        "hex": "#1a1c1e"
      }
    },
    "tertiary": {
      "$value": {
        "colorSpace": "srgb",
        "components": [0.724, 0.259, 0.180],
        "hex": "#b8422e"
      }
    }
  }
}

Dimension and Spacing Tokens

Spacing and rounded values are mapped via mapDimensionGroup and converted through dimToValue into structured dimension objects. Both token groups use the $type: "dimension" declaration:

{
  "spacing": {
    "$type": "dimension",
    "sm": { "$value": { "value": 8, "unit": "px" } },
    "md": { "$value": { "value": 16, "unit": "px" } }
  },
  "rounded": {
    "$type": "dimension",
    "lg": { "$value": { "value": 24, "unit": "px" } }
  }
}

Typography Token Structure

Typography definitions are transformed via mapTypography and typographyToValue into composite DTCG typography objects:

{
  "typography": {
    "h1": {
      "$type": "typography",
      "$value": {
        "fontFamily": "Public Sans",
        "fontSize": { "value": 3, "unit": "rem" }
      }
    }
  }
}

Summary

  • CLI Export: Use npx @google/design.md export --format dtcg DESIGN.md for quick command-line conversion to DTCG format
  • API Access: Import DtcgEmitterHandler from @google/design.md/linter/dtcg for programmatic control over the export process
  • Schema Compliance: Output follows the W3C DTCG 2025.10 specification with proper $schema declaration and $type annotations
  • Token Categories: Colors convert to sRGB component arrays with hex values, dimensions (spacing/rounded) to value/unit pairs, and typography to composite objects
  • Source Files: Implementation resides in packages/cli/src/commands/export.ts and packages/cli/src/linter/dtcg/handler.ts, with type definitions in packages/cli/src/linter/dtcg/spec.ts

Frequently Asked Questions

What DTCG schema version does the exporter support?

The DtcgEmitterHandler implements the 2025.10 DTCG schema as defined at https://www.designtokens.org/schemas/2025.10/format.json. This version includes standardized $type and $value structures for colors, dimensions, and typography tokens, ensuring interoperability with design tools that support the W3C specification.

Can I export only specific token categories like colors or spacing?

The current implementation in handler.ts exports all defined token categories—including colors, spacing, rounded values, and typography—as a complete design system. To export specific categories, filter the DesignSystemState object before passing it to handler.execute(), or post-process the resulting JSON output to remove unwanted token groups.

How does the CLI handle validation errors during export?

The export command in packages/cli/src/commands/export.ts runs the full linter on the DESIGN.md input before invoking the emitter. If the linter detects syntax errors or invalid token definitions, the process halts and reports the errors, preventing the generation of malformed DTCG output files.

What TypeScript types define the DTCG output structure?

Type definitions for DTCG token structures—including DtcgTokenFile and DtcgGroup interfaces—are declared in packages/cli/src/linter/dtcg/spec.ts. These types ensure type safety when working with the emitted token data programmatically in TypeScript environments, while the handlers are exported via packages/cli/src/linter/index.ts.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →