# How to Export DESIGN.md Tokens to Tailwind v4 CSS Format

> Export DESIGN.md tokens to Tailwind v4 CSS format using the design.md CLI or programmatically. Convert your design tokens efficiently for seamless integration.

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

---

**Use the `design.md export --format css-tailwind` command to convert DESIGN.md files into a Tailwind v4-compatible `@theme` CSS block, or programmatically invoke `TailwindV4EmitterHandler` and `serializeToCss` from the `@google/design.md` package.**

The [`google-labs-code/design.md`](https://github.com/google-labs-code/design.md/blob/main/google-labs-code/design.md) repository provides a CLI tool that transforms design system documentation into executable code. By leveraging the export functionality, you can parse DESIGN.md files and emit standards-compliant CSS that Tailwind v4 consumes directly through its `@theme` directive.

## Prerequisites and Installation

The CLI requires **Node.js version 20 or higher**, or alternatively Bun. Install the package globally via npm to access the [`design.md`](https://github.com/google-labs-code/design.md/blob/main/design.md) binary.

```bash
npm install -g @google/design.md

```

## Exporting Tokens via the CLI

The [`design.md`](https://github.com/google-labs-code/design.md/blob/main/design.md) CLI supports multiple output formats. For Tailwind v4, specify the **`css-tailwind`** format, which generates a CSS `@theme` block containing CSS variables derived from your design tokens.

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

```

- Pass `-` instead of a file path to read from **STDIN**.
- The command exits with a non-zero status if token validation fails.
- Output prints to stdout for easy redirection into your build pipeline.

## Programmatic Export with Node.js

For CI pipelines or custom build tools, import the linter and Tailwind v4 emitter directly from the package. This approach uses pure functions that perform no I/O, making them safe for automated environments.

```typescript
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';

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

// 2️⃣ Lint & get the design-system model
const report = lint(designMd);

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

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

```

## How the Export Pipeline Works

The export process operates in three distinct stages, each handled by specific modules in the `packages/cli/src` directory.

### Stage 1: Parsing and Linting

In [`packages/cli/src/commands/export.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/commands/export.ts), the CLI calls `readInput` to ingest the source file and `lint` to construct a **`DesignSystemState`** object. This state represents the validated token set, including categories like colors, typography, border-radius, and spacing.

### Stage 2: Tailwind v4 Emitter

The **`TailwindV4EmitterHandler`** class 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) validates every token name against the CSS identifier regex `/^[a-zA-Z0-9][a-zA-Z0-9-]*$/`. It then maps the design system maps into a plain **`TailwindV4ThemeData`** object. If validation fails, the handler returns an error result that prevents invalid CSS identifiers from reaching the output.

### Stage 3: CSS Serialization

The **`serializeToCss`** function in [`packages/cli/src/linter/tailwind/v4/serialize.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/tailwind/v4/serialize.ts) walks the ordered **`CATEGORIES`** list and writes each entry as a CSS variable inside an `@theme` block. This serialization is deterministic and produces the final CSS string that the CLI prints to stdout.

## Integrating with Tailwind v4

Consume the generated CSS in your Tailwind configuration by reading the file and injecting it into the base styles.

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

module.exports = {
  // ...your existing config
  theme: {
    // Tailwind v4 automatically reads `@theme` blocks from imported CSS.
  },
  plugins: [
    // Load the generated @theme block so Tailwind can resolve the variables.
    function ({ addBase }) {
      const css = fs.readFileSync(path.resolve(__dirname, 'tailwind-theme.css'), 'utf8');
      addBase(css);
    },
  ],
};

```

## Summary

- The [`design.md`](https://github.com/google-labs-code/design.md/blob/main/design.md) CLI exports DESIGN.md tokens to Tailwind v4 via the **`css-tailwind`** format.
- The pipeline uses three stages: parsing/linting (`readInput`, `lint`), emitting (`TailwindV4EmitterHandler`), and serialization (`serializeToCss`).
- Token names must validate against the regex **`/^[a-zA-Z0-9][a-zA-Z0-9-]*$/`** to ensure valid CSS identifiers.
- Pure functional architecture makes the export pipeline deterministic and safe for CI environments.

## 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. Earlier versions are not supported due to modern JavaScript dependencies used in the [`google-labs-code/design.md`](https://github.com/google-labs-code/design.md/blob/main/google-labs-code/design.md) toolchain.

### How does the Tailwind v4 emitter validate token names?

The `TailwindV4EmitterHandler` validates every token name against the CSS identifier regex `/^[a-zA-Z0-9][a-zA-Z0-9-]*$/`. If any token contains characters outside this pattern—such as spaces or special symbols—the export fails with a non-zero exit status and a descriptive error message.

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

Yes. Pass `-` as the file path argument to the export command: `design.md export - --format css-tailwind`. This reads the input from STDIN, allowing you to pipe design tokens directly into the CLI from other tools or scripts.

### Is the export pipeline safe to run in CI environments?

Yes. Both the `TailwindV4EmitterHandler` and `serializeToCss` functions are pure and deterministic, performing no side effects or I/O operations. This makes the entire export pipeline safe for CI pipelines and automated build processes.