Blog
By Published Updated 10 min read

npm v12 Install Scripts: What Breaks and How to Fix It

npm v12 blocks dependency install scripts by default. What changed, why builds break, how approve-scripts and allowScripts work, and a safe upgrade plan.

Working through a similar problem? Tell us what you want to build.

Legacies is an independent digital product brand based in Bucharest, Romania, founded by Horia Stan and Alexandru Tălnaci, and we have typed npm install so many times that it used to feel harmless. It is not. An install can execute code before anyone has opened a package's source, which makes the install step part of your security boundary.

npm v12 changes that default. Since July 8, 2026, dependency install scripts do not run unless your project explicitly allows them, and git and remote tarball dependencies are blocked too. Some builds will break, usually quietly, and the fix is a short, reviewed allowlist in package.json.

Quick answer

What npm v12 changed, exactly

According to the official GitHub changelog, three behaviors that used to be automatic are now opt-in:

SettingOld defaultnpm v12 defaultWhat it affects
Dependency install scriptsRun automaticallyOff until allowedpreinstall, install, postinstall, implicit node-gyp
allow-gitallnoneDependencies that point to a git repository
allow-remoteallnoneDependencies that point to an HTTPS tarball URL

The change was announced in June and npm 11.16.0 and later already printed warnings, so teams had time to prepare. The npm docs for install scripts describe the new behavior plainly: install commands silently skip lifecycle scripts for any dependency without a matching allowScripts entry, then print a list of what was skipped.

The git change matters more than it looks. The npm config docs note that git dependencies run git against a remote repo and may install configuration the project does not control. Coverage of the release reported that a git dependency's own .npmrc could even override the git executable with --ignore-scripts set. Blocking git deps by default closes that path.

Why npm finally flipped the default

Install scripts were the engine of most recent npm worms. The pattern GitHub describes in its July 2026 security update is simple: steal credentials, publish malware, run it at install time, steal more credentials.

A month after npm v12 shipped, the ChainDrop worm showed exactly why. It poisoned 444 packages and 2,212 versions in under four hours, and every poisoned version carried a preinstall dropper. Projects that did not run dependency scripts did not execute the payload. The malicious files still landed in node_modules, so this is not a complete defense, but it removes the automatic trigger.

If a package genuinely needs a script to compile a native module, you can approve it on purpose. If it does not, there is no reason to grant it that privilege by accident. We go deeper on the full defense stack in our npm supply chain security checklist.

What breaks after the upgrade

The tricky part is that failures rarely show up during install. npm finishes, prints a list of skipped scripts that is easy to miss in CI logs, and the break appears later.

Typical suspects, as named in coverage by Socket and InfoQ:

The symptoms are familiar: a "cannot find module" error pointing at a .node file, a test runner that cannot find its browser, or an app that crashes on the first database call. If your Docker build passed but the container fails on start, check the skipped scripts list first.

How to approve install scripts the right way

npm gives you a small set of commands that manage the allowScripts field for you. The approve-scripts docs cover the details. The short version:

npm approve-scripts --allow-scripts-pending   # list blocked scripts (read-only)
npm approve-scripts better-sqlite3 canvas     # approve, pinned to installed versions
npm deny-scripts some-telemetry-pkg           # keep a package blocked
npm install-scripts prune --dry-run           # preview stale entries after upgrades

The result lives in package.json, so it goes through code review with everything else. An example of what it looks like:

{
  "allowScripts": {
    "[email protected]": true,
    "some-telemetry-pkg": false
  }
}

Approvals are pinned to the exact version by default. When the package updates, npm asks again. That is the point: you reviewed one version, not every future one. You can write name-only entries with --no-allow-scripts-pin, but we only do that for packages from maintainers we already trust a lot.

Two more rules from the docs are worth knowing. A false entry always wins, so approve-scripts --all will not silently re-allow something you denied. And for global installs or npx, where there is no project package.json, you use the --allow-scripts flag or a user-level config instead.

Avoid the approve-all shortcut

npm approve-scripts --all exists, and it is tempting on a deadline. It also recreates the old default with extra steps. We run the pending list, read what each script does, and approve one package at a time. On a typical web project, the list is short.

