# How to Compare Two DESIGN.md Files: CLI and Programmatic Guide

> Effortlessly compare two DESIGN.md files using CLI tools. Identify design token, component, and lint differences to prevent regressions with our comprehensive guide.

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

---

**TLDR:** The `design.md diff` command compares two DESIGN.md documents and reports differences in design tokens, components, and lint findings, exiting with code 1 if the newer file introduces regressions.

The design.md repository provides dedicated tooling to compare two DESIGN.md files and identify changes across design tokens and component definitions. Whether you are reviewing design system updates in CI pipelines or auditing changes between versions, the built-in diff functionality analyzes both the semantic content and lint status of your design documentation.

## Using the design.md diff CLI Command

The primary interface for comparing DESIGN.md files is the `design.md diff` command implemented in [`packages/cli/src/commands/diff.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/commands/diff.ts). This command orchestrates the entire comparison workflow using the `citty` command-definition library, providing automatic help generation and a clean command-line interface.

### Basic JSON Comparison

By default, the command outputs structured JSON showing added, removed, and modified tokens across both files.

```bash
design.md diff ./examples/paws-and-paths/DESIGN.md ./examples/totality-festival/DESIGN.md

```

### Human-Readable Markdown Output

Add the `--format markdown` flag to generate a human-readable report suitable for pull request descriptions or documentation.

```bash
design.md diff ./design1.md ./design2.md --format markdown

```

## How the Diff Engine Works

The comparison process follows a seven-step pipeline defined in the source code.

### Reading Input Files

The `readInput` helper in [`packages/cli/src/utils.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/utils.ts) loads each file from a supplied path or from STDIN (`-`). If a file cannot be read, the process exits with code 2 and prints a JSON error.

### Linting and Resolving Design Tokens

The `lint` function from [`packages/cli/src/linter/lint.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/lint.ts) parses the markdown, resolves the design-system model, and runs the default lint rules. It returns a `LintReport` containing fully resolved token maps and a summary of findings.

### Diffing Token Maps

The generic `diffMaps` utility in [`packages/cli/src/utils.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/utils.ts) walks two `Map<string, V>` objects and produces three arrays: `added`, `removed`, and `modified`. This utility handles colors, typography, rounded corners, spacing, and component definitions.

### Component Serialization

Because components are stored as `Map<string, ComponentDef>`, the command converts each component's property map into a plain object before applying `diffMaps`, as implemented in [`packages/cli/src/commands/diff.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/commands/diff.ts).

### Report Assembly and Exit Codes

The command builds a structured report containing per-token diffs, lint-finding changes, and a `regression` boolean flag. The `regression` flag is `true` when the "after" file contains more errors or warnings than the "before" file. The process exits with code 1 on regression, otherwise 0, enabling CI pipelines to detect breaking changes automatically. The `formatOutput` helper in [`packages/cli/src/utils.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/utils.ts) renders the report as JSON or Markdown based on the `--format` flag.

## Programmatic API for Comparing DESIGN.md Files

You can also compare files programmatically using the internal utilities exposed by the CLI package.

```typescript
import { readInput } from '@google/design.md/src/utils.js';
import { lint } from '@google/design.md/src/linter/index.js';
import { diffMaps } from '@google/design.md/src/utils.js';

// Load two files
const before = await readInput('path/to/before.md');
const after  = await readInput('path/to/after.md');

// Lint both files
const beforeReport = lint(before);
const afterReport  = lint(after);

// Diff token maps
const tokenDiff = {
  colors: diffMaps(beforeReport.designSystem.colors, afterReport.designSystem.colors),
  // …repeat for other token categories
};

// Inspect the diff
console.log('Added colors:', tokenDiff.colors.added);

```

## Summary

- Use `design.md diff` to compare two DESIGN.md files and identify changes in design tokens and components.
- The command exits with code 1 if the second file introduces lint regressions, enabling CI automation.
- The `diffMaps` utility in [`packages/cli/src/utils.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/utils.ts) generates added, removed, and modified arrays for any token category.
- Output formats include JSON (default) and Markdown via the `--format` flag.
- Programmatic access is available through `readInput`, `lint`, and `diffMaps` from the CLI package.

## Frequently Asked Questions

### What exit codes does design.md diff return?

The command returns exit code 0 for successful comparisons with no regressions, code 1 when the "after" file has more errors or warnings than the "before" file, and code 2 when input files cannot be read. This allows CI pipelines to automatically flag design system breaking changes.

### Can I compare DESIGN.md files from STDIN?

Yes. The `readInput` helper in [`packages/cli/src/utils.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/utils.ts) accepts `-` as a file path argument, allowing you to pipe content directly into the comparison. For example: `cat design.md | design.md diff - ./other.md`.

### What types of changes does the diff command detect?

The command detects changes in design tokens including colors, typography, spacing, and rounded corners, as well as component definitions. It reports additions, removals, and modifications, along with changes in lint findings across both files.

### How does the diff command handle component definitions?

Components are stored as `Map<string, ComponentDef>` objects. Before comparison, the command serializes each component's property map into a plain object, then applies the `diffMaps` utility to generate the added, removed, and modified arrays for the report.