# How to Schedule Exports with design.md: CLI Automation Guide

> Automate design.md exports with cron or CI/CD. Learn how to schedule recurring exports using the idempotent CLI command for efficient workflow management.

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

---

**The design.md CLI does not include built-in scheduling capabilities, but you can automate recurring exports using external schedulers like cron or CI/CD pipelines because the export command is idempotent and stateless.**

The [`design.md`](https://github.com/google-labs-code/design.md/blob/main/design.md) repository from Google Labs provides a stand-alone CLI for converting [`DESIGN.md`](https://github.com/google-labs-code/design.md/blob/main/DESIGN.md) files into design token formats, but it lacks internal scheduling functionality. To run exports on a recurring basis, you must orchestrate the CLI yourself using external automation tools. This guide explains the export pipeline internals and provides practical examples for scheduling exports in production environments.

## Understanding the Export Command Architecture

The export functionality is implemented in [[`packages/cli/src/commands/export.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/commands/export.ts)](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/commands/export.ts). The command provides **no built-in scheduling facility**—its arguments are limited to the source file path, the output format, and an optional CSS prefix. The CLI is designed to be **idempotent and fast**, processing a single export request and exiting immediately, which makes it safe to invoke repeatedly from external schedulers.

## How the Export Pipeline Works

The export process follows a deterministic five-step pipeline:

1. **Argument validation** – The command validates that the requested format matches one of the closed enum values (`css-tailwind`, `json-tailwind`, `tailwind`, `dtcg`, `css-vars`). The validation check occurs at lines 49-57:

   ```ts
   if (!FORMATS.includes(format as ExportFormat)) { … }
   ```

2. **Input reading** – The CLI reads the [`DESIGN.md`](https://github.com/google-labs-code/design.md/blob/main/DESIGN.md) file (or stdin) via the `readInput` function from [[`packages/cli/src/utils.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/utils.ts)](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/utils.ts#L42-L68).

3. **Linting** – The content is parsed and linted using `lint(content)` to produce a `DesignSystemState`.

4. **Emitter selection** – Based on the format, the appropriate emitter handler is instantiated. The source code at lines 84-86 demonstrates the handler pattern:

   ```ts
   const handler = new TailwindEmitterHandler();
   const result = handler.execute(report.designSystem);
   ```

   Available handlers include `TailwindEmitterHandler`, `TailwindV4EmitterHandler`, `CssVarsEmitterHandler`, and `DtcgEmitterHandler` (re-exported from [[`packages/cli/src/linter/index.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/index.ts)](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/index.ts)).

5. **Result handling** – On success, the emitter output is transformed (via `JSON.stringify`, `serializeTailwindV4`, or `serializeCssVars`) and written to stdout.

The command exits with specific status codes defined at lines 118-124: `0` for success, `1` for invalid format or emitter errors, and `2` if the source file cannot be read.

## Scheduling Methods for design.md Exports

Because the CLI has no internal scheduler, you must use external orchestration to run exports on a schedule.

### Method 1: Cron-Based Scheduling

Add the following entry to your crontab (`crontab -e`) to run nightly exports at 02:00 UTC:

```cron
0 2 * * * cd /path/to/project && \
  npx @google/design.md export --format css-tailwind DESIGN.md > /var/www/assets/theme.css

```

This approach runs the CLI outside of your main application, redirecting output to your asset directory. The idempotent design ensures repeated executions remain safe.

### Method 2: CI/CD Pipeline Automation (GitHub Actions)

Trigger exports automatically when your design tokens change:

```yaml
name: Export Design Tokens
on:
  push:
    paths:
      - '**/DESIGN.md'
jobs:
  export:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npx @google/design.md export --format dtcg DESIGN.md > tokens.json
      - uses: actions/upload-artifact@v4
        with:
          name: dtcg-tokens
          path: tokens.json

```

This workflow regenerates DTCG JSON output every time a [`DESIGN.md`](https://github.com/google-labs-code/design.md/blob/main/DESIGN.md) file changes, storing artifacts for downstream consumption.

### Method 3: Manual One-Off Exports

For ad-hoc generation, invoke the CLI directly:

```bash

# Export to Tailwind v3 JSON (theme.extend)

npx @google/design.md export --format json-tailwind DESIGN.md > tailwind.theme.json

```

## Supported Export Formats and Handlers

The CLI supports five export formats, each handled by a specific emitter class:

- **`json-tailwind`** – Emits Tailwind v3 compatible JSON theme extensions via `TailwindEmitterHandler` ([[`packages/cli/src/linter/tailwind/handler.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/tailwind/handler.ts)](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/tailwind/handler.ts))
- **`css-tailwind`** – Generates Tailwind v4 CSS variables via `TailwindV4EmitterHandler` ([[`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)](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/tailwind/v4/handler.ts))
- **`dtcg`** – Outputs W3C Design Token Community Group format via `DtcgEmitterHandler` ([[`packages/cli/src/linter/dtcg/handler.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/dtcg/handler.ts)](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/dtcg/handler.ts))
- **`css-vars`** – Produces CSS custom properties via `CssVarsEmitterHandler`
- **`tailwind`** – Legacy Tailwind format support

## Summary

- The design.md CLI is **stateless and idempotent**, making it safe for automated scheduling.
- **No built-in scheduler exists** in [`packages/cli/src/commands/export.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/commands/export.ts); all scheduling must be external.
- Use **cron jobs** for server-based automation or **GitHub Actions** for CI/CD integration.
- The CLI returns specific exit codes (`0`, `1`, `2`) for programmatic error handling.
- All five export formats (`css-tailwind`, `json-tailwind`, `dtcg`, `css-vars`, `tailwind`) support automation equally via their respective emitter handlers.

## Frequently Asked Questions

### Can I schedule exports directly within the design.md CLI?

No, the CLI in [`packages/cli/src/commands/export.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/commands/export.ts) processes single export requests and immediately exits. It has no daemon mode, internal timer, or watch functionality. You must use external schedulers like cron, GitHub Actions, or other task runners to invoke the command repeatedly.

### What exit codes does the export command return?

The command returns three specific exit codes defined at lines 118-124 of [`export.ts`](https://github.com/google-labs-code/design.md/blob/main/export.ts): `0` indicates successful completion, `1` indicates invalid format or emitter errors (when the format argument is not in the `FORMATS` array), and `2` indicates the source file could not be read via `readInput`.

### Is it safe to run multiple design.md exports concurrently?

Yes, the CLI is designed to be deterministic and stateless, with no shared state between invocations. You can safely run multiple export commands in parallel through overlapping cron schedules or parallel CI jobs without risk of file corruption or race conditions.

### Which export formats support scheduled automation?

All supported formats—`css-tailwind`, `json-tailwind`, `tailwind`, `dtcg`, and `css-vars`—support automation equally. The scheduling mechanism operates at the process level (cron or CI), while the format-specific logic resides in individual emitter handlers (`TailwindEmitterHandler`, `DtcgEmitterHandler`, etc.) that all follow the same idempotent execution pattern.