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

> Explore the differences between dtcg, json-tailwind, and css-tailwind export formats in design.md. Understand how each format translates design tokens for Tailwind CSS.

- Repository: [Google Labs Code/design.md](https://github.com/google-labs-code/design.md)
- Tags: deep-dive
- Published: 2026-07-03

---

**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`](https://github.com/google-labs-code/design.md/blob/main/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`](https://github.com/google-labs-code/design.md/blob/main/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`](https://github.com/google-labs-code/design.md/blob/main/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`](https://github.com/google-labs-code/design.md/blob/main/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`](https://github.com/google-labs-code/design.md/blob/main/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`](https://github.com/google-labs-code/design.md/blob/main/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`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/commands/export.ts) (lines 83-94) instantiates the appropriate handler based on the `--format` flag:

```typescript
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:

```bash

# 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`](https://github.com/google-labs-code/design.md/blob/main/tokens.dtcg.json)):

```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`](https://github.com/google-labs-code/design.md/blob/main/tailwind-extend.json)):

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

```

**CSS-Tailwind output** ([`tailwind-theme.css`](https://github.com/google-labs-code/design.md/blob/main/tailwind-theme.css)):

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

```

## Key Implementation Files

| Path | Purpose |
|------|---------|
| [`packages/cli/src/commands/export.ts`](https://github.com/google-labs-code/design.md/blob/main/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`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/dtcg/handler.ts) | Implements `DtcgEmitterHandler` for W3C-compliant token generation. |
| [`packages/cli/src/linter/tailwind/handler.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/tailwind/handler.ts) | Implements `TailwindEmitterHandler` for Tailwind v3 JSON output. |
| [`packages/cli/src/linter/tailwind/v4/handler.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/tailwind/v4/handler.ts) | Implements `TailwindV4EmitterHandler` with CSS identifier validation. |
| [`packages/cli/src/linter/tailwind/v4/serializer.ts`](https://github.com/google-labs-code/design.md/blob/main/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`](https://github.com/google-labs-code/design.md/blob/main/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.