← Blog

npm stops trusting by default: what npm 12 changes and why you should get ready now

After the latest wave of poisoned npm packages, GitHub is bringing three breaking changes in npm 12: install scripts off by default, Git dependencies blocked and remote URL tarballs banned unless you approve them explicitly. Here's what breaks in your deployments and how to arrive prepared.

From "I trust everything" to "approve what you run"

If you follow security news, the past year on npm has been one scare after another: self-spreading worms, libraries with a hundred million weekly downloads compromised for a few hours, and maintainer accounts hijacked to slip malicious code into the supply chain. Yesterday GitHub — which maintains npm — made its move with what is probably the deepest overhaul of the package manager in years.

The core idea is simple and long overdue: npm will stop trusting by default. What today runs automatically on npm install will now need your explicit approval. It lands in npm 12, due in July, and if you manage servers, CI pipelines or any Node app in production, this one's for you.

Why now: the wave of poisoned packages

The trigger isn't a single case, it's a pattern. The loudest was Shai-Hulud, malware that behaves like a self-propagating worm: it runs during the preinstall phase, steals credentials (GitHub tokens, AWS, GCP and Azure keys, CI/CD secrets) and uses them to publish more infected packages and spin up malicious repositories, chaining the infection along. Its second wave racked up hundreds of compromised packages and over 25,000 automatically created repositories.

Add to that the hijacking of axios (one of the ecosystem's most used libraries), malicious packages published under corporate namespaces like @redhat-cloud-services off a compromised account, and smaller variants such as @tanstack or @antv. The vector keeps repeating: a script that runs on install, or a dependency pointing at a Git repo or a URL you never reviewed.

What npm 12 changes (the three breaking changes)

GitHub frames it as the shift from implicit trust to explicit consent. Specifically:

  1. Install scripts won't run by default. npm install will stop running your dependencies' preinstall, install and postinstall scripts — along with native module builds and prepare scripts from Git or local paths — unless you approve them explicitly. That closes the exact door Shai-Hulud walked through.
  2. Git dependencies blocked. npm install will no longer fetch dependencies pointing at Git repositories, direct or transitive, without permission. So long to a comfortable path for injecting code that never touches the registry.
  3. Remote URL dependencies blocked. Packages served from a URL (HTTPS tarballs) won't resolve without authorization either, again both direct and transitive.

In short: what used to happen "on its own" will now happen because you said so.

Who's affected

  • Anyone running npm install on a server or in CI, which today is basically any deployment with a modern frontend or a Node backend.
  • CI/CD pipelines especially, where a malicious postinstall has access to environment variables, tokens and keys. That's where it does the most damage and what these changes protect best.
  • And projects relying on Git or URL dependencies (internal forks, private packages without a registry): they'll still work, but you'll have to declare them. Better to find out now than when the build stops in red.

What you can do today, without waiting for v12

You don't need to wait until July to shrink your attack surface. These already work:

1. Check which npm version you're on

npm --version

Move to npm 11.16.0 or newer to start seeing warnings about which of your workflows v12 would affect:

npm install -g npm@latest

2. Disable install scripts where you don't need them

In CI and reproducible deployments you almost never need dependencies to run scripts:

# One-off install without running scripts
npm install --ignore-scripts

# Or permanently in the project (.npmrc)
echo "ignore-scripts=true" >> .npmrc

If a legitimate package genuinely needs its postinstall (say, one with a native binary), you approve it in a controlled way instead of leaving the door open for everyone.

3. Use deterministic installs in CI

npm ci

npm ci installs exactly what package-lock.json says, without resolving new versions. Less room for a freshly published, compromised version to sneak in unnoticed.

4. Pin and watch

  • Pin versions (avoid wide ranges ^/~ on sensitive dependencies).
  • Turn on dependency alerts (Dependabot) and review which packages ship a postinstall.
  • As soon as npm 12 ships, inventory the scripts and the Git/URL dependencies you actually use and approve them explicitly. Doing that homework calmly, before you upgrade, saves you the stopped-build scare.

What we do

On the deployments we manage, dependency installs run with npm ci and --ignore-scripts by default, and legitimate postinstall scripts get approved one by one. It isn't paranoia: the cost of reviewing a handful of packages is laughable next to a preinstall walking off with the server's keys. npm 12 heads in exactly that direction, so for us it isn't a change — it's the rule turned into the default.

The same old routine

With the supply chain, the moves look a lot like any other patch:

  • npm --version to know where you stand.
  • Move to 11.16.0+ to see the warnings.
  • --ignore-scripts / npm ci in CI and deployments.
  • Inventory scripts and Git/URL dependencies before jumping to v12.

Trust by default was convenient, but the bill was paid by whoever had the bad luck to install the wrong package on the wrong day. If you're not sure what your npm install runs in production or CI, it's a good time to look. And if you'd rather we review it for you, let's talk.

References

Want to talk about your case?

Tell us what you need and we will get back to you within 24 hours with a clear proposal.

Get a quote