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

nizm-cli

v0.3.1

Published

Lightweight, zero-config pre-commit hooks

Downloads

963

Readme

Lightweight, zero-config pre-commit hooks

Crates.io npm CI License

Quick Start · Installation · Configuration · Commands · How It Works

nizm (from Arabic nizam — system/order) is a fast, native CLI that runs your formatters and linters at the git pre-commit stage. It reads hook definitions straight from your existing project manifests — no .yaml files, no managed environments. Unlike pre-commit, nizm doesn't install tools for you; it trusts the ones already in your dev-dependencies and local PATH.

$ nizm run
nizm: running against 3 staged files
  ruff 3 files (120ms)
  mypy 3 files (340ms)
nizm: done in 461ms

Features

  • Zero config — hooks live in your existing manifest files
  • Fast — native Rust binary, no Python/Node runtime overhead
  • Partial staging — stashes unstaged changes, runs hooks on staged content only, restores cleanly
  • Scope filtering — each hook only sees files matching its glob pattern
  • Monorepo-ready — per-directory CWD isolation, multiple manifests, parallel execution
  • Auto-add — files modified by formatters are automatically re-staged
  • Smart init — scans dev-dependencies, suggests hooks it already knows about
  • Self-diagnosingnizm doctor verifies your setup and suggests fixes

Quick Start

npm install -g nizm-cli   # or: cargo install nizm
nizm init                 # scans dev-deps, injects hooks, installs git hook

That's it. Your next git commit runs your hooks automatically.

Installation

npm install -g nizm-cli

Platform-native binary — zero Node.js overhead at runtime.

cargo install nizm

Download the latest archive for your platform from GitHub Releases, extract, and place the binary somewhere on your PATH.

Configuration

nizm discovers hooks from your project manifests. No separate config file needed.

pyproject.toml

[tool.nizm.hooks]
ruff  = { cmd = "ruff check --fix {staged_files}", glob = "*.py" }
black = { cmd = "black {staged_files}",             glob = "*.py" }
mypy  = { cmd = "mypy {staged_files}",              glob = "*.py" }

package.json

{
  "nizm": {
    "hooks": {
      "prettier": { "cmd": "prettier --write {staged_files}" },
      "eslint": {
        "cmd": "eslint --fix {staged_files}",
        "glob": "*.{js,jsx,ts,tsx}"
      }
    }
  }
}

Cargo.toml

[package.metadata.nizm.hooks]
clippy  = { cmd = "cargo clippy --fix --allow-dirty -- -D warnings", glob = "*.rs" }
rustfmt = { cmd = "cargo fmt",                                       glob = "*.rs" }

.nizm.toml

Standalone config for projects that don't use any of the above, or for repo-root overrides:

[hooks]
check = { cmd = "make lint" }
test  = { cmd = "make test" }

Hook fields

| Field | Required | Description | | :----- | :------- | :-------------------------------------------------------------------- | | cmd | yes | Shell command to run. Use {staged_files} to receive the file list. | | glob | no | Filter staged files by pattern (*.py, *.{js,ts}, src/**/*.rs). | | type | no | Git hook type: pre-commit (default), pre-push, commit-msg, prepare-commit-msg. |

[!TIP] If {staged_files} is omitted, the command runs unconditionally when any file in scope is staged.

Commands

nizm init

Scans dev-dependencies, suggests hooks, and injects them into your manifest.

$ nizm init
  added clippy       cargo clippy --fix --allow-dirty -- -D warnings
  added rustfmt      cargo fmt

  Cargo.toml — [clippy, rustfmt]
pre-commit hook installed

Pass hook names directly for non-interactive use: nizm init ruff prettier

Known tools: ruff · black · mypy · prettier · eslint · biome · rustfmt · clippy

[!TIP] For Rust projects, rustfmt and clippy are suggested automatically when a [package] section exists — no dev-dependency needed.

nizm install

Writes a git hook into .git/hooks/ that calls nizm run. Existing hooks are preserved.

