---
title: @specdiff/cli Reference
description: Command-line reference for the specdiff CLI — compare documents, list rules, and gate CI pipelines.
url: https://pr-1-7cfcfe393d12.thally.app/specdiff-cli
---

# @specdiff/cli Reference

Command-line reference for the specdiff CLI — compare documents, list rules, and gate CI pipelines.

Command-line reference for `@specdiff/cli` v0.1.0. The binary is named
`specdiff`.

## Commands

### Compare two documents

```bash
specdiff <before> <after> [options]
```

Reads two JSON or YAML documents, detects their kind, computes the diff, and
writes the report to stdout (or to a file with `-o`).

### List rules

```bash
specdiff rules [--json]
```

Prints every rule with its default severity. Pass `--json` for
machine-readable output.

### Explain a rule

```bash
specdiff explain <code>
```

Prints the title, default severity, applies-to scope, description, and
remediation for a single rule.

### Help and version

```bash
specdiff --help
specdiff --version
```

---

## Compare flags

| Flag | Values | Default | Effect |
| --- | --- | --- | --- |
| `--format` | `text`, `json`, `markdown` | `text` | Report format |
| `--fail-on` | `breaking`, `warning`, `info`, `none` | `breaking` | Exit 1 when a change at or above this severity exists |
| `--ignore-rule` | rule code, repeatable | — | Drop changes from that rule |
| `--ignore-path` | JSON pointer prefix, repeatable | — | Drop changes at or beneath that pointer |
| `--kind` | `auto`, `openapi`, `json-schema` | `auto` | Force document kind |
| `--direction` | `request`, `response`, `neutral` | `neutral` | Direction for JSON Schema diffs (ignored for OpenAPI) |
| `--output` / `-o` | file path | — | Write report to file instead of stdout |
| `--no-color` | — | — | Disable ANSI colour in text output |
| `--color` | — | — | Force ANSI colour on |

Flags accept both `--flag value` and `--flag=value` syntax.

---

## Exit codes

| Code | Name | Meaning |
| --- | --- | --- |
| 0 | `ok` | No change at or above the `--fail-on` threshold |
| 1 | `thresholdExceeded` | At least one change meets or exceeds the threshold |
| 2 | `usage` | Usage error (bad flag, missing argument, unknown rule) |
| 3 | `inputError` | A document could not be read or parsed |

---

## Examples

```bash
# Basic comparison with default settings
specdiff old-api.yaml new-api.yaml

# JSON output, fail on warnings
specdiff before.json after.json --format json --fail-on warning

# Ignore description changes and a specific path
specdiff v1.yaml v2.yaml \
  --ignore-rule description-changed \
  --ignore-path "#/paths/~1internal"

# Write Markdown report to a file
specdiff before.yaml after.yaml --format markdown -o report.md

# Diff a JSON Schema as a response schema
specdiff request.json response.json --kind json-schema --direction response

# List all rules as JSON
specdiff rules --json

# Explain a single rule
specdiff explain enum-value-removed
```

---

## Programmatic API

The `@specdiff/cli` package exports its internals so other tools can embed the
CLI without spawning a child process.

### runCli

```ts
function runCli(
  argv: readonly string[],
  io: CliIo,
): Promise<number>;
```

Runs a command for the given argv (excluding the node and script entries) and
returns the exit code. Never calls `process.exit`.

### parseArgs

```ts
function parseArgs(argv: readonly string[]): ParsedCommand;
```

Parses argv into a command object. Throws a `UsageError` (an `Error` with
`name: "UsageError"`) on malformed input.

### EXIT_CODES

```ts
const EXIT_CODES: {
  ok: 0;
  thresholdExceeded: 1;
  usage: 2;
  inputError: 3;
};
```

### HELP_TEXT

```ts
const HELP_TEXT: string;
```

The full help string printed by `--help`.

### loadDocument

```ts
function loadDocument(
  filePath: string,
  cwd: string,
): Promise<unknown>;
```

Reads and parses a JSON or YAML document from disk. Throws
`DocumentLoadError` on failure.

### parseDocumentText

```ts
function parseDocumentText(
  text: string,
  fileName: string,
): unknown;
```

Parses text as JSON or YAML. The parser is chosen by file extension: `.json`
uses JSON, `.yaml`/`.yml` uses YAML. Other extensions try JSON first, then
YAML.

### createDocumentLoadError

```ts
function createDocumentLoadError(
  filePath: string,
  message: string,
): DocumentLoadError;
```

### isDocumentLoadError

```ts
function isDocumentLoadError(
  error: unknown,
): error is DocumentLoadError;
```

### CliIo

```ts
interface CliIo {
  stdout: (text: string) => void;
  stderr: (text: string) => void;
  cwd: string;
  isTty?: boolean;
}
```

- **`stdout`** — receives reports, rule listings, and help text.
- **`stderr`** — receives diagnostics and usage errors.
- **`cwd`** — directory relative input paths are resolved against.
- **`isTty`** — whether stdout is interactive; enables colour for text output
  unless `--no-color` is given.

### DocumentLoadError

An `Error` with `name: "DocumentLoadError"` and a `filePath: string` property.
Raised when an input document cannot be read or parsed.

---

## Programmatic usage example

```ts
import { runCli, type CliIo } from "@specdiff/cli";

const io: CliIo = {
  stdout: (text) => process.stdout.write(text),
  stderr: (text) => process.stderr.write(text),
  cwd: process.cwd(),
  isTty: process.stdout.isTTY === true,
};

const code = await runCli(
  ["before.yaml", "after.yaml", "--format", "json"],
  io,
);
process.exitCode = code;
```