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

Stay in the loop

Early access, research updates, and the occasional strong opinion.