I scanned the top 20 npm packages. Everyone passed CVE checks, but here's what the static analysis found
Every time you run npm install, you're trusting someone else's code to run on your machine. Not eventually — right now. Postinstall hooks fire the second a package lands. No review, no prompt. I built plum to change that. It's a CLI that downloads the package tarball into memory, reads the source, and scores it before anything touches your project. I pointed it at the 20 most downloaded npm packages. The results are mostly reassuring — but a few are worth talking about. When you run plum axios, it: Fetches the .tgz from npm into memory (never to disk) Scans every .js file for red flags — obfuscated eval, credential access, shell execution, outbound HTTP in install scripts Checks CVEs against the exact resolved version Looks at maintainer age, publish recency, download count, and typosquatting distance Instead of pass/fail, plum gives a 0–100 score. The same signal — like child_process access — means something very different in TypeScript's language server versus a brand-new package from an unknown maintainer. Package Downloads/wk Score Status debug 553M 100/100 ✅ SAFE semver 635M 100/100 ✅ SAFE commander 367M 100/100 ✅ SAFE chalk 410M 100/100 ✅ SAFE dotenv 119M 100/100 ✅ SAFE cors 49M 100/100 ✅ SAFE jsonwebtoken 40M 100/100 ✅ SAFE socket.io 12M 100/100 ✅ SAFE lodash 146M 100/100 ✅ SAFE moment 31M 100/100 ✅ SAFE react 125M 90/100 ✅ SAFE express 92M 90/100 ✅ SAFE vue 11M 90/100 ✅ SAFE eslint 126M 80/100 ✅ SAFE uuid 240M 80/100 ✅ SAFE mongoose 5M 80/100 ✅ SAFE axios 99M 70/100 ✅ SAFE typescript 181M 70/100 ✅ SAFE ⚠ webpack 44M 75/100 ✅ SAFE ⚠ next 34M 55/100 ⚠ RISKY 20/20 had zero CVEs. 16 scored SAFE. 1 scored RISKY. Next.js — 55/100, RISKY Next.js is not malicious. It's maintained by Vercel, one of the most trusted teams in JS. The score comes from three child_process references in helper scripts that detect your package manager and check if you're online. Totally legitimate. But 55/100 is a conversation starter, not a verdict. A framework using shell access is something you should know about, even if it's expected. That's the point of a score — it surfaces information and lets you decide. TypeScript & Webpack — flagged, still SAFE Both got dinged for child_process. TypeScript's language server needs shell access. Webpack spawns child processes for parallel builds. Neither is surprising. Plum caught real signals and still scored them SAFE given the context. Axios — 70, worth a look Axios scored 70 despite being clean with no CVEs and 99M weekly downloads. There's likely a pattern match hitting unnecessarily in the tarball — I'm investigating. If a tool flags something, it should explain every deduction. That's on the roadmap. I ran npm audit on all 20 packages too. Zero issues. Also correct. The difference is what each tool checks. npm audit is a database lookup — it tells you if a known CVE exists for a version. That's valuable. But the supply chain attacks that actually caused damage — event-stream, ua-parser-js, node-ipc — were all zero-days. No CVE existed when developers installed them. Behavior-based scanning doesn't replace CVE checking. It adds a layer that databases can't. npm install -g plum-scanner plum It's open source: github.com/rjcuff/plum Built in Rust. Scans in under a second. No account, no API key.
