Skip to content
industry insights

NPM 12 Ends the Scriptpocalypse

For years, a single `npm install` could unleash supply chain attacks on your machine. NPM 12 is finally slamming that door shut by killing automatic script execution by default.

Cassidy Wolfe
Hero image for: NPM 12 Ends the Scriptpocalypse

TL;DR / Key Takeaways

  • For years, a single `npm install` could unleash supply chain attacks on your machine.
  • NPM 12 is finally slamming that door shut by killing automatic script execution by default.

The Code Execution Free-for-All Ends

`npm 12` finally slams the door on the wild west of package installation, ending a dangerous era where `npm install` doubled as a silent code execution free-for-all. For years, `pre-install` and `post-install` scripts, alongside their `install` counterparts, ran automatically for every dependency, transforming a routine task into the primary vector for insidious supply chain attacks. This default behavior turned a simple package fetch into a high-stakes gamble.

An implicit trust model underpinned the entire JavaScript ecosystem, allowing any package to execute arbitrary code during installation without explicit user consent. Attackers masterfully exploited this blind spot. The self-propagating Shai-Hulud worm, for instance, compromised hundreds of packages to exfiltrate credentials and spread autonomously, while its May 2026 "Mini Shai-Hulud" variant targeted prominent projects like `TanStack` by exploiting GitHub Actions.

The community debated this critical vulnerability for years, caught between urgent security needs and the immense challenge of maintaining backward compatibility across a vast, script-reliant ecosystem. Now, `npm 12` cuts this Gordian knot. It disables automatic script execution by default, forcing an explicit approval flow via `npm approve-scripts`. This long-overdue shift from implicit trust to explicit allowlisting finally prioritizes security, ushering in a safer, if slightly less convenient, future.

Your New Gatekeeper: `npm approve-scripts`

`npm install` in version 12 no longer blindly executes arbitrary code from your dependencies. The days of `pre-install`, `install`, and `post-install` scripts running by default are definitively over, ending a critical vector for supply chain attacks like Shai-Hulud and the recent TanStack compromises. This blanket blockage extends even to essential native `node-gyp` builds and `prepare` scripts sourced from Git, file, or link dependencies, effectively neutering any unexpected code execution before it begins.

Enter `npm approve-scripts`, your new gatekeeper. This command introduces an explicit, auditable workflow, empowering developers to review every script and selectively enable only those they genuinely trust. Once approved, `npm` stores these allowances directly within your `package.json` file, creating a transparent, version-controlled record of permitted code that runs during installation. This replaces the previous dangerous automation with deliberate, informed consent.

This isn't merely a new command; it's a profound philosophical shift for the entire JavaScript ecosystem. `npm` moves decisively from a model of implicit trust – where any dependency could run anything – to one of explicit allowlisting. Developers regain absolute, granular control over precisely what code executes on their machines, transforming `npm install` from a potential liability into a deliberate, secure operation. The scriptpocalypse ends not with a whimper, but with a firm, auditable "No."

Locking Down More Attack Vectors

While `pre-install` and `post-install` scripts were the flashiest vectors for supply chain attacks, shrewd adversaries never put all their eggs in one basket. They also leveraged less obvious pathways, like direct Git dependencies and remote URL tarballs, to sneak malicious code into unsuspecting projects. Attackers famously exploited these methods in incidents such as the Mini Shai-Hulud variant that targeted packages under the TanStack namespace, often injecting malicious `.npmrc` files via these indirect routes.

npm 12 slams these secondary doors shut with a simple, explicit mandate. Developers must now use `--allow-git` to resolve Git-based dependencies and `--allow-remote` when installing packages from URL-based tarballs. This isn't just an inconvenience; it's a critical friction point designed to force conscious decisions, eliminating implicit trust for external sources and significantly narrowing the attack surface.

No one can claim ignorance when npm 12 rolls out in July; warnings for these breaking changes have been active since npm v11.16.0+. This grace period offers ample opportunity for teams to audit their build pipelines and update dependency declarations, avoiding sudden disruptions. For more detail on the upcoming shifts, consult the Upcoming breaking changes for npm v12 - GitHub Changelog.

A Necessary Step, But Is It Enough?

Finally, npm acknowledges reality. The script execution free-for-all, a primary vector for supply chain attacks, is ending with npm 12 after years of widespread exploitation. This long-overdue shift to explicit script approval, finally catching up to more security-conscious alternatives, transforms `npm install` from a naive trust exercise into a guarded operation. It's a necessary evolution, albeit one that arrives in July 2026, years after the first alarms sounded.

Even with these welcome changes, the battle for supply chain integrity continues. Many security experts, myself included, simply advocate for pnpm, which boasts superior defaults like blocking exotic sub-dependencies and delaying new package adoption. pnpm’s proactive stance, which has long championed a more restrictive, secure posture out of the box, offers a compelling alternative for projects demanding immediate, robust protection.

These updates significantly narrow the attack surface, curtailing the `pre-install` and `post-install` script vectors that fueled incidents like Shai-Hulud and the TanStack compromise. The explicit block on Git dependencies and remote tarballs further closes well-worn attack paths. However, attackers are relentlessly adaptive. Expect a pivot to other vulnerabilities, perhaps exploiting malicious `.npmrc` files, CI/CD misconfigurations, or sophisticated social engineering. Developer vigilance, scrutinizing every dependency and build process, remains the ultimate, indispensable firewall in this evolving threat landscape.

Frequently Asked Questions

What is the biggest change in NPM 12?

The most significant change is that `npm install` will no longer automatically run pre-install, install, or post-install scripts for dependencies. Users must now explicitly approve them.

How do I run scripts for trusted dependencies in NPM 12?

You need to use the new `npm approve-scripts` command. This will prompt you to approve scripts from your dependencies, and your selections will be saved to your package.json.

Why is NPM making these security changes now?

These changes are a direct response to a wave of sophisticated supply chain attacks, like the Shai-Hulud worm, that exploited automatic script execution to steal credentials and spread malware.

Are other package managers like PNPM or Yarn already this secure?

Yes, other package managers like PNPM and Yarn have already implemented similar security-by-default behaviors, such as blocking automatic install scripts, for some time.

Found this useful? Share it.

One short daily email of tools worth shipping. No drip funnel.

one email a day · unsubscribe in two clicks · no third-party tracking

🚀Discover More

Stay Ahead of the AI Curve

Discover the best AI tools, agents, and MCP servers curated by Stork.AI. Find the right solutions to supercharge your workflow.

P.S. Built something worth using? List it on Stork