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.extendhierarchy, optimizing for JavaScript configuration file consumption. - CSS-Tailwind wraps the same values in CSS custom property syntax within an
@themeblock, 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.extendobject as plain CSS strings for Tailwind v3 configuration files. - CSS-Tailwind emits a CSS file with
@themeblocks and custom properties for Tailwind v4's CSS-first architecture. - All three formats originate from the same
DesignSystemStatebut use distinct handlers:DtcgEmitterHandler,TailwindEmitterHandler, andTailwindV4EmitterHandler.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →