On June 9, GitHub published Upcoming breaking changes for npm v12 on its official changelog, announcing that npm v12 — expected in July — flips three behaviors to deny-by-default: preinstall/install/postinstall scripts from dependencies will no longer run automatically, and Git dependencies and remote URL tarballs will no longer resolve unless explicitly allowed. The Hacker News and BleepingComputer followed within days. This is the largest surgery ever performed on the default behavior of npm.
To understand why the cut goes this deep, look back at a decade of supply-chain incidents: the 2018 event-stream backdoor, the 2021 ua-parser-js cryptominer, and the self-replicating Shai-Hulud worm of 2025. Nearly every infection used the same front door: a postinstall script executing arbitrary code with your privileges the moment you typed npm install. The old defense was developer discipline plus an opt-in --ignore-scripts flag. npm v12 inverts the model entirely — from run-by-default to blocked-by-default.
The blast radius is not in question: the npm registry serves tens of billions of downloads weekly, and every project with a node_modules folder is in scope — including every Laravel project that bundles its frontend with Vite. Packages that rely on install scripts — native builds via node-gyp, sharp, esbuild, husky — will simply not run their scripts in clean environments starting in July. CI pipelines and Docker builds are the first fracture points.
Below: the exact behavior of the three changes, the npm approve-scripts migration workflow, and the trade-offs against pnpm, Bun and Yarn.
Technical details + CLI
- Dependency install scripts no longer execute by default (your own root project scripts are unaffected)
- Git dependencies (direct or transitive) require
--allow-git - Remote URL tarball dependencies require
--allow-remote
The recommended migration path per the npm docs: upgrade to npm 11.16.0 or later, run a normal install, review the warnings, then approve what you trust:
# Simulate v12 behavior today
npm install --ignore-scripts
# Upgrade to 11.16.0+; installs will list scripts that would be blocked
npm install -g npm@11
npm install
# Review pending package scripts and approve the ones you trust
npm approve-scripts --allow-scripts-pendingApprovals are written into package.json — version-controlled and code-reviewed. For the first time, trust decisions become an auditable diff.
Immediate actions for three audiences
- Engineers: add a CI job running
npm install --ignore-scriptsthis week and list what breaks; audit script-heavy packages such as sharp, esbuild, puppeteer, husky. - Tech leads: schedule npm 12 compatibility into the June sprint; pin npm versions in Docker base images and CI runners; inventory Git/URL dependencies in lockfiles.
- Founders / agencies: ask your maintenance vendor: will our project still build when npm 12 ships in July? If they cannot answer, that is the case for a maintenance contract.
Comparison and trade-offs
| Option | Pros | Cons | Migration cost |
|---|---|---|---|
| npm 12 (deny-by-default) | Official standard; auditable allow-list in package.json | CI takes the first hit in July; messy adjustment period | Low: approve-scripts + CI updates (0.5-1 day/project) |
| pnpm 10+ | Same default since early 2025; battle-tested | Lockfile incompatible with npm | Medium: swap lockfile and CI caches (1-2 days) |
| Bun | Very fast installs; default package allow-list | Runtime compatibility edges; conservative enterprise adoption | Medium-high: validate the whole build chain |
| Yarn Berry | PnP mode has no node_modules to infect | Steep learning curve; legacy compatibility issues | High: architectural migration (3-5+ days) |
What nobody tells you
- Blocking install scripts does not stop require-time attacks: malicious code moved into the module body still executes the moment you
importit. This removes the most convenient entry point, not the only one. - Allow-list fatigue is the new risk: once developers rubber-stamp approvals, attackers nest payloads in the dependency trees of packages everyone approves. Safe defaults shift attack costs; they do not eliminate them.
The next 3 months
After npm 12 goes GA in July, expect a first week of CI horror stories and bad allow-everything tutorials; major frameworks will publish official allow-list guidance. Watch whether the npm approve-scripts DX is good enough that people do not bypass it, and whether pnpm captures another wave of share.
FAQ
Will my project break, and how do I check fast?
Run npm install --ignore-scripts locally or in CI, then a full build and test pass. Breakage clusters around native builds (node-gyp) and binary-downloading packages (sharp, puppeteer, esbuild).
Are the build scripts of my own project blocked?
No. Only lifecycle scripts of dependencies are blocked; root package.json scripts (dev, build, postinstall) run as before.
What should pnpm teams do?
Essentially nothing — pnpm has shipped the same default since v10. npm is converging on the pnpm security model.
Are Laravel + Vite projects affected?
On the frontend dependency layer, yes. Vite itself is fine, but packages in its tree such as esbuild need approval; validate the full npm ci flow on staging before July.
My take
The mainstream story is that npm is finally safe. My read is the opposite: the most dangerous window is the first six months after the change lands. Safe defaults create a feeling of handled, while the attack surface merely moves to require-time and to the quality of allow-list reviews — and many teams, under broken-CI pressure, will tear down the new defenses themselves with an allow-everything workaround. Security decisions made under deadline pressure are usually the worst ones. For ScriptWalker, this is a deadline-driven opportunity: offer every maintenance client an npm 12 compatibility scan — one scan, one report, one approve-list PR — converting a one-off ecosystem event into billable care.