$ nizm install
scanning for manifests...
  pyproject.toml — [ruff, mypy]
pre-commit hook installed

| Flag | Description | | :--- | :---------- | | --config <path> | Bake specific manifests (repeatable, skips interactive picker) | | --parallel | Bake --parallel flag into the hook script | | --force | Overwrite modified nizm blocks without prompting |

nizm run

Runs hooks against staged files. This is what the git hook calls.

$ nizm run
nizm: running against 5 staged files
  clippy 5 files (780ms)
  rustfmt 5 files (210ms)
nizm: done in 991ms

| Flag | Description | | :--- | :---------- | | HOOK | Run a single hook by name | | --config <path> | Explicit manifest paths (repeatable, skips auto-discovery) | | --parallel | Run manifests concurrently | | --all | Run against all tracked files instead of staged | | --hook-type <TYPE> | Hook type to run (default: pre-commit) |

nizm doctor

Diagnoses hook health — checks hook files, config validity, and tool availability.

$ nizm doctor
hooks
  pre-commit (nizm-managed) ✓
  └ Cargo.toml ✓
     ├ clippy (cargo) ✓
     └ rustfmt (cargo) ✓

all 4 checks passed

nizm ls

Lists all configured hooks across discovered manifests.

$ nizm ls
Cargo.toml
  clippy   cargo clippy --fix --allow-dirty -- -D warnings  *.rs
  rustfmt  cargo fmt                                        *.rs

nizm recover

Restores your working tree from a rescue snapshot after a failed stash recovery.

$ nizm recover
working tree restored from rescue snapshot

If recovery produces conflicts, resolve them manually — the rescue ref is cleaned up automatically.

nizm uninstall

Removes nizm hook blocks from .git/hooks/. Use --purge to also strip hook config from manifests.

$ nizm uninstall --purge
pre-commit hook removed
  cleaned Cargo.toml

Environment variables

| Variable | Description | | :---------- | :--------------------------------------------------- | | NIZM_SKIP | Comma-separated hook names to skip (e.g. mypy,ruff) | | NO_COLOR | Disable colored output when set |

How It Works

git commit
    │
    ▼
.git/hooks/pre-commit        ← baked by `nizm install`
    │
    ▼
nizm run --config pyproject.toml --config package.json
    │
    ├─ detect partially staged files
    ├─ stash unstaged changes (StashGuard)
    │
    ├─ for each manifest:
    │     ├─ cd to manifest directory
    │     ├─ for each hook:
    │     │     ├─ scope-filter staged files by glob
    │     │     └─ execute cmd with {staged_files}
    │     └─ next hook
    │
    ├─ auto-add files modified by hooks
    ├─ restore unstaged changes from stash
    └─ exit 0 (pass) or exit 1 (fail → commit blocked)

Partial staging

When you stage only part of a file (git add -p), nizm stashes the unstaged changes before running hooks. This ensures formatters and linters see exactly what will be committed — not your working tree. After hooks complete, unstaged changes are restored cleanly.

A rescue ref is saved at refs/nizm-backup before every stash operation. If anything goes wrong:

nizm recover

Parallel execution

With --parallel, each manifest's hooks run in a separate thread. Hooks within a single manifest stay sequential (so your formatter runs before your linter). Output is captured per-manifest and printed in order — no interleaving.

Monorepo support

nizm uses git ls-files to discover manifests, respecting .gitignore at all levels. Each manifest's hooks run with cwd set to that manifest's directory, so tools resolve paths correctly:

repo/
├── pyproject.toml          ← ruff, mypy run here
├── frontend/
│   └── package.json        ← prettier, eslint run here
└── services/api/
    └── package.json        ← separate hooks, separate cwd

Building from source

git clone https://github.com/viperadnan-git/nizm.git
cd nizm
cargo build --release
# Binary at target/release/nizm

Running checks

cargo fmt -- --check
cargo clippy -- -D warnings
cargo test

License

MIT


Built with Rust. No runtime dependencies. Just fast hooks.