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

> Export DESIGN.md tokens to Tailwind v4 CSS custom properties with the design.md CLI. Learn how to use 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-27

---

**The [`design.md`](https://github.com/google-labs-code/design.md/blob/main/design.md) CLI converts DESIGN.md token definitions into Tailwind v4 compatible CSS `@theme` blocks using the `--format css-tailwind` flag, emitting CSS custom properties that Tailwind v4 consumes natively.**

The [`google-labs-code/design.md`](https://github.com/google-labs-code/design.md/blob/main/google-labs-code/design.md) repository ships with a purpose-built toolchain for managing design tokens in Markdown. When working with Tailwind v4, you can export DESIGN.md tokens directly to the CSS `@theme` format, enabling seamless integration of your design system into the utility-first framework without manual variable mapping.

## Prerequisites

Install the [`design.md`](https://github.com/google-labs-code/design.md/blob/main/design.md) CLI globally using your preferred package manager. The tool requires **Node.js ≥ 20** or Bun.

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

# or

bun add @google/design.md

```

## CLI Method: Quick Export

The fastest way to export tokens is using the `export` command with the `css-tailwind` format. This parses your DESIGN.md file, validates all token names against CSS identifier rules, and outputs a complete `@theme` block.

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

```

- Use `-` instead of a file path to read from **STDIN**.
- The command exits with a non-zero status if any token fails validation (e.g., contains characters not matching `/^[a-zA-Z0-9][a-zA-Z0-9-]*$/`).
- The output is deterministic and safe to run in CI pipelines.

**Example:**

```bash
design.md export ./examples/totality-festival/DESIGN.md --format css-tailwind > ./totality-theme.css

```

## Programmatic Method: Node.js Integration

For custom build pipelines, import the linting and emission modules directly. The API is pure (no I/O side effects), making it ideal for testing and automation.

```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 and build the design system state
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);

```

## Understanding the Export Pipeline

The export process follows a strict 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). Each stage is isolated and testable.

### Parsing and Linting

The `readInput` function ingests the source Markdown, while `lint` constructs a `DesignSystemState` object containing validated maps for colors, typography, border-radius, and spacing.

### Tailwind v4 Emission

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), the `TailwindV4EmitterHandler` class validates every token name against CSS identifier rules. It transforms the `DesignSystemState` into a plain `TailwindV4ThemeData` object, mapping design system categories to Tailwind-compatible theme keys.

### 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 produces standard CSS custom properties that Tailwind v4 references automatically.

## Integrating with Tailwind v4

Import the generated CSS file into your project. Tailwind v4 natively recognizes `@theme` blocks, making the variables available to utility classes.

```css
/* main.css */
@import './tailwind-theme.css';
@import 'tailwindcss';

```

Alternatively, load the CSS programmatically in your build configuration if you need to process it through additional PostCSS steps.

## Summary

- **Install the CLI** with `npm install -g @google/design.md` (requires Node ≥ 20).
- **Export via CLI** using `design.md export <file> --format css-tailwind`.
- **Validate token names** automatically against CSS identifier rules (`/^[a-zA-Z0-9][a-zA-Z0-9-]*$/`).
- **Use programmatically** by importing `TailwindV4EmitterHandler` and `serializeToCss` from the `@google/design.md` package.
- **Consume in Tailwind v4** by importing the generated `@theme` block into your CSS entry point.

## Frequently Asked Questions

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

The [`design.md`](https://github.com/google-labs-code/design.md/blob/main/design.md) CLI requires **Node.js 20 or higher**, or alternatively Bun. This ensures native support for modern file system APIs and module resolution used in the export pipeline.

### Can I export DESIGN.md tokens to Tailwind v3 format?

The `css-tailwind` format specifically targets Tailwind v4's native `@theme` CSS block. For Tailwind v3, you would need to construct a JavaScript theme object manually or use a different emission strategy, as v3 does not support the CSS-based `@theme` syntax introduced in v4.

### What happens if my token names contain invalid characters?

The `TailwindV4EmitterHandler` validates all token names against the regex `/^[a-zA-Z0-9][a-zA-Z0-9-]*$/`. If a token name contains spaces, special characters, or starts with a hyphen, the export exits with a non-zero status code and displays an error message indicating which token failed validation.

### How do I import the generated CSS into a Tailwind v4 project?

Import the generated file into your main CSS entry point before the Tailwind directive. Tailwind v4 automatically scans imported CSS for `@theme` blocks and registers the custom properties as theme values:

```css
@import './tailwind-theme.css';
@import 'tailwindcss';

```