npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@yuesu4/specdrift-codex-b

v0.1.0

Published

Diff OpenAPI 3.x specifications and identify breaking API changes

Readme

specdrift

CI npm

specdrift compares two OpenAPI 3.x documents and reports contract drift. It reads JSON or YAML from local paths and HTTPS URLs, resolves local $ref pointers while comparing schemas, emits human or stable machine-readable output, and exits non-zero when the configured severity threshold is reached.

Install

npm install --global @yuesu4/specdrift-codex-b

Node.js 20 or newer is required.

CLI

specdrift <old-spec> <new-spec> [options]

Options:
  --format <text|json>                  Output format (default: text)
  --fail-on <breaking|additive|informational>
                                        Lowest severity that exits 1 (default: breaking)
  --no-cache                            Bypass the on-disk HTTPS cache
  -h, --help                            Show help
  -v, --version                         Show version

Both inputs may independently be a local JSON/YAML file or an https:// URL. HTTP is deliberately rejected so remote API contracts are not downloaded in clear text.

# Human-readable diff; fail only for breaking changes
specdrift openapi-v1.yaml openapi-v2.yaml

# Stable JSON; fail for additive or breaking changes
specdrift https://example.com/v1.json ./v2.yaml --format json --fail-on additive

# Always re-download remote inputs
specdrift OLD_URL NEW_URL --no-cache

Text is coloured only when stdout is a TTY; set NO_COLOR=1 to disable colour explicitly. Exit code 0 means the threshold was not met, 1 means it was, and 2 means the inputs or command line were invalid. The default --fail-on breaking makes the command directly useful as a CI gate.

Severity thresholds are inclusive:

| --fail-on | Exits 1 for | | --- | --- | | breaking | breaking | | additive | additive, breaking | | informational | informational, additive, breaking |

What is detected

  • Paths and HTTP methods added or removed
  • Parameters added or removed, retyped, or changed between optional and required
  • Request bodies added, removed, or changed between optional and required
  • Request and response properties added, removed, retyped, or changed between optional and required
  • Response status codes added or removed
  • Effective operation security requirements changed, including inherited root requirements

Nested object and array properties are reported with paths such as owner.login and items[].id. Local OpenAPI component references are followed with cycle protection. External $ref documents are not downloaded; bundle them first when their schemas need to be compared. For each content map, application/json is preferred and otherwise the lexically first media type is compared.

Severity taxonomy

Every change includes a severity and a short reason. The taxonomy is intentionally consumer-oriented: if a previously valid request may be rejected, or a previously documented response can no longer be safely consumed, the change is breaking.

| Change | Severity | Reasoning | | --- | --- | --- | | Remove path or method | breaking | Existing calls lose their target. | | Add path or method | additive | Existing operations are unchanged. | | Add required request parameter/body/property | breaking | Existing clients do not send it. | | Add optional request parameter/body/property | additive | Existing requests remain valid. | | Remove request parameter/body/property | breaking | Existing clients may still send it. | | Make request input required | breaking | Existing clients may omit it. | | Make request input optional | additive | The accepted request set expands. | | Add response property or status | additive | A response capability is added without removing an existing one. | | Remove response property or status | breaking | Clients may depend on the documented result. | | Make response property optional | breaking | Clients can no longer assume it is present. | | Make response property required | breaking | Strict validators observe a stronger contract constraint. | | Retype parameter or schema property | breaking | Existing encoded values or decoders may be incompatible. | | Change effective security requirements | breaking | Authentication/authorization assumptions may no longer hold. |

informational is reserved in result schema 1.0 for future non-contract metadata detectors. It is accepted now as the lowest failure threshold so consumers do not need a CLI change when those detectors arrive.

JSON output

--format json emits a deterministic object. schemaVersion versions this public contract; new fields may be added compatibly, while a breaking shape change will increment it.

{
  "schemaVersion": "1.0",
  "changes": [
    {
      "category": "parameter.required",
      "severity": "breaking",
      "location": {
        "path": "/pets",
        "method": "GET",
        "parameter": "query:limit"
      },
      "message": "parameter query:limit became required",
      "reason": "Existing requests may omit the parameter."
    }
  ],
  "summary": {
    "total": 1,
    "breaking": 1,
    "additive": 0,
    "informational": 0
  },
  "hasBreakingChanges": true
}

Changes are ordered by path, method, and comparison category traversal so the same documents produce stable output.

URL cache

Successful HTTPS responses are cached by a SHA-256 digest of their URL. The default directory is $XDG_CACHE_HOME/specdrift, or ~/.cache/specdrift when XDG_CACHE_HOME is unset. A repeat run parses the cached bytes without another request. --no-cache bypasses both cache reads and writes. The library API also accepts cacheDir for isolated CI caches.

Real-world verification

The release was verified on 2026-08-25 against two dated, publicly available versions of GitHub's REST API OpenAPI description: 2022-11-28 and 2026-03-10. Both URLs returned HTTP 200. The actual report contained 1,378 changes, so this worked example shows its first findings and complete summary:

specdrift \
  https://raw.githubusercontent.com/github/rest-api-description/8114b0d0e23240dfe45374e2daf01651a4729210/descriptions/api.github.com/api.github.com.2022-11-28.yaml \
  https://raw.githubusercontent.com/github/rest-api-description/8114b0d0e23240dfe45374e2daf01651a4729210/descriptions/api.github.com/api.github.com.2026-03-10.yaml
BREAKING (1371)
[!] GET / · response 200 · authorizations_url — response property authorizations_url was removed
    Existing clients may depend on this response property.
[!] GET / · response 200 · hub_url — response property hub_url was removed
    Existing clients may depend on this response property.
[!] DELETE /app/installations/{installation_id} · response 204 — response status 204 was removed
    Clients may rely on handling this documented response.
… 1368 more breaking changes

ADDITIVE (7)
[+] DELETE /app/installations/{installation_id} · response 202 — response status 202 was added
    The operation documents an additional outcome without removing an existing one.
… 6 more additive changes

Summary: 1371 breaking, 7 additive, 0 informational.

The opt-in npm run test:live test also fetches GitHub's current public document through the same loader. Ordinary npm test uses deterministic fixtures and a controlled Fetch response, so CI is not coupled to an external service.

Library API

The package ships ESM JavaScript and TypeScript declarations.

import { diffSources, diffSpecs, formatText, loadSpec } from '@yuesu4/specdrift-codex-b';

const oldDocument = await loadSpec('./old.yaml');
const newDocument = await loadSpec('https://example.com/new.yaml');

const pureResult = diffSpecs(oldDocument, newDocument); // synchronous, no I/O
const loadedResult = await diffSources('./old.yaml', './new.yaml', {
  cache: true,
  cacheDir: '/tmp/specdrift-cache',
});

console.log(formatText(loadedResult));

Public values:

  • loadSpec(source, options?) loads and validates one OpenAPI 3.x document.
  • diffSpecs(oldDocument, newDocument) performs a deterministic in-memory comparison.
  • diffSources(oldSource, newSource, options?) loads both inputs concurrently and compares them.
  • formatText(result, colour?) renders the human-readable form.
  • Types include Change, ChangeCategory, ChangeLocation, ChangeSummary, DiffResult, LoadOptions, OpenApiDocument, and Severity.

Development

npm ci
npm run lint
npm run typecheck
npm test
npm run build
npm run docs

CI runs lint, type checking, and tests on Node.js 20 and 22. Releases publish the scoped package with npm provenance, and the documentation site is rebuilt from this README.

License

MIT