# How to Use the Programmatic API to Lint DESIGN.md Files

> Learn to use the programmatic API to lint DESIGN.md files with @google/design.md. Resolve tokens, run validation rules, and get a structured LintReport for efficient design system management.

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

---

**The `@google/design.md` package exports a `lint` function that parses DESIGN.md content, resolves design tokens into a typed model, runs configurable validation rules, and returns a structured `LintReport` containing findings, severity counts, and a Tailwind-compatible configuration.**

The [`google-labs-code/design.md`](https://github.com/google-labs-code/design.md/blob/main/google-labs-code/design.md) repository provides a self-contained linting engine for design system documentation. While the CLI handles file system operations, the programmatic API allows you to integrate DESIGN.md validation directly into CI pipelines, custom tooling, or editor extensions. This guide covers the core `lint` function and its supporting handlers as implemented in the TypeScript source.

## Importing the Linter Entry Point

The public API surface is exposed through the package's `linter` entry point. Import the `lint` function and associated types from `@google/design.md/linter` to begin processing DESIGN.md content programmatically.

```typescript
import { lint, type LintReport, type LintOptions } from '@google/design.md/linter';
import { readFileSync } from 'node:fs';

```

The main entry file at [`packages/cli/src/linter/index.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/index.ts) re-exports the core implementation from [`packages/cli/src/linter/lint.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/lint.ts) along with type definitions and rule helpers.

## Understanding the Linting Pipeline

When you invoke `lint(content, options?)`, the function executes a five-stage pipeline defined in [`packages/cli/src/linter/lint.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/lint.ts):

1. **Parsing** – `ParserHandler` reads the raw Markdown, extracts YAML front-matter (if present), and constructs a `ParsedDesignSystem` structure.
2. **Model resolution** – `ModelHandler` resolves token references, normalizes colors, dimensions, and typography into a fully typed `DesignSystemState`.
3. **Rule execution** – `runLinter` applies the `DEFAULT_RULES` set or any custom `LintRule`s supplied in options, aggregating findings and severity counts.
4. **Tailwind emission** – `TailwindEmitterHandler` generates a Tailwind-compatible theme configuration from the resolved design system.
5. **Report assembly** – Results are packaged into a `LintReport` containing findings, the model, Tailwind config, and a section map.

The function gracefully handles documents missing YAML front-matter by falling back to a simple heading scan (`extractSectionsFromContent`) and returning a warning-level finding rather than throwing an exception.

## Basic Linting Example

Load your DESIGN.md content and call `lint` to receive a complete validation report.

```typescript
// Load raw markdown content
const designMd = readFileSync('examples/totality-festival/DESIGN.md', 'utf8');

// Run the linter with default options
const report: LintReport = lint(designMd);

// Inspect results
console.log('Resolved tokens:', report.designSystem.tokens?.length ?? 0);
console.log('Findings:', report.findings.length);

report.findings.forEach(f => {
  console.log(`[${f.severity.toUpperCase()}] ${f.message}`);
});

// Access generated Tailwind configuration
console.log('Tailwind config:', JSON.stringify(report.tailwindConfig, null, 2));

```

## Customizing Validation Rules

Pass a `LintOptions` object to override the default rule set. Import `DEFAULT_RULES` and individual rules like `brokenRef` from [`packages/cli/src/linter/rules/index.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/rules/index.ts) to compose custom validation logic.

```typescript
import { DEFAULT_RULES, brokenRef } from '@google/design.md/linter';

const customOptions: LintOptions = {
  rules: [
    ...DEFAULT_RULES,
    // Add custom validation for broken references
    brokenRef,
  ],
};

const report = lint(designMd, customOptions);

```

## Advanced Programmatic Workflows

Beyond basic linting, the API exposes handlers for additional processing.

- **Programmatic fixing** – Import `fixSectionOrder` from [`packages/cli/src/fixer/handler.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/fixer/handler.ts) to reorder sections after linting.
- **DTCG export** – Use `DtcgEmitterHandler` (defined in [`packages/cli/src/dtcg/handler.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/dtcg/handler.ts)) to serialize the resolved design system to a token file format compatible with downstream tooling.

## Key Types and Source Files

Reference these core types when building integrations.

| Type | Description | Source Location |
|------|-------------|-----------------|
| `LintReport` | Complete result including findings, design system, and Tailwind config | [`packages/cli/src/linter/lint.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/lint.ts) |
| `LintOptions` | Configuration interface accepting custom rule arrays | [`packages/cli/src/linter/lint.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/lint.ts) |
| `Finding` | Individual issue with severity level and message | [`packages/cli/src/linter/spec.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/spec.ts) |
| `DesignSystemState` | Fully resolved design tokens model | [`packages/cli/src/model/spec.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/model/spec.ts) |

The rule execution logic resides in [`packages/cli/src/linter/runner.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/runner.ts), while the Tailwind configuration emitter is implemented in [`packages/cli/src/tailwind/handler.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/tailwind/handler.ts).

## Summary

- Import the `lint` function from `@google/design.md/linter` to validate DESIGN.md content programmatically.
- The **pipeline** parses Markdown, resolves tokens via `ModelHandler`, executes rules via `runLinter`, and generates Tailwind config via `TailwindEmitterHandler`.
- The function handles missing YAML front-matter gracefully by falling back to heading extraction with a warning.
- Customize validation by passing custom rules through the `LintOptions` interface.
- Access auxiliary handlers like `fixSectionOrder` and `DtcgEmitterHandler` for fixing and exporting operations.

## Frequently Asked Questions

### What happens if my DESIGN.md file lacks YAML front matter?

The `lint` function detects missing front-matter and automatically falls back to `extractSectionsFromContent` for basic heading analysis. It returns a warning-level finding in the report rather than throwing an error, allowing the linting process to continue with reduced metadata extraction.

### How do I add custom lint rules to the programmatic API?

Construct a `LintOptions` object with a `rules` array containing your custom `LintRule` implementations. Import the `DEFAULT_RULES` array from [`packages/cli/src/linter/rules/index.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/rules/index.ts) and spread it into your custom array alongside additional rules like `brokenRef` to extend or replace the default validation behavior.

### Can I export the linted design system to other formats?

Yes. After linting, use the `DtcgEmitterHandler` (located in [`packages/cli/src/dtcg/handler.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/dtcg/handler.ts)) to serialize the `DesignSystemState` into a DTCG (Design Tokens Community Group) compatible token file format for integration with other design tools and pipelines.

### Where is the lint function defined in the source code?

The `lint` function is implemented in [`packages/cli/src/linter/lint.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/lint.ts) and re-exported as the public API entry point in [`packages/cli/src/linter/index.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/index.ts). The function orchestrates the parsing, modeling, and rule execution phases while delegating specific tasks to specialized handlers like `ParserHandler` and `ModelHandler`.