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

pre-commit-readme-enforcer

v1.4.0

Published

Pre-commit hook: stage nearest companion docs with code changes; optional custom doc patterns, warn-only mode, and root README reachability over relative Markdown links

Readme

pre-commit-readme-enforcer

Git pre-commit hook: if you stage non-README code, you should also stage the nearest README for each changed path (same directory, then parents). By default a miss blocks the commit; optional warn-only mode prints the same guidance but lets the commit proceed (Configuration). No config required for the default check.

Prerequisites: Node.js 18+, npm, and git (Husky 9 needs Node 18). The check-readme-updated script alone may run on older Node if you wire hooks without Husky.

Using the hook in your repo → commands below. Contributing to this project → Development.

Install (npm + Husky)

In your project root:

npm install --save-dev pre-commit-readme-enforcer husky
npx husky
echo "npx check-readme-updated" > .husky/pre-commit

On macOS or Linux you may optionally run chmod +x .husky/pre-commit. On Windows, use the hook line above as-is — see Windows (consumer repos).

Stage code and the README paths the hook names, or the commit stops with a short list of what is missing (unless warn-only mode is enabled).

Teams / CI

Add "prepare": "husky" under scripts in your package.json so npm install on a fresh clone keeps Husky’s core.hooksPath wired. In CI or other environments where hooks should not run, set HUSKY=0.

Usage

The hook runs on git commit when Husky is active.

git add src/feature.ts
git commit -m "feature"   # default: fails until required README files are staged too

git add src/README.md     # after you edit them (paths the hook prints)
git commit -m "feature"   # succeeds

With warn-only mode enabled, the first commit prints a warning (including ⚠ README review suggested) but still succeeds if nothing else fails the hook.

On Windows, use the same git commands from Git Bash, PowerShell, or cmd. See Windows (consumer repos).

Windows (consumer repos)

For developers using this hook in their own project on Windows (not contributing to this package).

Prerequisites: Node.js 18+, npm, and Git for Windows. Run git and npm from your repository root. Husky runs hooks via Git’s shell — installing Git is enough for typical setups.

Install and create the pre-commit hook

npm install --save-dev pre-commit-readme-enforcer husky

PowerShell

npx husky
Set-Content -Path .husky/pre-commit -Value "npx check-readme-updated" -NoNewline
Add-Content -Path .husky/pre-commit -Value "`n"

cmd

npx husky
echo npx check-readme-updated> .husky\pre-commit

Git Bash / macOS / Linux

npx husky
echo "npx check-readme-updated" > .husky/pre-commit

Optional on Unix only: chmod +x .husky/pre-commit.

Add to your app’s package.json so hooks install on clone:

"scripts": {
  "prepare": "husky"
}

Daily usage

git add src/feature.ts
git commit -m "feature"

If the commit fails (default mode), the hook lists README paths using forward slashes (e.g. src/README.md). Stage those files, then commit again:

git add src/README.md
git commit -m "feature"

Manual check

npx check-readme-updated

If you copied the script into the repo, use node check-readme-updated.js (not ./check-readme-updated.js in cmd — Windows cmd does not run shebangs).

Opt-in warn-only mode on Windows

Prefer a CLI flag in .husky/pre-commit (works in every shell):

npx check-readme-updated --warn

Or set "readmeEnforcer": { "mode": "warn" } in package.json. See Configuration.

Opt-in README reachability on Windows

Prefer a CLI flag in .husky/pre-commit (works in every shell):

npx check-readme-updated --enforce-readme-interlink

One-off manual run with an environment variable:

PowerShell

$env:README_ENFORCE_INTERLINK = "1"
npx check-readme-updated

cmd

set README_ENFORCE_INTERLINK=1
npx check-readme-updated

Git Bash

README_ENFORCE_INTERLINK=1 npx check-readme-updated

CI and disabling hooks

PowerShell: $env:HUSKY = "0"
cmd: set HUSKY=0
bash: export HUSKY=0

Verify on Windows

  1. Change a tracked file, git add it, run git commit — expect failure with listed README paths (forward slashes), unless warn-only mode is on (then expect a warning and success).
  2. Edit and git add those READMEs, commit again — expect success with no warning.

Windows troubleshooting

| Issue | What to try | |--------|-------------| | Hook never runs | Run npx husky from the repo root; confirm .husky/pre-commit exists and .husky/_/ contains hook shims (e.g. .husky/_/pre-commit). An empty .husky/_/ means Husky was never installed — run npx husky again | | node / npm not found | Install Node.js, restart the terminal, check PATH | | README staged but hook still fails | Upgrade to 1.1.1+ (path normalization fix); ensure paths match what git status shows | | ./check-readme-updated.js fails in cmd | Use node check-readme-updated.js or npx check-readme-updated |

Verify

  1. Change a tracked file under your repo, git add it, try git commit — expect failure with listed README paths (default), or a warning and success (warn-only).
  2. Edit and git add those READMEs, commit again — expect success.

Run the checker by hand: npx check-readme-updated (from a devDependency install) or node check-readme-updated.js if you copied the script. On Windows, see Windows (consumer repos).

