---
title: @specdiff/core API
description: Complete API reference for every public export in @specdiff/core v0.1.0.
url: https://pr-1-7cfcfe393d12.thally.app/specdiff-core-api
---

# @specdiff/core API

Complete API reference for every public export in @specdiff/core v0.1.0.

Complete API reference for `@specdiff/core` v0.1.0.

## Types

### Severity

```ts
type Severity = "breaking" | "warning" | "info";
```

### Direction

```ts
type Direction = "request" | "response" | "neutral";
```

Which side of an API contract a schema describes. Tightening a request schema
breaks clients that send the old shape, whereas tightening a response schema
gives clients stronger guarantees. Plain JSON Schema documents default to
`"neutral"`, which follows the request-side (validation-centric) reading.

### DocumentKind

```ts
type DocumentKind = "openapi" | "json-schema";
```

### RuleCode

```ts
type RuleCode = keyof typeof RULES;
```

A stable identifier for one of the 45 built-in rules, such as
`"property-removed"`.

### FailThreshold

```ts
type FailThreshold = Severity | "none";
```

Accepted by `exceedsThreshold` and the CLI `--fail-on` flag. `"none"` never
fails.

### SchemaChange

```ts
interface SchemaChange {
  code: RuleCode;
  severity: Severity;
  path: string;
  message: string;
  before?: unknown;
  after?: unknown;
}
```

A single classified difference. The `path` is an RFC 6901 JSON pointer into
the after document (or the before document for removals), always prefixed with
`#`.

### DiffSummary

```ts
interface DiffSummary {
  breaking: number;
  warning: number;
  info: number;
  total: number;
}
```

### DiffResult

```ts
interface DiffResult {
  changes: SchemaChange[];
  summary: DiffSummary;
  maxSeverity: Severity | null;
  kind: DocumentKind;
}
```

The complete, sorted outcome of comparing two documents. `maxSeverity` is
`null` when there are no changes.

### DiffOptions

```ts
interface DiffOptions {
  ignoreRules?: RuleCode[];
  overrides?: Partial<Record<RuleCode, Severity>>;
  ignorePaths?: string[];
  direction?: Direction;
}
```

| Key | Type | Default | Description |
| --- | --- | --- | --- |
| `ignoreRules` | `RuleCode[]` | `[]` | Rule codes whose changes are dropped entirely |
| `overrides` | `Partial<Record<RuleCode, Severity>>` | `{}` | Severity overrides keyed by rule code; wins over both default and direction table |
| `ignorePaths` | `string[]` | `[]` | JSON pointer prefixes to ignore; leading `#` is optional |
| `direction` | `Direction` | `"neutral"` | Direction for JSON Schema diffs; ignored for OpenAPI |

### RuleInfo

```ts
interface RuleInfo {
  code: RuleCode;
  defaultSeverity: Severity;
  title: string;
  description: string;
  remediation: string;
  appliesTo: DocumentKind | "both";
}
```

### FormatTextOptions

```ts
interface FormatTextOptions {
  color?: boolean;
}
```

When `color` is `true`, ANSI colour codes are emitted. Off by default.

### Resolved

```ts
interface Resolved {
  schema: unknown;
  ref: string | undefined;
  unresolved: string | undefined;
}
```

Outcome of resolving one node through `$ref` chains. `ref` is the `$ref` value
that was followed; `unresolved` is set when a `$ref` could not be resolved
locally.

---

## Constants

### SEVERITY_ORDER

```ts
const SEVERITY_ORDER: { breaking: 0; warning: 1; info: 2 };
```

Lower numbers are more severe.

### SEVERITIES

```ts
const SEVERITIES: readonly ["breaking", "warning", "info"];
```

### RULES

```ts
const RULES: Record<RuleCode, RuleInfo>;
```

Catalogue of every rule (45 entries) keyed by stable rule code.

### DIRECTION_SEVERITY

```ts
const DIRECTION_SEVERITY: Partial<Record<RuleCode, Record<Direction, Severity>>>;
```

Direction-dependent severities for the 12 rules whose meaning flips between
request and response. Rules absent from this table use their `defaultSeverity`
on every side.

---

## Diff functions

### diffJsonSchema

```ts
function diffJsonSchema(
  before: unknown,
  after: unknown,
  options?: DiffOptions,
): DiffResult;
```

Compares two JSON Schema documents.

### diffOpenApi

```ts
function diffOpenApi(
  before: unknown,
  after: unknown,
  options?: DiffOptions,
): DiffResult;
```

Compares two OpenAPI 3.x documents.

### diffDocuments

```ts
function diffDocuments(
  before: unknown,
  after: unknown,
  options?: DiffOptions,
): DiffResult;
```

Auto-detects the document kind (OpenAPI if either document has an `openapi`
key) and delegates to the appropriate diff function.

### detectDocumentKind

```ts
function detectDocumentKind(document: unknown): DocumentKind;
```

