eden's digital garden
← back to the garden
evergreen supply chain · npm

Why I stopped trusting `npm install` the way I used to

Planted 14 July 2026 · last tended 18 August 2026

The first time I really looked at what happens when I type npm install, I stopped sleeping well for a week.

A package can declare a postinstall script in its package.json. That script runs on your machine, with your user, the moment the install finishes. It can read your filesystem. It can hit the network. It can drop a persistence hook and be gone before you notice. And it doesn’t just run for the packages you asked for — it runs for every transitive dependency in your tree.

The event-stream incident in 2018 is the canonical example. A malicious maintainer took over a legitimate package, published a version that pulled in a payload targeting a specific downstream project, and stole cryptocurrency wallets. Users who ran npm install on any project that transitively depended on event-stream ran the payload.

What I do now

I don’t stop using npm — that would be silly. But I’ve changed a few defaults:

  • npm install --ignore-scripts for anything I don’t fully trust
  • Look at package-lock.json diffs when they change, not just skim past them
  • Prefer npm ci over npm install in CI so the lockfile is authoritative
  • Watch dependency counts. Adding a package that pulls in 200 others is a decision I make on purpose now, not by accident

None of this is bulletproof. It’s just less naive than the way I used to work.

Found something wrong or want to add a thought? Reach out on any of the channels in the footer — I'd rather revise than be right.