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

> Export DESIGN.md tokens to Tailwind v4 CSS using the @google/design.md CLI. Learn how to generate CSS variables with the --format css-tailwind flag for seamless integration.

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

---

**The `@google/design.md` CLI exports DESIGN.md tokens to Tailwind v4's `@theme` format using the `--format css-tailwind` flag, generating a CSS file that maps design tokens to CSS variables inside an `@theme` block.**

The [`google-labs-code/design.md`](https://github.com/google-labs-code/design.md/blob/main/google-labs-code/design.md) repository provides a toolchain for managing design tokens in markdown. When targeting Tailwind v4, you can export DESIGN.md tokens to the CSS `@theme` format, which Tailwind v4 consumes natively to configure theme variables.

## How the Export Pipeline Works

The export process follows a deterministic three-stage pipeline implemented in [`packages/cli/src/commands/export.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/commands/export.ts):

### Stage 1: Parsing and Linting

The `readInput` function ingests the source file, and the `lint` function constructs a `DesignSystemState` object that represents the validated token set.

### Stage 2: Tailwind v4 Emission

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 CSS identifier rules using the regex `/^[a-zA-Z0-9][a-zA-Z0-9-]*$/`. It then maps the design system categories—colors, typography, border-radius, and spacing—into a plain `TailwindV4ThemeData` object.

### 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. Because both the emitter and serializer are pure functions with no I/O side effects, the pipeline is deterministic and safe for CI environments.

## Installation Requirements

Install the CLI globally using npm or Bun. The tool requires **Node.js ≥ 20** or **Bun**.

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

# or

bun add @google/design.md

```

## CLI Export Method

Run the `export` command with the `--format css-tailwind` flag to generate the CSS output. You can redirect the stdout to a file or pipe it to another process.

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

```

The command accepts the following behaviors:
- Use `-` as the file path to read from **STDIN**.
- The command exits with a non-zero status if any token name fails validation (e.g., contains characters not allowed by `/^[a-zA-Z0-9][a-zA-Z0-9-]*$/`).

## Programmatic Usage (Node.js)

For custom build pipelines, import the linter and Tailwind v4 emitter directly. This approach gives you programmatic access to the `DesignSystemState` and_validation errors.

```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 to 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);

```

## Integrating with Tailwind v4

Import the generated CSS file into your Tailwind configuration so that the `@theme` block is available to the Tailwind engine.

```javascript
// 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);
    },
  ],
};

```

Tailwind v4 automatically reads `@theme` blocks from imported CSS, resolving the CSS custom properties as theme variables.

## Summary

- The **`css-tailwind`** format produces a native Tailwind v4 `@theme` CSS block.
- The pipeline runs through `readInput` → `lint` → `TailwindV4EmitterHandler` → `serializeToCss`.
- Token names must match the regex `/^[a-zA-Z0-9][a-zA-Z0-9-]*$/` or the export will fail with a non-zero exit code.
- The emitter and serializer are pure functions, making the export safe for CI pipelines.

## Frequently Asked Questions

### What Node.js version is required to run the exporter?

The CLI requires **Node.js ≥ 20** or **Bun**. Earlier Node versions are not supported due to modern JavaScript features used in the [`google-labs-code/design.md`](https://github.com/google-labs-code/design.md/blob/main/google-labs-code/design.md) toolchain.

### 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 allows you to pipe content from other tools or use the CLI in shell pipelines.

### What happens if my DESIGN.md contains invalid token names?

The export will fail with a non-zero exit status. The `TailwindV4EmitterHandler` validates every token name against the CSS identifier regex `/^[a-zA-Z0-9][a-zA-Z0-9-]*$/`, and any mismatch will raise a validation error before serialization occurs.

### Where is the Tailwind v4 emitter logic implemented?

The core logic resides in two files within the `@google/design.md` package: [`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) contains the `TailwindV4EmitterHandler` class that transforms the design system state, and [`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) contains the `serializeToCss` function that generates the final CSS output.