npm 2,036 audit sends the shape of your tree — names and versions, not code — to the registry's advisory service and prints every published vulnerability that matches. It runs after npm install; run it deliberately in CI, where its exit code fails the build. This project depends on one ancient release, minimist@1.2.0:
> npm audit # npm audit report minimist 1.0.0 - 1.2.5 Severity: critical Prototype Pollution in minimist - https://github.com/advisories/GHSA-vh95-rmgr-6w4m Prototype Pollution in minimist - https://github.com/advisories/GHSA-xvch-5gv4-984h fix available via `npm audit fix --force` Will install minimist@1.2.8, which is outside the stated dependency range node_modules/minimist 1 critical severity vulnerability
Read the "fix available" line carefully. Without --force, npm audit fix moves to a patched version inside your declared range and only rewrites the lockfile, so it is safe to commit. --force steps outside the range — a major upgrade with real breaking-change risk — so never wire it into CI.
The exit code is what CI cares about: zero when nothing at or above the threshold is found. npm audit --audit-level=critical --omit=dev raises that threshold and drops build-time packages; --json gives the machine-readable form, whose metadata.vulnerabilities object a script asserts on.
Audit data knows only disclosed vulnerabilities, so a package malicious from its first publish has no advisory until somebody notices. osv-scanner 11,098 (https://github.com/google/osv-scanner 11,098 ) reads package-lock.json directly, needing no node_modules, and covers ecosystems npm audit cannot see; audit-ci 297 (https://github.com/IBM/audit-ci 297 ) adds an allowlist, so an unfixable advisory is waived with an expiry date rather than silenced with --audit-level=none.
| Tool | Install | Source | Best at |
|---|---|---|---|
| npm audit | built in | GitHub 29 advisories | gate on every install |
| osv-scanner | release binary | OSV.dev 26,430 | lockfile-only scans |
| audit-ci | npm i -D audit-ci | npm, pnpm 69,400 , yarn | expiring allowlists |
| Socket CLI 320 | @socketsecurity/cli | code behavior | undisclosed malware |
One caveat: a development-only advisory carries the same severity words as a production one, so triage by reachability.