Verdict
The headline change, install scripts blocked by default, broke puppeteer, cypress, sqlite3 and Claude Code's npm package, and silently skipped lefthook's git hooks. esbuild, bcrypt, sharp and better-sqlite3 kept working. Every install reported success, and the only sign was a warning after the summary.
Tested on
- npm
- 12.2.0 (also 12.0.0 / 11.19.1 for comparison)
- Node
- 26.10.0 / 24.14.0
- OS
- Windows 11 Pro
Contents
npm 12 is the current latest, so npm install -g npm now lands on it. Node itself hasn’t moved: even Node 26.10.0 still ships npm 11.19.1, so you only get 12 by upgrading npm yourself, or when a CI image does it for you. I took npm 12.2.0, installed real packages into fresh projects, and used each one afterwards. That last step matters, because npm 12 reports success either way.
1. Install scripts are blocked by default
The big change. Packages can no longer run preinstall, install or postinstall scripts unless your project allows them. The install finishes, prints “found 0 vulnerabilities”, and only then:
npm warn install-scripts 5 packages had install scripts blocked because they are not covered by allowScripts:
npm warn install-scripts @sentry/cli@3.8.0 (postinstall: node ./scripts/install.js)
npm warn install-scripts cypress@16.1.1 (postinstall: node dist/index.js --exec install)
npm warn install-scripts lefthook@2.1.16 (postinstall: node postinstall.js)
npm warn install-scripts puppeteer@25.12.0 (postinstall: node install.mjs)
npm warn install-scripts sqlite3@6.0.1 (install: prebuild-install -r napi || node-gyp rebuild)
A blocked script doesn’t automatically mean a broken package. Many ship a prebuilt binary and use the script only as a check. So I used every package after installing it:
| Package | Script blocked? | Works after install? | What you see |
|---|---|---|---|
| esbuild 0.28.2 | Yes | ✅ Yes | transformed TypeScript fine |
| bcrypt 6.0.0 | Yes | ✅ Yes | hashed fine (ships prebuilt binaries) |
| sharp | No script | ✅ Yes | made a PNG |
| better-sqlite3 13.0.3 | No script | ✅ Yes | ran a query |
| Sentry CLI 3.8.0 | Yes | ✅ Yes | sentry-cli 3.8.0 |
| puppeteer 25.12.0 | Yes | ❌ No | Could not find Chrome (ver. 154.0.8037.57) (fix) |
| cypress 16.1.1 | Yes | ❌ No | No version of Cypress is installed in: … |
| sqlite3 6.0.1 | Yes | ❌ No | Could not locate the bindings file (fix) |
| lefthook 2.1.16 | Yes | ⚠️ Silently | no git hooks installed, no error |
| Claude Code, npm global install | Yes | ❌ No | claude.exe is not compatible with the version of Windows |
The pattern: packages whose script downloads or builds something essential break (a browser, an app binary, a native module). Packages that only verify a prebuilt binary keep working. lefthook is the nasty one: it installs fine and runs fine, and your pre-commit hooks just never get set up.
Allow the packages that need their scripts, then run them:
npm install-scripts approve puppeteer sqlite3 lefthook
npm rebuildapprove writes an allowScripts block into package.json, which you commit so teammates and CI get the same answer:
"allowScripts": {
"sqlite3@6.0.1": true,
"lefthook@2.1.16": true,
"puppeteer@25.12.0": true
}To approve by name instead, so upgrades keep working:
npm install-scripts approve lefthook --no-allow-scripts-pin
That writes "lefthook": true, and switching versions after that produced no warning.
For packages whose script you’ve decided you don’t need, npm install-scripts deny <pkg> records false and stops the warning. npm install-scripts ls shows what’s still undecided.
Global installs work differently: there’s no project package.json to hold approvals. npm’s own warning gives the two options, and I tested both with Claude Code:
npm install -g @anthropic-ai/claude-code --allow-scripts=@anthropic-ai/claude-code
npm config set allow-scripts=@anthropic-ai/claude-code --location=user
The full story of that failure: Claude Code “not compatible with the version of Windows”.
2. Git and tarball dependencies are refused
Dependencies fetched from git or from a tarball URL are now off by default. These do fail the install, with new error codes:
npm error code EALLOWGIT
npm error Fetching packages of type "git" have been disabled
npm error Refusing to fetch "github:jonschlinkert/is-odd"
npm error code EALLOWREMOTE
npm error Fetching packages of type "remote" have been disabled
npm error Refusing to fetch "https://registry.npmjs.org/is-odd/-/is-odd-3.0.1.tgz"
Allow them for your own package.json (root), in the project’s .npmrc:
allow-git=root
allow-remote=rootThe release notes also allow all. root is the narrower of the two, so start there.
3. Unknown flags now throw, but unknown .npmrc settings don’t (yet)
The release notes say unknown configs in .npmrc now throw. In my tests they don’t, on 12.0.0 or 12.2.0. A pnpm setting left in .npmrc still only warns:
npm warn Unknown project config "auto-install-peers". This will stop working in the next major version of npm.
Same for strict-peer-dependencies and shamefully-hoist. A user-level .npmrc warned too, and npm 11 prints the identical warning. Fix these now anyway: the warning says they’ll stop working in the next major version.
What does throw now is an abbreviated command-line flag, which older npm versions expanded for you:
npm install is-odd --leg
npm error code EUNKNOWNCONFIG
npm error Unknown cli flag:
npm error - --leg
Write flags in full: --legacy-peer-deps.
4. Smaller changes that bit in testing
| Change | What happened on npm 12.2.0 |
|---|---|
npm shrinkwrap removed |
Unknown command: "shrinkwrap". Rename npm-shrinkwrap.json to package-lock.json |
npm adduser removed |
Unknown command: "adduser". Use npm login |
npm star removed |
Surprise: npm star is-odd now runs as npm start, giving Missing script: "start" (that error explained) |
npm view --json |
Always an array now: [ "3.0.1" ] where npm 11.9.0 printed "3.0.1". Scripts that parse it break |
npm init -y |
No license field at all (was "ISC") |
| Node support | ^22.22.2 || ^24.15.0 || >=26.0.0. On Node 24.14.0 npm 12 printed npm v12.2.0 does not support Node.js v24.14.0 but still ran |
Should you upgrade?
Yes, but plan for it. Before upgrading npm, on your current version, run npm install and read the install-scripts warning (recent npm 11 releases already list the packages, worded “not yet covered by allowScripts”). That list is everything npm 12 will block. Check each one against the table above, approve the ones that download or build something, and commit the allowScripts block. Then upgrade.
How this was tested
npm 12.2.0 installed into a separate folder and run on a portable Node 26.10.0 (checksum-verified), with 12.0.0 and the bundled 11.19.1 for comparison. Each package was installed into a fresh project and then actually used: a transform, a hash, an image, a query, a browser launch, cypress verify, a version check. Download caches for puppeteer and Cypress were pointed at empty folders so nothing cached from earlier could hide a failure. Every message above is the real output.
— N.K., end of entry No.039