State of npm Supply Chain Trust: April 2026
We audited the 50 most downloaded npm packages with behavioral commitment scoring. 30% are CRITICAL. 2.54 billion weekly downloads depend on a single maintainer each.
Executive Summary
15 of the top 50 npm packages by weekly downloads are CRITICAL — meaning a single person's npm token is the only barrier between those packages and a supply chain compromise. Combined, those 15 packages receive 2.54 billion weekly downloads, representing 34% of all downloads across the top 50.
The packages that passed include webpack (score=100, 8 maintainers), prettier (score=100, 11 maintainers), and TypeScript (score=98, 6 maintainers). The packages that are CRITICAL include minimatch (562M downloads/week, 1 maintainer), chalk (413M downloads/week, 1 maintainer), and glob (332M downloads/week, 1 maintainer).
Here's the uncomfortable part: every single package scores above 70 on structural metrics. The behavioral signals look fine. Release cadence looks fine. Download momentum looks fine. The risk is invisible to any metric that doesn't explicitly flag single-maintainer concentration at scale — which is exactly what npm audit doesn't do.
This is the same structural profile that the ua-parser-js attack exploited in October 2021. A single token. A window. A malicious publish. Cryptominer and credential stealer deployed to 7 million weekly downloads before anyone noticed. axios carries the same profile at 82 million weekly downloads.
The Full Dataset
Audited April 18, 2026 via proof-of-commitment. CRITICAL = 1 maintainer + >10M weekly downloads.
| # | Package | Score | Risk | Maintainers | Downloads/wk |
|---|---|---|---|---|---|
| 1 | semver | 95 | ✅ SAFE | 5 | 633M |
| 2 | minimatch | 85 | 🔴 CRITICAL | 1 | 562M |
| 3 | debug | 82 | ✅ SAFE | 2 | 553M |
| 4 | chalk | 75 | 🔴 CRITICAL | 1 | 413M |
| 5 | commander | 86 | ✅ SAFE | 2 | 366M |
| 6 | tslib | 89 | ✅ SAFE | 6 | 357M |
| 7 | picomatch | 90 | ✅ SAFE | 4 | 342M |
| 8 | glob | 82 | 🔴 CRITICAL | 1 | 332M |
| 9 | @types/node | 88 | 🔴 CRITICAL | 1 | 310M |
| 10 | uuid | 82 | ✅ SAFE | 2 | 239M |
| 11 | esbuild | 88 | 🔴 CRITICAL | 1 | 190M |
| 12 | ws | 93 | ✅ SAFE | 4 | 188M |
| 13 | typescript | 98 | ✅ SAFE | 6 | 178M |
| 14 | yargs | 84 | ✅ SAFE | 2 | 173M |
| 15 | zod | 83 | 🔴 CRITICAL | 1 | 158M |
| 16 | chokidar | 81 | 🔴 CRITICAL | 1 | 158M |
| 17 | caniuse-lite | 87 | ✅ SAFE | 2 | 155M |
| 18 | lodash | 87 | 🔴 CRITICAL | 1 | 145M |
| 19 | micromatch | 84 | ⚠️ WARN | 3 | 141M |
| 20 | @babel/core | 93 | ✅ SAFE | 4 | 128M |
| 21 | eslint | 91 | ✅ SAFE | 2 | 125M |
| 22 | react | 91 | ✅ SAFE | 2 | 122M |
| 23 | dotenv | 93 | ✅ SAFE | 3 | 120M |
| 24 | react-dom | 91 | ✅ SAFE | 2 | 116M |
| 25 | vite | 91 | ✅ SAFE | 4 | 105M |
| 26 | rollup | 99 | ✅ SAFE | 5 | 102M |
| 27 | axios | 89 | 🔴 CRITICAL | 1 | 101M |
| 28 | express | 97 | ✅ SAFE | 5 | 93M |
| 29 | tailwindcss | 95 | ✅ SAFE | 3 | 89M |
| 30 | prettier | 100 | ✅ SAFE | 11 | 87M |
| 31 | undici | 96 | ✅ SAFE | 3 | 82M |
| 32 | sharp | 84 | 🔴 CRITICAL | 1 | 51M |
| 33 | cors | 87 | ✅ SAFE | 3 | 50M |
| 34 | webpack | 100 | ✅ SAFE | 8 | 44M |
| 35 | jest | 95 | ✅ SAFE | 5 | 44M |
| 36 | ts-node | 81 | ✅ SAFE | 2 | 43M |
| 37 | jsonwebtoken | 87 | ✅ SAFE | 3 | 40M |
| 38 | @babel/preset-env | 93 | ✅ SAFE | 4 | 38M |
| 39 | @types/jest | 81 | 🔴 CRITICAL | 1 | 37M |
| 40 | next | 91 | ✅ SAFE | 2 | 36M |
| 41 | hono | 82 | 🔴 CRITICAL | 1 | 34M |
| 42 | pino | 93 | ✅ SAFE | 4 | 28M |
| 43 | pg | 81 | 🔴 CRITICAL | 1 | 24M |
| 44 | winston | 89 | ✅ SAFE | 8 | 22M |
| 45 | cross-env | 73 | 🔴 CRITICAL | 1 | 17M |
| 46 | ioredis | 88 | ✅ SAFE | 2 | 17M |
| 47 | socket.io | 87 | ✅ SAFE | 2 | 13M |
| 48 | nodemon | 86 | 🔴 CRITICAL | 1 | 12M |
| 49 | prisma | 91 | ✅ SAFE | 2 | 10M |
| 50 | redis | 96 | ✅ SAFE | 5 | 9M |
Data: JSON dataset — proof-of-commitment API, April 18 2026.
Try it: npx proof-of-commitment <package-name>
Score Distribution
Here's what the structural scores look like across the 50 packages — and why the score alone is insufficient:
| Band | Count | % of packages | What it means |
|---|---|---|---|
| 🟢 90–100 (Green) | 22 | 44% | Strong behavioral signals: consistent releases, active maintainers, growing adoption |
| 🟡 70–89 (Yellow) | 28 | 56% | Some gaps — lower maintainer depth, release cadence variance, or age signals |
| 🔴 40–69 (Red) | 0 | 0% | Structural decay — stale, abandoned, or fragile |
| 🔴 CRITICAL flag | 15 | 30% | 1 maintainer + >10M weekly downloads — score doesn't save you here |
The uncomfortable finding: scores look fine. The risk is hiding in the CRITICAL flag. Every package in the top 50 scores 70 or above — solidly in the "healthy" zone by behavioral metrics. Release cadence, longevity, and download momentum all look reasonable. The danger isn't in the scores.
It's in the 15 packages where a single npm token is the only barrier between those downloads and a supply chain compromise.
The CRITICAL List
These are the 15 packages where one person's credentials control access for millions of developers. Sorted by blast radius (weekly downloads).
| Package | Downloads/wk | Score | Why it matters |
|---|---|---|---|
| minimatch | 562M | 85 | Used by npm itself, ESLint, Mocha, Jest — it's in almost everything |
| chalk | 413M | 75 | Terminal colors for every CLI tool, build script, and logging framework |
| glob | 332M | 82 | File matching used in test runners, bundlers, and build tools everywhere |
| @types/node | 310M | 88 | TypeScript type definitions for Node.js — in every TS project |
| esbuild | 190M | 88 | Bundler powering Vite, Next.js, and half the JS build toolchain |
| zod | 158M | 83 | De facto validation for TypeScript APIs; runtime boundary for AI outputs |
| chokidar | 158M | 81 | File watcher in Webpack, Vite, Jest; active in every dev environment |
| lodash | 145M | 87 | Utility belt in production codebases worldwide; often 3–5 levels deep |
| axios | 101M | 89 | Compromised April 1st, 2026. Token stolen, malicious publish. Zero CVE warning. |
| sharp | 51M | 84 | Native image processing with C++ bindings — malicious version is hard to detect |
| @types/jest | 37M | 81 | Type defs that run at dev time — test toolchain poisoning |
| hono | 34M | 82 | Fastest-growing edge framework — Cloudflare Workers standard |
| pg | 24M | 81 | PostgreSQL client with direct database access — maximum blast radius per install |
| cross-env | 17M | 73 | Sets env vars at build time — runs in CI/CD pipelines across the industry |
| nodemon | 12M | 86 | Dev process watcher — executes code on save; runs with full process permissions |
Total: 2.54 billion weekly downloads, controlled by 15 individual npm tokens.
Risk Categories
1. Infrastructure utilities nobody thinks about
minimatch, glob, and debug are in this category. They're not glamorous packages — they're the plumbing. minimatch is what npm itself uses to match package names. glob is what test runners use to find test files. debug is what Express, Mongoose, and nearly every server framework uses for internal logging. Nobody writes blog posts about them. They're just there, in everything, downloaded 500+ million times a week each.
All three: one maintainer.
2. The famous singletons
Chalk, lodash, axios, zod, esbuild. These are the packages developers know by name. Chalk colors your terminal. Lodash is your utility belt. Axios is your HTTP client. Zod validates your API shapes. esbuild makes your builds fast. They're recommended in tutorials, listed in starter templates, referenced in documentation everywhere.
Each one: one maintainer.
The ua-parser-js case is instructive. The behavioral score was high — well-maintained, active, consistent releases. The structural flag was there for years before the October 2021 attack. npm audit showed nothing. The attack took a compromised token and four hours. The blast radius included Facebook, Microsoft, Amazon, and Google. axios carries an identical structural profile at 12x the download volume.
3. TypeScript ecosystem bottlenecks
@types/node and @types/jest are maintained by a single contributor each through DefinitelyTyped, the community type repository. Every TypeScript project that touches Node.js APIs installs @types/node. Every project using Jest for testing has @types/jest in its dev dependencies. These packages don't ship runtime code — they ship type definitions. But a malicious publish could inject incorrect type definitions that cause type-checking to miss real vulnerabilities, or include a postinstall script with arbitrary code execution.
4. Dev toolchain and CI exposure
chokidar, nodemon, and cross-env run in development environments and CI pipelines. They have process-level access. chokidar watches file system events — it's in Webpack and Vite. nodemon restarts your server on file changes — it executes code directly. cross-env sets environment variables at build time — it runs in CI with full access to secrets.
These packages are less likely to be in production images, but CI pipeline compromise is increasingly the attack target. The CodeCov incident (2021), the XZ Utils attack (2024) — build toolchain is the new attack surface.
The Packages That Passed
The safe packages earn it through demonstrated commitment over time — not certification, not promises.
- prettier (score=100, 11 maintainers, 87M/wk) — The most maintained package in the top 50 by active contributor count. Consistent weekly releases. 11 people with publish access means 11 tokens would need to be compromised simultaneously.
- webpack (score=100, 8 maintainers, 44M/wk) — 14 years of shipping. 8 maintainers. Behavioral record that predates most of its users.
- semver (score=95, 5 maintainers, 633M/wk) — The most-downloaded safe package. 15 years old, 5 maintainers, consistent release record. npm's versioning backbone, done right.
- typescript (score=98, 6 maintainers, 178M/wk) — Microsoft-backed, 6 maintainers, 14 years of behavioral record. The structural antithesis of esbuild (also from the JS toolchain, 5x fewer maintainers).
- tslib (score=89, 6 maintainers, 357M/wk) — Also Microsoft-backed TypeScript infrastructure. 6 maintainers, strong release cadence. Not the headline package, but well-governed.
What You Can Do
The gap between the packages that passed and the ones that are CRITICAL isn't code quality — it's governance structure. Chalk is high-quality code. So is zod. So is esbuild. The risk isn't in the implementation; it's in the single point of failure for publish access.
That's a solvable problem — but only if you can see it.
Audit your stack in 30 seconds:
npx proof-of-commitment axios zod chalk hono esbuild
# Or against your whole project:
npx proof-of-commitment --file package.json Add to CI (posts table directly on your PR):
- uses: piiiico/proof-of-commitment@main
with:
fail-on-critical: false
comment-on-pr: true MCP server (works with Claude Desktop, Cursor, Windsurf):
{
"mcpServers": {
"proof-of-commitment": {
"type": "streamable-http",
"url": "https://poc-backend.amdal-dev.workers.dev/mcp"
}
}
} Then: "Audit the dependencies in vercel/ai" — it fetches the package.json, scores everything, returns a risk table.
Web interface: getcommit.dev/audit — paste packages or drop your package.json.
Methodology
All data sourced from public npm registry and GitHub APIs via proof-of-commitment. Five behavioral dimensions, all from observable signals:
| Dimension | Max | What it measures |
|---|---|---|
| Longevity | 25 | Package age — time in production is signal |
| Download Momentum | 25 | Weekly downloads + trend direction |
| Release Consistency | 20 | Cadence, recency, gaps |
| Maintainer Depth | 15 | Number of active maintainers with publish access |
| GitHub Backing | 15 | Star traction, repo activity, issue health |
CRITICAL = 1 maintainer + >10M weekly downloads. This is the exact profile that the ua-parser-js attack (October 2021) and event-stream (2018) exploited. High download count means high value target. Single maintainer means one token to compromise.
This analysis does not replace npm audit — it answers a different question. npm audit scans for known CVEs in the NVD database. proof-of-commitment scores structural resilience: would this package survive a maintainer compromise, a token theft, or a gradual abandonment?
The ua-parser-js attack had zero CVE warnings. Zero npm audit flags. It had a structural flag for years. The same is true for axios, minimatch, chalk, and the other CRITICAL packages in this dataset — right now.
Download the raw dataset: github.com/piiiico/proof-of-commitment
· Run your own audit: npx proof-of-commitment --file package.json
· getcommit.dev/audit
We're building Commit — trust infrastructure for the autonomous economy. Behavioral commitment data, not declarations. Source: github.com/piiiico/proof-of-commitment.
See also: Benchmarks Lied. Now What? · The Missing Layer · Declarations Are Gameable