How to Export DESIGN.md Tokens to Tailwind v4 CSS Theme

Use the design.md CLI with the --format css-tailwind flag to convert DESIGN.md files into CSS @theme blocks that Tailwind v4 consumes natively.

The google-labs-code/design.md toolchain provides a purpose-built CLI to transform DESIGN.md token definitions into Tailwind v4-compatible CSS themes. This export pipeline validates token names against strict CSS identifier rules and maps design system categories—including colors, typography, spacing, and border-radius—into the modern @theme at-rule format.

How the Export Pipeline Works

The conversion from DESIGN.md to Tailwind v4 CSS occurs through three deterministic stages implemented in pure functions, making it safe to run in CI pipelines.

Stage 1: Parsing and Linting

The process begins in packages/cli/src/commands/export.ts where the CLI invokes readInput to ingest the source file. The lint function then constructs a DesignSystemState object that represents the validated token hierarchy and resolves all token references.

Stage 2: Tailwind v4 Emission

The TailwindV4EmitterHandler class in packages/cli/src/linter/tailwind/v4/handler.ts processes the DesignSystemState. It validates every token name against the CSS identifier regex /^[a-zA-Z0-9][a-zA-Z0-9-]*$/ and maps the design system maps into a plain TailwindV4ThemeData object. If validation fails, the handler returns an error and the CLI exits with a non-zero status.

Stage 3: CSS Serialization

The serializeToCss function in packages/cli/src/linter/tailwind/v4/serialize.ts receives the validated theme data. It iterates through the ordered CATEGORIES list and writes each entry as a CSS variable inside an @theme block, producing the final CSS string that the CLI prints to stdout.

Prerequisites

  • Node.js version 20 or higher, or Bun
  • The @google/design.md package installed globally or locally
npm install -g @google/design.md

or

bun add @google/design.md

CLI Export Method

Export your DESIGN.md file using the css-tailwind format flag. You can provide a file path or - to read from STDIN.

design.md export path/to/DESIGN.md --format css-tailwind > tailwind-theme.css

The command outputs a complete CSS @theme block to stdout. Redirect this to a file for consumption by Tailwind v4.

Integrating the CSS into Tailwind v4

Tailwind v4 automatically recognizes @theme blocks from imported CSS. Load the generated file into your configuration using a plugin.

// tailwind.config.js
const fs = require('fs');
const path = require('path');

module.exports = {
  plugins: [
    function ({ addBase }) {
      const css = fs.readFileSync(path.resolve(__dirname, 'tailwind-theme.css'), 'utf8');
      addBase(css);
    },
  ],
};

Programmatic API Usage

For custom build pipelines, invoke the emitter and serializer directly without using the CLI.

import { readFile } from 'fs/promises';
import { lint } from '@google/design.md/linter';
import { TailwindV4EmitterHandler } from '@google/design.md/linter/tailwind/v4/handler';
import { serializeToCss } from '@google/design.md/linter/tailwind/v4/serialize';

// Load DESIGN.md text
const designMd = await readFile('./examples/totality-festival/DESIGN.md', 'utf8');

// Lint and build the design-system model
const report = lint(designMd);

// Emit Tailwind v4 theme data
const emitter = new TailwindV4EmitterHandler();
const result = emitter.execute(report.designSystem);
if (!result.success) {
  throw new Error(result.error.message);
}

// Serialize to CSS @theme block
const css = serializeToCss(result.data.theme);
console.log(css);

This approach provides the same validation and output as the CLI, but allows you to manipulate the intermediate TailwindV4ThemeData before serialization.

Summary

  • The design.md export command with --format css-tailwind generates Tailwind v4 compatible @theme CSS blocks.
  • The export pipeline in packages/cli/src/linter/tailwind/v4/handler.ts validates token names against /^[a-zA-Z0-9][a-zA-Z0-9-]*$/ to ensure CSS compatibility.
  • Token categories including colors, typography, spacing, and border-radius are serialized by serializeToCss in packages/cli/src/linter/tailwind/v4/serialize.ts.
  • Both CLI and programmatic APIs are deterministic and safe for CI/CD environments.
  • The generated CSS file integrates into Tailwind v4 via standard CSS imports or the addBase plugin helper.

Frequently Asked Questions

What Node.js version is required to run the design.md CLI?

The CLI requires Node.js version 20 or higher, or alternatively Bun. These versions provide the necessary JavaScript features and performance characteristics for the linting and serialization pipeline.

Why does the export command fail with a token validation error?

The TailwindV4EmitterHandler validates every token name against the CSS identifier regex /^[a-zA-Z0-9][a-zA-Z0-9-]*$/. If any token contains special characters or spaces, the export exits with a non-zero status. Ensure your DESIGN.md tokens use only alphanumeric characters and hyphens, starting with a letter or number.

Can I read the DESIGN.md file from STDIN instead of a file?

Yes. Pass - as the file path to design.md export to read from STDIN. This is useful for piping data from other commands or processing files in memory.

cat DESIGN.md | design.md export - --format css-tailwind > theme.css

How do I import the generated CSS file into my Tailwind v4 project?

Tailwind v4 natively consumes CSS @theme blocks. You can either import the generated CSS file directly in your main CSS entry point, or use the addBase plugin function in tailwind.config.js to inject the content programmatically, as shown in the integration example above.

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 →