Returns `"openapi"` if the document has a string `openapi` key, otherwise
`"json-schema"`.

### exceedsThreshold

```ts
function exceedsThreshold(
  result: DiffResult,
  threshold: FailThreshold,
): boolean;
```

Returns `true` when the result contains at least one change at or above
`threshold`. `"none"` never returns `true`.

### finalize

```ts
function finalize(
  rawChanges: readonly SchemaChange[],
  kind: DocumentKind,
  options?: DiffOptions,
): DiffResult;
```

Applies options (ignored rules, ignored paths, severity overrides), sorts
changes, and wraps them into a `DiffResult`.

### summarize

```ts
function summarize(
  changes: readonly SchemaChange[],
): DiffSummary;
```

Computes per-severity counts.

### compareChanges

```ts
function compareChanges(a: SchemaChange, b: SchemaChange): number;
```

Sort comparator: severity (breaking first), then path, then code, then message.

---

## Rule functions

### explainRule

```ts
function explainRule(code: string): RuleInfo | undefined;
```

Looks up a rule by code. Returns `undefined` for unknown codes.

### listRules

```ts
function listRules(): RuleInfo[];
```

Returns the whole catalogue in stable catalogue order.

### isRuleCode

```ts
function isRuleCode(value: string): value is RuleCode;
```

Type guard for known rule codes.

### severityFor

```ts
function severityFor(code: RuleCode, direction: Direction): Severity;
```

Returns the severity a rule carries in a given direction before user overrides.
Consults `DIRECTION_SEVERITY` first, then falls back to `defaultSeverity`.

---

## Formatters

All formatters end with exactly one trailing newline.

### formatText

```ts
function formatText(
  result: DiffResult,
  options?: FormatTextOptions,
): string;
```

Human-readable text grouped by severity. ANSI colour is off unless
`color: true`.

### formatMarkdown

```ts
function formatMarkdown(result: DiffResult): string;
```

GitHub-flavoured Markdown with a summary table and per-severity tables.

### formatJson

```ts
function formatJson(result: DiffResult): string;
```

Pretty-printed JSON (`JSON.stringify(result, null, 2)` with trailing newline).

### summaryLine

```ts
function summaryLine(result: DiffResult): string;
```

One-line summary such as `"3 changes: 1 breaking, 1 warning, 1 info"` or
`"No changes detected."`.

### formatRulesMarkdown

```ts
function formatRulesMarkdown(): string;
```

The full rule catalogue as a Markdown table.

---

## JSON Pointer helpers

### escapePointerSegment

```ts
function escapePointerSegment(segment: string | number): string;
```

RFC 6901 escape: `~` becomes `~0`, `/` becomes `~1`.

### unescapePointerSegment

```ts
function unescapePointerSegment(segment: string): string;
```

Reverse of `escapePointerSegment`.

### joinPointer

```ts
function joinPointer(
  base: string,
  ...segments: Array<string | number>
): string;
```

Appends escaped segments to a pointer.

### parsePointer

```ts
function parsePointer(pointer: string): string[];
```

Splits a fragment pointer into decoded segments. Throws on invalid pointers.

### normalizePointer

```ts
function normalizePointer(pointer: string): string;
```

Normalizes varying prefix forms to `#/...`.

### pointerHasPrefix

```ts
function pointerHasPrefix(pointer: string, prefix: string): boolean;
```

Segment-aware prefix test.

### resolvePointer

```ts
function resolvePointer(document: unknown, pointer: string): unknown;
```

Walks a document by pointer; returns `undefined` when missing.

---

## Ref helpers

### isLocalRef

```ts
function isLocalRef(ref: string): boolean;
```

Returns `true` for `#/...` or `#` references.

### resolveNode

```ts
function resolveNode(
  document: unknown,
  node: unknown,
  maxDepth?: number,
): Resolved;
```

Follows a chain of local `$ref` values starting at `node`. `maxDepth` defaults
to 32; longer chains are treated as unresolved.

---

## Usage examples

### Ignoring specific rules

```ts
import { diffDocuments } from "@specdiff/core";

const result = diffDocuments(before, after, {
  ignoreRules: ["description-changed", "deprecated-added"],
});
```

### Overriding severity

```ts
import { diffDocuments, exceedsThreshold, formatMarkdown } from "@specdiff/core";

const result = diffDocuments(before, after, {
  overrides: { "default-changed": "breaking" },
});

console.log(formatMarkdown(result));
console.log(exceedsThreshold(result, "warning")); // true if warning+ exists
```

### Ignoring paths

```ts
import { diffDocuments } from "@specdiff/core";

const result = diffDocuments(before, after, {
  ignorePaths: ["#/paths/~1internal"],
});
```

### Direction-aware diffing

```ts
import { diffJsonSchema } from "@specdiff/core";

// Diff as a response schema: removing a required field is breaking,
// adding a required field is info
const result = diffJsonSchema(before, after, {
  direction: "response",
});
```