# What Framework Powers the DESIGN.md CLI? Inside the Citty Architecture

> Discover the Citty architecture powering the DESIGN.md CLI. Explore this type-safe, lightweight framework for defining commands and sub-commands in this in-depth technical analysis.

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

---

**The DESIGN.md CLI is built entirely on top of the Citty command-line framework, a type-safe, lightweight library for defining commands and sub-commands.**

The DESIGN.md CLI, part of the [`google-labs-code/design.md`](https://github.com/google-labs-code/design.md/blob/main/google-labs-code/design.md) repository, provides a robust command-line interface for managing design system documentation. Understanding the underlying **DESIGN.md CLI framework** helps developers extend its functionality and adopt similar patterns for their own tools. At its core, the project leverages Citty to handle argument parsing, help generation, and command routing.

## Why Citty? The Core DESIGN.md CLI Framework

The CLI relies on **Citty** as its sole command-line framework. Unlike larger alternatives, Citty offers a minimal, type-safe API specifically designed for modern Node.js applications.

In [`packages/cli/src/index.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/index.ts), the entry point imports `defineCommand` and `runMain` directly from the `citty` package. These two functions form the backbone of the entire application structure. The `defineCommand` function creates type-safe command definitions, while `runMain` executes the command tree and handles process exit codes.

According to [`packages/cli/package.json`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/package.json), Citty is listed as a runtime dependency, cementing its role as the primary framework driving the interface.

## Architecture: How Citty Drives the CLI

The DESIGN.md CLI organizes functionality into modular sub-commands, all registered through Citty's unified API.

### Entry Point and Command Registration

The main entry point in [`packages/cli/src/index.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/index.ts) demonstrates Citty's declarative approach. It defines the root command with metadata and registers four sub-commands: `lint`, `diff`, `export`, and `spec`.

```typescript
import { defineCommand, runMain } from 'citty';
import { VERSION } from './version.js';
import lintCommand from './commands/lint.js';
import diffCommand from './commands/diff.js';
import exportCommand from './commands/export.js';
import specCommand from './commands/spec.js';

const main = defineCommand({
  meta: {
    name: 'design.md',
    version: VERSION,
    description: 'Agent‑first CLI for DESIGN.md — the hands and eyes for design system work.',
  },
  subCommands: {
    lint: lintCommand,
    diff: diffCommand,
    export: exportCommand,
    spec: specCommand,
  },
});

runMain(main);

```

### Sub-command Implementation Pattern

Each sub-command follows an identical pattern using `defineCommand`. The `lint` command in [`packages/cli/src/commands/lint.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/commands/lint.ts) illustrates how Citty handles positional arguments, optional flags, and async execution.

```typescript
import { defineCommand } from 'citty';
import { lint } from '../linter/index.js';
import { readInput, formatOutput, FileReadError } from '../utils.js';

export default defineCommand({
  meta: {
    name: 'lint',
    description: 'Validate a DESIGN.md file for structural correctness.',
  },
  args: {
    file: { type: 'positional', description: 'Path to DESIGN.md (use "-" for stdin)', required: true },
    format: { type: 'string', description: 'Output format: json or text', default: 'json' },
  },
  async run({ args }) {
    // Command implementation
  },
});

```

## Dependencies and Ecosystem

While Citty provides the CLI framework, the project combines it with specialized libraries for content processing. Alongside Citty, [`packages/cli/package.json`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/package.json) lists **unified**, **remark** plugins, and **zod** for schema validation.

Citty remains exclusively responsible for:

- Command-line argument parsing and validation
- Automatic help text generation
- Sub-command routing and execution
- Process exit code management

## Usage Examples

Once built, the CLI leverages Citty's automatic wiring to provide a seamless interface:

```bash

# Lint a DESIGN.md file

npx design.md lint path/to/file.md

# Export a DESIGN.md file to JSON

npx design.md export path/to/file.md --format=json

```

Citty automatically generates help menus and validates required arguments before executing the `run` function defined in each command file.

## Summary

- The **DESIGN.md CLI framework** is **Citty**, a type-safe command-line library for Node.js.
- The entry point in [`packages/cli/src/index.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/index.ts) uses `defineCommand` and `runMain` from Citty to bootstrap the application.
- Sub-commands like `lint`, `diff`, `export`, and `spec` are defined using Citty's declarative API in `packages/cli/src/commands/`.
- Citty handles argument parsing, help generation, and command routing automatically, allowing developers to focus on business logic.

## Frequently Asked Questions

### What is Citty?

Citty is a lightweight, type-safe command-line framework for Node.js that provides a minimal API for defining commands, sub-commands, arguments, and automatic help output. It is designed to be smaller and more modern than traditional CLI frameworks like Commander or Yargs.

### How does the DESIGN.md CLI use Citty for argument parsing?

The CLI defines arguments within each command's `defineCommand` configuration object. For example, in [`packages/cli/src/commands/lint.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/commands/lint.ts), the `args` property specifies positional arguments like `file` and optional flags like `format`, which Citty automatically parses and validates before passing to the `run` function.

### Can I extend the DESIGN.md CLI with custom commands?

Yes. Following the pattern in [`packages/cli/src/index.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/index.ts), you can create a new file in `packages/cli/src/commands/` that exports a `defineCommand` object, then register it in the `subCommands` object of the main command. Citty will automatically wire up the new command and its help text.

### What other libraries does the DESIGN.md CLI depend on besides Citty?

While Citty powers the CLI framework itself, the project also uses **unified** and **remark** plugins for Markdown processing, and **zod** for runtime schema validation. These handle the content parsing logic, while Citty manages the command-line interface layer.