npm v12 makes install scripts opt-in. Here's how to prepare.
The npm team targets July 2026 for three install time default changes that will block install scripts, Git dependencies, and remote tarballs unless explicitly allowed.
The npm team targets July 2026 for three install time default changes that will block install scripts, Git dependencies, and remote tarballs unless explicitly allowed.
The single largest code-execution surface in the JavaScript ecosystem is about to get harder to use by accident. In July 2026, npm plans to ship v12 with three install-time defaults flipped from implicit to explicit, according to the GitHub Changelog post from June 9, 2026. Install scripts, Git dependencies, and remote tarballs will all stop working unless a project opts in.
The good news for teams caught off guard: every change ships as a warning in npm 11.16.0 and newer, so the migration cost is one terminal command and a code review. The bad news is the same thing, because that command surfaces transitive dependencies most projects have never read, and the resulting allowlist becomes a permanent fixture in the repository.
The first change covers lifecycle scripts. In v12, preinstall, install, and postinstall scripts from dependencies will not run unless explicitly allowed. The [npm CLI documentation for npm approve-scripts](https://docs.npmjs.com/cli/v11/commands/npm-approve-scripts) describes the new model: each script source gets approved or denied individually, and the allowlist lives in package.json. The default behavior also blocks implicit node-gyp rebuilds, the build step that runs whenever a package ships a binding.gyp, even when the package has no explicit install script. Git, file, and link dependencies lose their prepare scripts by default too.
The second change narrows what counts as an installable source. [--allow-git will default to none](https://github.blog/changelog/2026-02-18-npm-bulk-trusted-publishing-config-and-script-security-now-generally-available/), which means npm install will refuse to resolve Git URLs for direct or transitive dependencies. The flag has been available since npm 11.10.0, and the team announced the default flip in February 2026 as part of the same security push that introduced bulk OIDC trusted publishing.
The third change does the same thing for remote URLs. [--allow-remote will default to none](https://github.blog/changelog/2026-06-09-upcoming-breaking-changes-for-npm-v12/), blocking HTTPS tarballs, GitHub tarball references, and other remote sources unless a project explicitly allows them. The flag has been available since npm 11.15.0. Two related flags, --allow-file and --allow-directory, are documented in the npm config reference but are not changing their defaults in v12. They sit alongside the others, which has caused some confusion in early discussions.
The list of packages and tools that need an explicit nod from the new allowlist is longer than most teams expect. Native modules top it: sharp, better-sqlite3, canvas, bcrypt, node-sass, bufferutil, utf-8-validate, and most database drivers all run native code at install time. Test frameworks like Cypress, Playwright, and Puppeteer download browser binaries during install. Electron pulls in platform binaries. Husky installs git hooks. None of these will install silently under v12 defaults.
Monorepos and projects that lean on Git-sourced dependencies are the second exposure. A package declared as "my-internal-lib": "github:myorg/my-internal-lib" will fail to resolve in v12 without a matching --allow-git configuration. The same applies to any transitive Git dependency, which means a single Git-sourced package deep in a dependency tree can break a fresh install.
Remote tarballs are the third exposure, and the one most teams do not know they have. Any dependency declared as a direct HTTPS URL, or any tool that pulls in such a dependency as a transitive, will fail to resolve.
The npm team's official migration recipe starts with a one-line audit: npm approve-scripts --allow-scripts-pending. That command lists every script the new defaults would block, then sits in a read-only review state. From there, the maintainer runs [npm approve-scripts <package>](https://docs.npmjs.com/cli/v11/commands/npm-approve-scripts) to allow individual packages or [npm deny-scripts <package>](https://docs.npmjs.com/cli/v11/commands/npm-deny-scripts) to block them, and commits the resulting allowlist to package.json. By default, npm approve-scripts <pkg> pins approval to the installed version (pkg@1.2.3); the --no-allow-scripts-pin flag approves any future version by name.
The point of the allowlist is not bureaucratic. It is a durable, reviewable contract for what is allowed to execute on developer machines and CI runners. A reviewer can see exactly which scripts run during install, and any change to that allowlist shows up in pull requests like any other dependency change.
The friction is real. This shift moves maintenance work onto every project that installs npm packages. A small library with a few dependencies and no native code will need to do almost nothing. A monorepo with a dozen native modules, a handful of Git-sourced internal libraries, and a CI matrix that pulls remote tarballs will spend hours on the migration. The cost falls on maintainers, not on the npm team, and there is no equivalent of a "migrate for me" tool. There is also a real risk of misconfigured CI: a CI image running npm 11.16.0 with strict-allow-scripts set, or npm 12 once it ships, will fail in surprising ways if the allowlist does not match the install path. The fix is to commit the allowlist and treat it as part of the build configuration, but the first build to fail is the first build to teach a team that lesson.
The full migration is available now. Upgrading to npm 11.16.0 turns all three defaults into warnings. Running npm install against a current project surfaces every dependency the new rules would block, and the warnings tell teams exactly what to add to the allowlist. CI images can flip to strict-allow-scripts today to enforce the v12 behavior without the upgrade, which is the closest thing to a dry run.
What to watch next: the npm team's July 2026 estimate is forward-looking, and a slip by a release cycle or two is common for default-flipping changes. The community discussion thread is the best place to track migration friction in real time, especially around native modules and Git dependencies, and any change to the named flag list before the v12 cutoff will land there first.