← back to gallery

Maintainer Blast Radius

Live atlas of npm maintainer accounts ranked by the weekly-download blast radius an attacker captures by phishing them.

dev-toolsnpmsupply-chainsecuritymaintainersblast-radiusshai-huluddownloadsleaderboard
Open product ↗

maintainer-blast

Live npm maintainer blast-radius atlas — who controls the most weekly downloads, and what falls if their account gets phished.

Every supply-chain dashboard on the market today scores packages. After the May 2026 Mini Shai-Hulud wave (TanStack, node-ipc, @antv), it's obvious the unit of compromise is the maintainer account — one phished maintainer can detonate hundreds of packages at once. maintainer-blast is the public, daily-refreshed leaderboard of npm maintainers ranked by aggregate weekly downloads under their publish rights, with a package risk-lookup tool for any package on npm.

Quick start

npm install
npm start
# → http://localhost:4844/maintainer-blast/

A first pipeline run kicks automatically 5 seconds after boot if the DB is empty. Subsequent refreshes run on cron (daily full at 04:00 UTC; top-20 partial every 6 hours).

To trigger a manual refresh:

npm run refresh

Endpoints

All endpoints are public. No auth, no API keys, no admin login.

| Method | Path | Purpose |
|---|---|---|
| GET | /maintainer-blast/health | service status + last refresh summary |
| GET | /maintainer-blast/api/leaderboard?limit=200 | top maintainers by blast radius |
| GET | /maintainer-blast/api/stats | aggregate counts |
| GET | /maintainer-blast/api/top-packages?limit=50 | top packages by weekly downloads (indexed) |
| GET | /maintainer-blast/api/maintainers/:name | maintainer detail + portfolio |
| GET | /maintainer-blast/api/maintainers/:name/card.svg | shareable 800×420 SVG card |
| GET | /maintainer-blast/api/packages/:name | package detail + maintainers + overlap |
| POST | /maintainer-blast/api/lookup | bulk lookup (up to 50 names) |

Data sources

Every score, count, and rank is computed live. There is no seeded download number anywhere in the codebase.

| Source | URL | Frequency |
|---|---|---|
| npm package doc | https://registry.npmjs.org/{pkg} | per-package, on every pipeline run |
| npm maintainer search | https://registry.npmjs.org/-/v1/search?text=maintainer:{user} | per maintainer, on every pipeline run |
| npm weekly downloads | https://api.npmjs.org/downloads/point/last-week/{names} | per chunk of 128 packages, every pipeline run |

The only static input is seed/popular_packages.json, a list of 250 popular npm package names. These names are the targets — not the data. Every download number, maintainer list, and blast-radius score is fetched at runtime.

How it works

  1. Read the seed list (seed/popular_packages.json, 250 names).
  2. For each seed, GET registry.npmjs.org/{pkg} and persist the package + its declared maintainers.
  3. For each unique maintainer collected in step 2, page through registry.npmjs.org/-/v1/search?text=maintainer:{user} to enumerate every package they currently own (cap 1000).
  4. For every package now in the DB, batch-fetch last-week downloads via the npm bulk endpoint (128 names per call, scoped packages handled one at a time).
  5. Re-aggregate: each maintainer's blast_radius is the sum of weekly_downloads across their portfolio.

Stack

Node 18+ · Express · better-sqlite3 (WAL) · node-cron · helmet · compression. Vanilla JS SPA frontend, dark theme, no framework, no localStorage.

License

MIT