A safe upgrade plan for small teams

  1. Find out which npm you actually runRun npm -v on laptops, in CI and inside Docker images. npm 12 requires Node 22.22.2+, 24.15.0+ or 26+, per its package.json engines field, and your Node install may still bundle npm 11.
  2. Upgrade in a branch, not in productionInstall npm 12, run a clean npm ci, then run the full build and test suite. Read the skipped scripts list at the end of the install.
  3. Approve deliberatelyUse the pending list, approve what you need pinned to versions, deny what you do not, and commit the change in one reviewed pull request.
  4. Check git and tarball dependenciesReplace git URL dependencies with published versions where you can. If you cannot, allow git per project in .npmrc, not globally.
  5. Pin npm in CI and DockerMake every environment use the same major version so local and CI behavior match.

The token deadline you should not miss

npm v12 shipped alongside a token change. Granular access tokens with 2FA bypass lost the ability to skip 2FA for sensitive account actions in early August 2026. In the second phase, expected around January 2027, those tokens will no longer publish directly. Publishing will need trusted publishing with OIDC or staged publishing, which has been generally available since May 2026 and holds each release until a maintainer approves it with 2FA.

If your team publishes internal or public packages from CI with a long-lived token, plan the move now. A token that can both run in CI and publish a package is a high-value target.

Why this is a reliability issue, not just a security one

It is easy to file dependency hygiene under "developer stuff". In practice, it is a customer experience issue. A compromised package can leak credentials, block a launch, or force a rushed rebuild at the exact moment a business needs its site or app to work. A surprise build break from an npm upgrade can do the same, more quietly.

That is why we build client projects to be maintainable after launch: clear dependencies, predictable builds, and an update path the next developer can follow. Our Monthly Maintenance plan includes monthly technical updates like this one, for 499 lei per month (about 95 EUR). If you want a quick read on your public site first, our free website audit checks speed, mobile and SEO basics in seconds, no signup.

If you are deciding on a stack for a new project, we explained our reasoning in why we choose the Next.js App Router, and the same maintenance mindset applies to Next.js security patches.

Do it yourself or bring someone in?

Do it yourself if you have one app, a developer who owns the build, and a test suite you trust. The upgrade above takes an hour or two, and the allowlist is usually a few lines.

Bring someone in if your builds already feel fragile, if nobody knows why a git dependency is there, if several projects share CI tokens, or if you publish packages and the January 2027 deadline is on your plate. The headline is not that npm became inconvenient. It is that the old default was too trusting, and good software is mostly sensible defaults applied before an incident forces the conversation.

Frequently Asked Questions

Does npm v12 disable postinstall scripts?

Yes, for dependencies. Since npm v12, dependency preinstall, install and postinstall scripts are skipped unless the package is listed in the allowScripts field of your package.json or allowed through config. Your own project's scripts still run normally.

Why did my build break after upgrading to npm 12?

Most likely a dependency needed an install script to compile a native module or download a binary, and npm skipped it. Check the list of skipped packages printed at the end of the install, or run npm approve-scripts --allow-scripts-pending, then approve only the packages you actually need.

How do I allow install scripts for one package in npm 12?

Run npm approve-scripts package-name in your project. npm adds a pinned entry with the installed version to allowScripts in package.json, so the approval only covers the version you reviewed. Commit the change so CI and your teammates get the same policy.

Is it safe to run npm approve-scripts --all?

It works, but it largely brings back the old behavior where every dependency could run code at install time. It is safer to review the pending list and approve packages one by one, which on most web projects means only a few entries.

Why are git dependencies blocked in npm v12?

Because allow-git now defaults to none. Git dependencies run git against a remote repository and can bring in configuration your project does not control. You can still allow them per project in .npmrc or per command, but it is better to switch to published registry versions when possible.

Do I need npm v12 if I already use ignore-scripts?

ignore-scripts=true already blocks install scripts, but it blocks everything, which is why many teams turned it off again. npm v12 gives you a reviewed allowlist instead, plus the new git and remote dependency defaults. If you keep ignore-scripts=true, remember it overrides the allowlist.

Which Node.js versions support npm 12?

According to the engines field in npm 12's package.json, it runs on Node.js 22.22.2 or later in the 22 line, 24.15.0 or later in the 24 line, and Node.js 26 and newer. Your Node install may still bundle npm 11, so check npm -v and upgrade npm separately if needed.

Node.jsSupply Chain SecurityJavaScriptDeveloper Tools
Website maintenance and updatesProjects we have builtFree website auditAbout Legacies