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

@adrkit/cli

v0.14.0

Published

Git-native architecture decision record tooling from adrkit.

Downloads

3,601

Readme

@adrkit/cli

Git-native architecture decision record tooling from adrkit.

Install and run

Use the package name for zero-install runs. The published binary is adr, but a bare npx adr resolves an unrelated npm package:

npx @adrkit/cli lint

For project use, add it as a dev dependency and invoke it through a script:

npm install --save-dev @adrkit/cli    # or: bun add --dev @adrkit/cli
npm pkg set scripts.adr=adr
npm run adr -- lint

That keeps you on the installed local binary instead of whatever npx adr might download from the registry.

You can also install it globally:

npm install -g @adrkit/cli
adr lint

Every install also provides adrkit, an identical alias for the same binary. Prefer adrkit in CI, Makefiles, and agent instructions because its name is unambiguous:

adrkit lint

Do not use npx adrkit or bunx adrkit. There is no unscoped adrkit package, so those forms would resolve against the registry rather than the published @adrkit/cli package.

Human-readable CLI output is TTY-aware: it stays ANSI-free when redirected or piped, honors NO_COLOR, and can be forced with --color auto|always|never.

Commands

The binary includes:

  • new
  • lint
  • graph
  • explain
  • check
  • queue
  • migrate --from madr
  • completion
  • evaluate

Run adr --help for the command list, adr help <command> for one command's flags, and adr --version to print the installed version.

Decision graph

adr graph chooses its default at the stdout boundary: an interactive terminal gets a compact status and relationship view, while a pipe, redirect, or captured subprocess keeps receiving deterministic Graphviz DOT. Pin a channel whenever another tool consumes the output:

adr graph                                  # terminal view on a TTY; DOT in a pipe
adr graph --focus 0014                     # one ADR and its direct neighborhood
adr graph --kind supersedes                # one relationship kind
adr graph --format mermaid > decisions.mmd
adr graph --format dot | dot -Tsvg > decisions.svg
adr graph --format json > decisions.json

--kind is repeatable and accepts supersedes, relatesTo, and conflictsWith. Explicit --format terminal|dot|json|mermaid always overrides TTY selection. DOT, Mermaid, and JSON remain ANSI-free even with forced color. Large sparse and focused terminal views are bounded; use another --kind or a machine format for the complete edge set.

If one or more corpus records are invalid, graph still emits the complete projection of every valid record, writes the error findings to stderr, and exits 1. Exit 0 means rendered without corpus errors; exit 2 remains a usage or unreachable-directory error.

Shell completions

adr completion <bash|zsh|fish> prints a deterministic completion script to stdout. The generated script registers both adr and adrkit where the shell format permits.

adr completion bash > ~/.local/share/bash-completion/completions/adr
cp ~/.local/share/bash-completion/completions/adr ~/.local/share/bash-completion/completions/adrkit
adr completion zsh > ~/.zsh/completions/_adr
cp ~/.zsh/completions/_adr ~/.zsh/completions/_adrkit
adr completion fish > ~/.config/fish/completions/adr.fish
cp ~/.config/fish/completions/adr.fish ~/.config/fish/completions/adrkit.fish

If you prefer symlinks, point both Fish entry points at the same generated file:

ln -sf ~/.config/fish/completions/adr.fish ~/.config/fish/completions/adrkit.fish

Inbound @adr markers

adr explain <path> and adr check <files...> resolve decisions in both directions. A record declares the paths it governs with affects; a source file can declare the decision it lives under with a comment marker:

// @adr 0012
export function syncOnce() { /* ... */ }
$ adr explain src/services/sync/retry.ts
Decisions governing src/services/sync/retry.ts:
  0009  [accepted] Resolve affects deterministically
    via path: src/services/sync/**
  0012  [accepted] Bind catalog entities to owned paths
    declared by src/services/sync/retry.ts:1 (@adr 0012)

Marker scanning is intentionally narrow:

  • only the first 8192 bytes of a file are considered
  • the scan stops at the last complete line inside that window
  • at most the first 64 declarations per file are retained
  • the marker must be the first content on a dedicated comment line
  • lines inside fenced code blocks are ignored
  • markdown files (.md, .mdx, .markdown) accept only <!-- and {/*

Nothing is written back to the record.

A marker that names a superseded, rejected, or deprecated record still resolves to that historical record and emits an advisory stale-marker warning. For a superseded chain, the warning names the terminal live successor when one can be resolved; adrkit never silently substitutes it. The warning does not affect the exit code.

Under --as-of, a marker naming a record that was in force on that date is not stale — it was an accurate declaration then. The present-tense warning is unchanged.

Time travel: adr explain --as-of

adr explain <path> --as-of <date|ref> answers which decisions governed a path on a past date. Every record carries a date, and a superseded record names its successor, so a valid-time window is derivable with no schema change: it opens on the record's own date and closes on its immediate successor's.

$ adr explain src/auth/session.ts --as-of 2026-03-01
As of 2026-03-01
Note: matchers and @adr markers are read from today’s corpus and working tree; only standing is re-dated.
Decisions governing src/auth/session.ts as of 2026-03-01:
  0007  [superseded] Use JWT sessions (superseded by 0019)
    in force 2026-01-15 → 2026-06-01 (closed by 0019)
    via path: src/auth/**
Not yet recorded as of 2026-03-01:
  0019  [accepted] Use opaque server sessions
    recorded 2026-06-01

The status in brackets is the record's status now; the window underneath is what placed it. Both are true, and a reader needs both. The note under the header is there because the evidence lines (via path:, declared by …) are read from today's corpus and today's file — they are the one thing --as-of does not re-date.

  • The value is a date first, a git ref second. YYYY-MM-DD or an ISO datetime with an explicit timezone is read as a date; anything else is resolved with git rev-parse --verify <ref>^{commit} in the current directory and dated by that commit's committer date. A tag named 2026-03-01 therefore reads as a date, not as that tag.
  • Windows are half-open. The successor owns its own start day, so exactly one record along a supersession chain is in force on any given date.
  • deprecated is reported as undetermined, not guessed at. The schema allows supersededBy only on superseded, so a deprecated record records no date it stopped governing. Saying so is the honest answer; a rejected record is history on every date, because it was in force on none.
  • --as-of re-dates the corpus, never the working tree. Which decisions reach the path is still read from today's records and today's file contents. Reading file contents at a past ref is a larger contract and is not attempted.
  • It is additive. Without the flag, output is unchanged. With it, --json gains an asOf block and the present-tense governing, activeProposals, and history keys keep their meaning (ADR-0039).

In --json, pattern matches appear in firedMatchers and file declarations in declaredBy. explain --json includes a single-file markers block plus scannedBytes, fileBytes, and exact retained/omitted declaration counts. check --json includes a markerScan report with state counts; exact unavailable, truncated, and skipped paths; and aggregate declaration counts.

Multi-file scans are capped at 3,000 normalized paths with 16 concurrent reads, and retain at most the first 10,000 declarations in code-unit path then source order. Skipped paths and declaration overflow each collapse to one bounded warning; neither they nor marker claims can change the exit code.

See the commands reference.

The published ESM CLI runs on Node.js 22 or newer; development in the adrkit repository uses Bun.

See also @adrkit/mcp, a local read-only Model Context Protocol server that exposes the same corpus to coding agents.

Documentation: https://adrkit.dev

License: Apache-2.0