The editorial frames install scripts as the single largest supply-chain attack surface in JS for a decade, citing event-stream, ua-parser-js, protestware waves, and the lottie-player compromise as all relying on postinstall execution. It positions npm v12 as finally catching up to pnpm's onlyBuiltDependencies, Bun's trustedDependencies, and Deno's no-scripts default.
The npm team's changelog frames the lifecycle-script default-off as a deliberate hardening of the install pathway, requiring explicit opt-in via --foreground-scripts, ignore-scripts=false, or a trustedDependencies allowlist. The RFC's acceptance and the v11.5 flag-gated preview signal they view this as a necessary security correction rather than a developer-experience regression.
The editorial points out that the Node 20.19+/22.12+ floor now throws on startup instead of emitting an EBADENGINE warning, that --legacy-peer-deps removal will force teams onto overrides or --force, and that npm pack honoring .gitignore will silently change published tarball contents. These are framed as load-bearing changes that will surprise teams focused only on the install-scripts headline.
The editorial argues npm audit's habit of failing CI on low and moderate vulnerabilities created a noise floor that teams routinely ignored or suppressed, providing no real security value. Defaulting to exit 0 for those severities is framed as honest scoping — audits still report, but stop blocking pipelines on issues nobody was triaging anyway.
The editorial explicitly notes pnpm shipped onlyBuiltDependencies in 2024, Bun has had trustedDependencies since launch, and Deno doesn't run install scripts at all. The framing positions npm v12 as the last major package manager to adopt allowlist-based script execution, suggesting the ecosystem's de facto standard already shifted without npm.
On June 9, GitHub's npm team published the breaking-change list for npm v12, the first major bump since v11 landed in early 2025. The headline change: lifecycle scripts (`preinstall`, `install`, `postinstall`, `prepare`) will no longer run by default during `npm install` or `npm ci`. To restore the old behavior, you pass `--foreground-scripts`, set `ignore-scripts=false` in `.npmrc`, or maintain an explicit `trustedDependencies` allowlist in `package.json`.
The rest of the list is less flashy but equally load-bearing. The supported Node range moves to 20.19.0+ or 22.12.0+ — anything older throws on startup rather than printing the familiar yellow `EBADENGINE` warning. The legacy `--legacy-peer-deps` resolver, kept on life support since npm v7, is removed; peer conflicts now require either `--force` or an `overrides` block. `npm audit` will still report vulnerabilities but will exit 0 for `low` and `moderate` severities by default, ending the years-long CI-failure tax that nobody actually triaged. And `npm pack` now respects `.gitignore` in addition to `.npmignore`, which will quietly change what ships to the registry for a lot of packages.
The target ship date is Q4 2026, bundled with Node 24 LTS. No release candidate yet, but the RFC PRs are merged and the behavior is already toggleable behind flags in npm v11.5.
The install-scripts change is the one that'll break the most CI pipelines, and it's the one with the longest backstory. Install scripts have been the single largest supply-chain attack surface in the JavaScript ecosystem for a decade: every confirmed npm worm — `event-stream`, `ua-parser-js`, the protestware waves, the recent `lottie-player` compromise — relied on a `postinstall` running arbitrary code on developer machines and CI runners the moment a transitive dep got pulled in. pnpm shipped `onlyBuiltDependencies` as an allowlist in 2024. Bun has had `trustedDependencies` since launch. Deno doesn't run them at all. npm is the last major package manager to flip the default, and it took until 2026.
The practical fallout is sharper than the security framing suggests. A non-trivial chunk of the ecosystem genuinely needs install scripts to function: `node-gyp` rebuilds for native modules (`better-sqlite3`, `bcrypt`, `canvas`), `prisma generate` to produce the client, `husky install` to wire git hooks, `puppeteer` to download Chromium, `playwright install`. None of these will work after `npm ci` on v12 unless you've explicitly opted them in, and the failure mode is a successful install with a broken `node_modules` — the worst kind of bug, because nothing throws until runtime.
The peer-dep change is smaller in scope but spicier in the trenches. `--legacy-peer-deps` has become the de-facto fix for every React 18-to-19, Angular major, or `@types/*` mismatch that anyone hits, and large monorepos have it permanently pinned in `.npmrc`. Those repos will need to either resolve the conflicts honestly or commit to an `overrides` block, which is more explicit but also more brittle — overrides apply transitively and don't surface in `npm outdated`.
The audit change is the one developers will quietly cheer. The community consensus, including from Snyk's own 2025 State of Open Source Security report, is that `npm audit`'s noise-to-signal ratio is closer to 50:1 for low/moderate findings, most of which are ReDoS in a dev-only dependency that never sees user input. Defaulting those to non-failing brings npm in line with `pnpm audit --prod` and Yarn's audit behavior, and removes one of the most common reasons teams disable audit in CI entirely.
Do three things this week, in order. First, grep your `package.json` files for `scripts` keys named `install`, `postinstall`, or `prepare`, then run `npm ls --all` and check which transitive deps have install scripts (`npm query ':attr(scripts.postinstall)'` works in v10+). Anything that touches native bindings, Prisma, Husky, Puppeteer, Playwright, Electron, or `sharp` needs to go on your `trustedDependencies` list before you bump npm.
Second, pin npm in CI. If you're not already running `npm install -g npm@11` or using `packageManager` in `package.json`, you'll get auto-upgraded to v12 the day it ships, which for Node 22 users is whenever they bump their base image. Add `"packageManager": "npm@11.x"` to your root `package.json` now and treat the v12 bump as a deliberate migration, not a coincidence. Corepack will respect it on Node 22.12+.
Third, if you maintain a published package with install scripts, start writing your `trustedDependencies` migration docs now. The npm team has signaled that the registry UI will eventually badge packages that require install scripts, and the friction curve for being on that list is going to steepen. Native module maintainers in particular should evaluate whether prebuilt binaries via `prebuild-install` or `node-gyp-build` get them off the hook entirely — `better-sqlite3` and `bcrypt` already ship prebuilds for every common arch, which means consumers can drop them from any allowlist.
For the audit change, the practical move is to leave the default and add `npm audit --audit-level=high` to your CI script if you want the old failure behavior for high/critical only. That's where the actual signal is.
npm v12 is a quiet but consequential release: it closes the last big delta between npm and the alternative package managers that have spent the last three years eating its mindshare. The interesting question isn't whether v12 is the right call — pnpm and Bun have proven the model — but whether shipping it five years late is enough to slow the migration away from npm at all. The Bun and pnpm install-script defaults didn't just protect users; they became a recruiting tool for every team that had been bitten by a supply-chain incident. npm matching the behavior in 2026 means new projects no longer have a security reason to leave, but it doesn't claw back the ones already gone. Either way, your CI will break on the upgrade. Plan for it now, not in October.
postinstall scripts should've been removed long time ago, it's the cancer of NPM packages. There's so many deeply nested, uncontrolled postinstalls that run randomly when you pull something it's insane, I don't know how someone at some point ever though that was a good idea.
I bet there have been a hundred different discussions about this inside of NPM since it was disclosed 10 years ago. With Shai Halud it's gotten too big to ignore.
It is not obvious from the post but it seems like the allow list for the scripts supports whitelisting packages instead of a global setting. This should make it easier to maintain org-wise rules to allow scripts only for specific packages.Is there a linter that could be used for scenarios like this
Are the current LTS node versions (iirc 22, 24, 26) going to update the bundled npm to v12 to benefit from these security fixes? All come with npm v11 now
Top 10 dev stories every morning at 8am UTC. AI-curated. Retro terminal HTML email.
I'm not sure how I missed that npm was acquired by GitHub, but man, a lot of stuff suddenly makes a lot of sense. I really can't think of a worse home for such a critical part of the Node ecosystem.