How to Compare Two DESIGN.md Files: CLI and Programmatic Guide
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. 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.
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.
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 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 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 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.
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 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.
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 diffto 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
diffMapsutility inpackages/cli/src/utils.tsgenerates added, removed, and modified arrays for any token category. - Output formats include JSON (default) and Markdown via the
--formatflag. - Programmatic access is available through
readInput,lint, anddiffMapsfrom 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 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →