DTCG vs JSON-Tailwind vs CSS-Tailwind: Understanding the Export Format Differences in design.md

The dtcg format exports W3C-standard design tokens as JSON with typed metadata, while json-tailwind produces a Tailwind v3 configuration object, and css-tailwind generates a CSS file with @theme blocks for Tailwind v4.

The export command in the google-labs-code/design.md CLI transforms DESIGN.md token sets into three distinct serialization strategies. Each format targets a specific consumer toolchain, from standards-compliant design token pipelines to Tailwind CSS configurations. Understanding the difference between dtcg, json-tailwind, and css-tailwind export formats ensures you select the right output for your build pipeline.

Architecture Overview

All three emitters originate from the same internal DesignSystemState model produced by the linter, but they project this data into fundamentally different consumer representations.

DTCG Format

The dtcg format targets tools that understand the W3C Design Tokens Community Group specification. According to the source code in packages/cli/src/linter/dtcg/handler.ts, the DtcgEmitterHandler maps the internal state into a DtcgTokenFile that includes a $schema reference to https://www.designtokens.org/schemas/2025.10/format.json. The output organizes tokens into groups like color, spacing, rounded, and typography, with each token expressing $value, $type, and $description metadata.

JSON-Tailwind Format

The json-tailwind format (also aliased as tailwind) generates a JSON object specifically structured for Tailwind v3 configuration files. The TailwindEmitterHandler in packages/cli/src/linter/tailwind/handler.ts converts the design system into a nested theme.extend object containing colors, fontFamily, fontSize, borderRadius, and spacing keys. Values remain as simple CSS strings (e.g., "#ff00aa" or "1rem") suitable for direct merging into tailwind.config.js.

CSS-Tailwind Format

The css-tailwind format caters to Tailwind v4's new CSS-first configuration approach. The TailwindV4EmitterHandler in packages/cli/src/linter/tailwind/v4/handler.ts produces a plain CSS file containing an @theme block with CSS custom properties (e.g., --color-primary). This output requires additional validation via VALID_TOKEN_NAME to ensure token names are legal CSS identifiers, then serializes the result through serializeTailwindV4 in src/linter/tailwind/v4/serializer.ts.

Internal Serialization Differences

While all three formats consume the same DesignSystemState, their serialization strategies diverge significantly:

  • DTCG converts tokens into a schema-validated JSON structure with typed values (color spaces, units) and metadata properties.
  • JSON-Tailwind flattens values into CSS strings inside a theme.extend hierarchy, optimizing for JavaScript configuration file consumption.
  • CSS-Tailwind wraps the same values in CSS custom property syntax within an @theme block, producing plain text output for CSS/SCSS pipelines.

The dispatch logic in packages/cli/src/commands/export.ts (lines 83-94) instantiates the appropriate handler based on the --format flag:

if (format === 'json-tailwind' || format === 'tailwind') {
  const handler = new TailwindEmitterHandler();
  const result = handler.execute(report.designSystem);
  console.log(JSON.stringify(result.data, null, 2));
} else if (format === 'dtcg') {
  const handler = new DtcgEmitterHandler();
  const result = handler.execute(report.designSystem);
  console.log(JSON.stringify(result.data, null, 2));
} else if (format === 'css-tailwind') {
  const handler = new TailwindV4EmitterHandler();
  const result = handler.execute(report.designSystem);
  process.stdout.write(serializeTailwindV4(result.data.theme));
}

CLI Usage Examples

Run the export command from the repository root to generate each format:


# Export as W3C DTCG standard

npx design-md export design.tokens.json --format dtcg > tokens.dtcg.json

# Export as Tailwind v3 configuration extension

npx design-md export design.tokens.json --format json-tailwind > tailwind-extend.json

# Export as Tailwind v4 CSS theme

npx design-md export design.tokens.json --format css-tailwind > tailwind-theme.css

Output Format Comparison

DTCG output (tokens.dtcg.json):

{
  "$schema": "https://www.designtokens.org/schemas/2025.10/format.json",
  "color": {
    "primary": { "$value": { "colorSpace": "srgb", "components": [0.5,0.2,0.9], "hex":"#7f33e6" } }
  },
  "spacing": {
    "small": { "$value": { "value": 8, "unit": "px" } }
  }
}

JSON-Tailwind output (tailwind-extend.json):

{
  "theme": {
    "extend": {
      "colors": {
        "primary": "#7f33e6"
      },
      "spacing": {
        "small": "8px"
      }
    }
  }
}

CSS-Tailwind output (tailwind-theme.css):

@theme {
  --color-primary: #7f33e6;
  --spacing-small: 8px;
}

Key Implementation Files

Path Purpose
packages/cli/src/commands/export.ts CLI entry point that dispatches to the appropriate emitter based on the --format argument.
packages/cli/src/linter/dtcg/handler.ts Implements DtcgEmitterHandler for W3C-compliant token generation.
packages/cli/src/linter/tailwind/handler.ts Implements TailwindEmitterHandler for Tailwind v3 JSON output.
packages/cli/src/linter/tailwind/v4/handler.ts Implements TailwindV4EmitterHandler with CSS identifier validation.
packages/cli/src/linter/tailwind/v4/serializer.ts Contains serializeTailwindV4 for generating CSS @theme blocks.

Summary

  • DTCG produces standards-compliant JSON with rich metadata for design-token-aware build pipelines.
  • JSON-Tailwind generates a theme.extend object as plain CSS strings for Tailwind v3 configuration files.
  • CSS-Tailwind emits a CSS file with @theme blocks and custom properties for Tailwind v4's CSS-first architecture.
  • All three formats originate from the same DesignSystemState but use distinct handlers: DtcgEmitterHandler, TailwindEmitterHandler, and TailwindV4EmitterHandler.

Frequently Asked Questions

Which format should I use for Tailwind CSS v3 projects?

Use json-tailwind (or the tailwind alias). This format produces a JSON object with a theme.extend structure that merges directly into your tailwind.config.js file, allowing you to extend the default theme with custom design tokens as simple CSS strings.

Can I consume DTCG output directly in Tailwind CSS?

Not directly. The dtcg format follows the W3C Design Tokens Community Group specification and includes metadata like $value and $type that Tailwind does not natively understand. You would need a transformation step to convert DTCG tokens into the format Tailwind expects, or use the json-tailwind or css-tailwind formats instead.

Why does css-tailwind require additional validation?

The css-tailwind format generates CSS custom properties (variables) within an @theme block. The TailwindV4EmitterHandler validates token names against VALID_TOKEN_NAME patterns to ensure they are legal CSS identifiers. This prevents syntax errors in the generated CSS file, as CSS variable names must follow specific naming rules that differ from JavaScript object keys.

What is the difference between json-tailwind and css-tailwind outputs?

json-tailwind produces a JSON file containing a theme.extend object with nested keys for colors, spacing, and other tokens, suitable for JavaScript configuration. css-tailwind generates a plain CSS file with an @theme block containing CSS custom properties (e.g., --color-primary), designed for Tailwind v4's CSS-based configuration system.

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 →