
Socket: npm v12 Ships With Install Scripts Off by Default
npm v12 is now generally available, disabling preinstall/install/postinstall lifecycle scripts, the implicit node-gyp rebuild triggered by binding.gyp, git dependency resolution, and remote URL dependency resolution by default, all of which required explicit opt-in via allowScripts, --allow-git, and --allow-remote. The release also begins phasing out granular access tokens configured to bypass 2FA, first restricting their account/org actions (~Aug 2026) and later removing their ability to publish directly (~Jan 2027), pushing teams toward trusted publishing (OIDC) or staged-publish-with-2FA-approval workflows instead. The changes respond to a year of install-time supply-chain worms (Shai-Hulud, Miasma/Phantom Gyp) that exploited default script execution and binding.gyp-based implicit builds to evade scanners.
What it is
Operational detail on npm v12's new install-time defaults — the behaviors, settings, and specific packages an engineer needs to know before upgrading. The summary establishes what changed; this covers how it fails and what breaks.
How it works
The new default is a soft skip, not a hard failure: an unapproved preinstall/install/postinstall script is skipped, npm prints a warning, and the install still succeeds. Native modules are the trap — a skipped node-gyp build does not fail the install; it fails later at runtime when your code tries to load a module that was never compiled.
The --allow-git change also closes a specific hole: a git dependency's .npmrc could override the git executable and run code even under --ignore-scripts.
Preconditions / Affected
Packages that need explicit approval to function after upgrade:
- Native modules:
sharp,better-sqlite3,bcrypt,node-sass - Binary downloaders: Cypress, Playwright, Puppeteer, Electron
Anyone carrying legacy or tool-specific keys in .npmrc should note the walked-back breaking change (below).
flowchart TD
A[npm install, v12 default] --> B{Script approved?}
B -->|Yes| C[Runs normally]
B -->|No, default| D[Skip + warn, install succeeds]
D --> E{strict-allow-scripts set?}
E -->|Yes, CI| F[Hard error]
E -->|No| G[Native module: fails later at runtime]What to do
- For CI, opt into hard failure so skipped scripts don't pass silently: set
strict-allow-scripts. - To review what needs approval, use
npm approve-scripts --allow-scripts-pending, which lists packages with scripts and the command each runs. Note the gap: it does not show what the scripts do (files pulled, network calls, env reads). .npmrcbreaking change was reverted: unknown config file keys now warn instead of erroring (EUNKNOWNCONFIG). Opt into the strict check withstrict-npmrc. Unknown CLI flags still error.- For native module authors: vlt's Darcy Clarke recommends shipping platform-specific binaries via optional dependencies (the esbuild model) instead of install scripts.
Caveats
- The v12 backport to Node 24 and Node 26 is only hoped for — the decision belongs to the Node release team, not npm. Without it, the new defaults wait for Node 27.
- The approve-scripts tooling shows commands but not behavior; deeper review (network/env/filesystem signals, new-vs-changed detection) exists only as a proposed RFC, not a shipped feature.
Technologies named here
Techniques named here
Threat actors named here
Related in Supply Chain