How it works

  1. Looks at staged non–companion-doc files (companion docs = readme* by default, plus optional readmeEnforcer.docs patterns).
  2. For each, walks up directories to the first folder containing any matching companion doc.
  3. Requires every matching companion doc in that directory to be staged with a change when any of those code paths are staged — or warns and exits 0 when warn-only mode is enabled.
  4. Prints which companion doc paths to review; in default mode the commit is blocked until they are staged.

Other ways to install

Global CLI + Husky

npm install -g pre-commit-readme-enforcer

Then in each repo:

npm install --save-dev husky
npx husky
echo "npx check-readme-updated" > .husky/pre-commit

One-off check (no git hook)

npx pre-commit-readme-enforcer

Copy the built script

Clone, build, copy check-readme-updated.js into your project, then point .husky/pre-commit at it, for example:

echo "node check-readme-updated.js" > .husky/pre-commit

(Use npm install --save-dev husky and npx husky first if Husky is not set up. On Windows, see Windows (consumer repos).)

Python pre-commit framework

Requires Node on the machine (hook is JS).

repos:
  - repo: https://github.com/taidaid/pre-commit-readme-enforcer
    rev: main  # pin a tag or commit in real projects
    hooks:
      - id: check-readme-updated
        args: [--warn]  # optional; omit for default hard-fail

Or with reachability:

repos:
  - repo: https://github.com/taidaid/pre-commit-readme-enforcer
    rev: main
    hooks:
      - id: check-readme-updated
        args: [--enforce-readme-interlink]

Configuration

No config is required for the default staged-README check. Optional ignore rules let you skip the nearest-README requirement for certain paths (generated code, lockfiles, vendored deps, and so on). Ignore rules apply only to the staged-README check, not to opt-in README reachability.

Optional: warn-only mode (staged-README check)

By default, a missing nearest README blocks the commit. In warn-only mode the hook uses the same detection but exits 0 so commits can proceed (useful when READMEs should capture durable contracts, not routine implementation inventories).

Example warn-only output:

⚠ README review suggested (warn-only mode — commit not blocked).
Code files staged for commit: 1
Nearest README file(s) not staged with your code changes: 1

The following README files are closest to your staged code changes:
  - src/README.md

Update co-located README(s) only if durable contract changed
(boundaries, invariants, env/ops gotchas, glossary, ADR-worthy decisions).
Otherwise you may proceed.

Default (hard-fail) mode uses ❌ README update required! and suggests concrete README edits instead of the durable-contract footer above.

Enable in Husky (recommended — all platforms):

npx check-readme-updated --warn

Enable with an environment variable in .husky/pre-commit:

README_ENFORCER_MODE=warn npx check-readme-updated

Enable in package.json:

{
  "readmeEnforcer": {
    "mode": "warn"
  }
}

Precedence: CLI flag (--warn / --warn-only) → README_ENFORCER_MODE env var → package.json readmeEnforcer.mode. Accepted warn values: warn, warn-only, warn_only. Accepted fail values: fail, error, strict. Default when unset: fail.

Warn mode applies only to the staged nearest-README check, not to opt-in README reachability.

Optional: ignore paths (staged-README check)

Define patterns in either or both of:

  • .readme-enforcerignore at the repository root — one pattern per line; # starts a comment; blank lines are ignored.
  • package.json — "readmeEnforcer": { "ignore": ["vendor/", "*.lock"] }

When both exist, patterns are merged (union). Invalid package.json (parse error or non-array ignore) is skipped so a broken manifest does not block commits.

.readme-enforcerignore example:

# Vendored and generated code
vendor/
generated/

# Lockfiles
*.lock

# Single file
scripts/codegen.ts

package.json example:

{
  "readmeEnforcer": {
    "mode": "warn",
    "ignore": ["vendor/", "*.lock", "scripts/codegen.ts"]
  }
}

Supported pattern syntax (repo-relative paths, forward slashes):

| Pattern | Matches | Example | |---------|---------|---------| | dir/ or dir | Path equals dir, or starts with dir/ | vendor/ → vendor/foo.ts | | *.ext | Basename ends with .ext (any depth) | *.lock → yarn.lock | | anything else | Exact path match | scripts/codegen.ts |

No **, ?, or negation in v1. When staged files match ignore rules, the hook logs how many were skipped and does not require README updates for them.

Optional: companion doc patterns (staged-README check)

By default the hook treats filenames beginning with readme (any case) as companion documentation. Optional readmeEnforcer.docs in package.json adds extra basename patterns — configured patterns extend the default; you do not repeat readme*.

When code is staged, the hook walks up from each changed path, stops at the first directory containing any matching companion doc, and requires every matching file in that directory to be staged with the code (hard-fail), or warns and exits 0 (warn-only). Staging only companion doc files (no code) still passes.

Invalid docs config (non-array) is ignored, same as ignore. Ignore rules and warn-only mode apply unchanged. Opt-in README reachability is unaffected (still readme* only).

package.json example:

{
  "readmeEnforcer": {
    "docs": ["ARCHITECTURE.md", "AGENTS.md", "doc*"]
  }
}

With that config, staging src/feature.ts when src/README.md and src/ARCHITECTURE.md both exist requires staging both companion docs (plus the code).

