# How to Lint a DESIGN.md File Using the CLI: Complete Validation Guide

> Lint DESIGN.md files with the CLI using npx @google-labs/design-cli lint. Validate structure, tokens, and Tailwind CSS for design system consistency. Ensure error-free development.

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

---

**Use `npx @google-labs/design-cli lint path/to/DESIGN.md` to validate structural correctness, token consistency, and Tailwind CSS theme generation, with the process exiting with code 1 if any errors are detected.**

The **design.md** repository by Google Labs ships a comprehensive command-line interface for validating [`DESIGN.md`](https://github.com/google-labs-code/design.md/blob/main/DESIGN.md) documents. When you need to lint a DESIGN.md file using the CLI, the tool executes an eight-stage pipeline that parses YAML front-matter, resolves design tokens into typed models, and validates document structure against configurable rules. This pure TypeScript toolchain enables integration into CI pipelines, pre-commit hooks, and local development workflows.

## Quick Start: Basic CLI Commands

Install and run the linter directly using `npx` without global installation:

```bash

# Lint a specific file with JSON output (default)

npx @google-labs/design-cli lint path/to/DESIGN.md

# Generate human-readable Markdown report

npx @google-labs/design-cli lint path/to/DESIGN.md --format markdown

# Pipe content from stdin for pipeline integration

cat path/to/DESIGN.md | npx @google-labs/design-cli lint - --format json

```

The positional `file` argument accepts a path to your [`DESIGN.md`](https://github.com/google-labs-code/design.md/blob/main/DESIGN.md) file or `-` to read from **stdin**. The `--format` flag supports `json` (default) or `markdown` (abbreviated as `md`) output styles.

## The Linting Pipeline Architecture

The CLI orchestrates a sophisticated validation pipeline defined across several modular components in `packages/cli/src/`.

### Entry Point and Input Handling

The **CLI entry point** lives in [`packages/cli/src/commands/lint.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/commands/lint.ts), which parses arguments and delegates to `readInput` in [`packages/cli/src/utils.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/utils.ts). This utility safely loads file contents or streams from `stdin`, ensuring the linter can process both local files and piped data.

### Document Parsing and Model Resolution

Once input is loaded, `ParserHandler` ([`packages/cli/src/linter/parser/handler.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/parser/handler.ts)) extracts YAML front-matter, markdown sections, and headings to build a `ParsedDesignSystem`. Immediately following, `ModelHandler` ([`packages/cli/src/linter/model/handler.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/model/handler.ts)) converts these parsed tokens into a strongly typed `DesignSystemState`, resolving references and validating token consistency.

### Rule Execution and Tailwind Generation

The **core linting logic** resides in `runLinter` within [`packages/cli/src/linter/linter/runner.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/linter/runner.ts). This function executes the default rule set (or a custom list if specified) and aggregates findings into severity levels: `error`, `warning`, and `info`. Default rules include validators like [`section-order.ts`](https://github.com/google-labs-code/design.md/blob/main/section-order.ts) which enforces proper heading hierarchy.

Simultaneously, `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)) generates a ready-to-use Tailwind CSS configuration object from the resolved design system state.

### Report Assembly and Formatting

The `lint` function in [`packages/cli/src/linter/lint.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/lint.ts) serves as the central orchestrator, merging model findings, linter results, and Tailwind output into a comprehensive `LintReport`. This report contains:

- `designSystem` – the fully resolved model
- `findings` – array of rule violations with severity levels
- `summary` – counts of errors, warnings, and info messages
- `tailwindConfig` – generated Tailwind theme object
- `sections` and `documentSections` – extracted markdown structure

Finally, `formatOutput` 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 either JSON or Markdown based on the `--format` flag.

## Input Methods and Output Formats

The CLI supports flexible input and output configurations for diverse workflows:

**Input Options:**
- **File path**: Direct path to [`DESIGN.md`](https://github.com/google-labs-code/design.md/blob/main/DESIGN.md) file
- **Stdin**: Use `-` as the file argument to read from standard input

**Output Formats:**
- **JSON** (default): Machine-readable format ideal for CI integration and automated processing
- **Markdown**: Human-readable format with formatted sections and findings

## Exit Codes and Automation Integration

The CLI uses process exit codes to signal results:

- **Exit 0**: No errors found (warnings and info may be present)
- **Exit 1**: One or more `error` findings detected

This behavior makes the tool immediately compatible with CI/CD pipelines and Git hooks. For example, in a [`package.json`](https://github.com/google-labs-code/design.md/blob/main/package.json) script:

```json
{
  "scripts": {
    "lint:design": "design-cli lint DESIGN.md --format json"
  }
}

```

Or in a GitHub Actions workflow step:

```yaml
- name: Validate Design System
  run: npx @google-labs/design-cli lint DESIGN.md --format markdown

```

## Summary

- The **design.md** CLI validates [`DESIGN.md`](https://github.com/google-labs-code/design.md/blob/main/DESIGN.md) files through an eight-stage pipeline including parsing, model resolution, rule execution, and Tailwind generation.
- **Entry point**: [`packages/cli/src/commands/lint.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/commands/lint.ts) coordinates the entire process through [`packages/cli/src/linter/lint.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/lint.ts).
- **Input flexibility**: Accepts file paths or stdin (`-`) via `readInput` in [`packages/cli/src/utils.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/utils.ts).
- **Output options**: JSON (default) for automation or Markdown for human review, controlled by `--format`.
- **Exit codes**: Returns `1` when errors are found, enabling seamless CI/CD integration.
- **Core components**: `ParserHandler`, `ModelHandler`, `runLinter`, and `TailwindEmitterHandler` work sequentially to produce the final `LintReport`.

## Frequently Asked Questions

### What does the linting process validate?

The CLI validates **structural correctness** (heading order, section requirements), **token consistency** (resolving design tokens into a typed `DesignSystemState`), and **Tailwind CSS theme generation** capabilities. The `runLinter` function in [`packages/cli/src/linter/linter/runner.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/linter/runner.ts) executes rules that check for errors, warnings, and informational issues across these domains.

### Can I integrate this into a CI/CD pipeline?

Yes. The CLI exits with status **1** when any `error` findings are reported, making it compatible with standard CI failure mechanisms. Use `--format json` for machine-readable output that automated systems can parse, or `--format markdown` for readable logs in build reports.

### How do I lint a DESIGN.md file from stdin?

Use the `-` character as the file argument: `cat DESIGN.md | npx @google-labs/design-cli lint - --format json`. The `readInput` utility in [`packages/cli/src/utils.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/utils.ts) handles both file streams and stdin safely, enabling pipeline integration with other tools.

### What is included in the LintReport output?

The `LintReport` generated by [`packages/cli/src/linter/lint.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/lint.ts) contains the fully resolved `designSystem` model, an array of `findings` with severity levels, a `summary` with error counts, a ready-to-use `tailwindConfig` object, and extracted `sections` and `documentSections` from the markdown structure.