Pattern syntax (basename only, case-insensitive):

| Pattern | Matches | Example | |---------|---------|---------| | readme* | Basename starts with readme | README.md, readme-notes.txt | | doc* | Basename starts with doc | doc-overview.md | | ARCHITECTURE.md | Exact basename | ARCHITECTURE.md only |

Prefix patterns end with *; otherwise the pattern is an exact basename match. No path segments, **, ?, or negation in v1.

Behavior note: if a directory contains multiple readme* files (e.g. README.md and readme-notes.md), the hook now requires all of them when related code is staged. This is rare but stricter than picking a single nearest README.

Default behavior (always on)

  • Companion doc detection: filenames beginning with readme (any case), plus any patterns from readmeEnforcer.docs.
  • Matching: nearest directory with any companion doc per staged code path; all matching files in that directory must be staged when any listed code is staged (hard-fail), or the hook warns and exits 0 (warn-only).

Optional: root README reachability (opt-in)

When enabled, the hook also verifies that every tracked readme* file is reachable from a single root README by following relative inline Markdown links [text](relative-path) from file to file (BFS). Cycles and multiple incoming links are allowed; only orphan READMEs (never linked from the root’s component) fail the check.

  • Root README: tracked readme* at the repository root (path with no /). Preference order: README.md, then readme.md; otherwise the first path when sorted with en locale. The hook prints which root was used.
  • Link sources: only .md / .markdown readmes are scanned for outbound links. Other readme* files (e.g. readme.txt) can still be targets but do not contribute links.
  • Graph: nodes are tracked readme* paths from git ls-files. Untracked READMEs are ignored.

Enable in Husky (recommended — all platforms):

npx check-readme-updated --enforce-readme-interlink

Enable with a CLI flag (e.g. Python pre-commit args):

repos:
  - repo: https://github.com/taidaid/pre-commit-readme-enforcer
    rev: main
    hooks:
      - id: check-readme-updated
        args: [--enforce-readme-interlink]

You can combine the flag and env var; either is sufficient.

Enable with an environment variable (bash / Git Bash) in .husky/pre-commit:

echo 'README_ENFORCE_INTERLINK=1 npx check-readme-updated' > .husky/pre-commit

On Windows, prefer the CLI flag in the hook file; see Windows (consumer repos) for PowerShell/cmd one-off runs.

Manual run:

npx check-readme-updated --enforce-readme-interlink

Or with an env var (bash / Git Bash): README_ENFORCE_INTERLINK=1 npx check-readme-updated

If the root-level README rule cannot be satisfied (no tracked root readme*), the reachability check exits with an error when opt-in is on.

Performance: with opt-in, each commit reads every tracked README for link parsing—fine for typical repos; very large documentation trees may prefer running this check in CI instead.

Troubleshooting

command not found: node / npm — Install Node.js (includes npm), restart the terminal.

Permission denied on ./build.sh — chmod +x build.sh then run again.

Hook never runs — Work in the repo root; confirm .husky/pre-commit exists; confirm .husky/_/ contains hook shims (run npx husky if _/ is empty). On Windows, see Windows (consumer repos).

README staged but hook still fails (Windows) — Use package version 1.1.1+; ensure you use npx check-readme-updated or node check-readme-updated.js, not ./script.js in cmd.

npx husky errors — Run git status in a git repo; run npm install; use Node 18+ for Husky 9.

Hook runs but “no README” — Add a README (e.g. README.md) where the tool expects it, or adjust your layout.

Hook runs but “README reachability failed” — Ensure the root README links (directly or transitively) to every other tracked readme* using relative inline Markdown links. See Configuration.

Still stuck — Open an issue with OS, node --version, the exact error, and commands you ran.

Development

For this repository (not consuming the package elsewhere):

git clone https://github.com/taidaid/pre-commit-readme-enforcer.git
cd pre-commit-readme-enforcer
npm run setup

On Windows, use npm run setup (same as above). On macOS/Linux you may alternatively run ./build.sh, which calls npm run setup and configures the local Husky hook.

This repository includes "prepare": "husky" in package.json so npm install keeps .husky/_/ shims wired on fresh clones.

This repo's own pre-commit hook runs in warn-only mode — it nudges you to review nearest READMEs but does not block commits. Update READMEs only when you make substantial contract or architecture changes, not for routine edits.

  • npm run setup — install deps, compile TypeScript, run Husky
  • npm run build — compile TypeScript
  • npm run dev — run via ts-node
  • npm start / npm test — build, run integration tests, then smoke-run the hook

Agent skills

This repo includes AGENTS.md and docs/agents/ for engineering skills (issue tracker, triage labels, domain docs). Edit those files to change how skills interact with GitHub issues and project documentation.

Releasing to npm

  1. Update CHANGELOG.md and the version field in package.json (this repo does not run npm version automatically).
  2. From a clean tree, run npm test (also runs automatically via prepublishOnly on publish).
  3. npm publish (uses prepack to compile TypeScript before the tarball is built). Use npm publish --dry-run first if you want to inspect the pack without uploading.

License

MIT — see LICENSE.