GitHub has announced a set of critical changes in npm version 12, the most important of which is disabling dependency install scripts by default. The change affects all developers using the Node.js ecosystem: the npm install command will no longer automatically run preinstall, install and postinstall scripts from dependencies without explicit approval. The npm 12 release is scheduled for next month. To prepare, GitHub recommends upgrading to npm 11.16.0 or later and using the npm approve-scripts command to explicitly approve trusted packages.
What exactly is changing
GitHub has described lifecycle scripts executed during installation as “the largest code execution surface in the entire npm ecosystem.” The problem is that npm install runs scripts from every transitive dependency — which means a single compromised package anywhere in the dependency tree can execute arbitrary code on a developer’s machine or in a CI/CD environment.
npm 12 introduces three key restrictions:
- Blocking install scripts:
npm installwill not runpreinstall,installandpostinstallscripts from dependencies unless they are explicitly allowed in the project configuration. - Blocking Git dependencies: direct and transitive Git dependencies will not be resolved without explicitly specifying the
--allow-gitflag. - Blocking remote
Native builds via node-gyp are also subject to blocking: packages with a binding.gyp file but without an explicit install script will also be blocked, because npm runs an implicit node-gyp rebuild command for them. prepare scripts from Git, file, and symlink dependencies are blocked in the same way.
Closing the .npmrc bypass
The default setting of --allow-git to none deserves special attention. This closes an attack vector where an .npmrc file inside a Git dependency could override the Git executable being used. Notably, this code execution path worked even when using the --ignore-scripts flag, which until now was considered the primary mitigation against malicious install scripts.
Who is affected
The changes will affect virtually the entire Node.js ecosystem. The greatest impact will be felt by:
- Projects with native modules — any dependencies that use node-gyp to compile C/C++ add-ons will require explicit approval.
- CI/CD pipelines — automated builds that rely on postinstall scripts to configure the environment may break unless their configuration is updated.
- Projects with Git dependencies — monorepos and projects that reference private repositories directly will require explicit authorization.
If no action is taken, upgrading to npm 12 will lead to dependency installation failures — all unapproved scripts will simply stop running.
How to prepare
GitHub recommends the following steps:
- Upgrade npm to version 11.16.0 or later.
- Run a standard dependency installation and review the warnings that are displayed.
- Run
npm approve-scripts --allow-scripts-pendingto view the list of packages that contain scripts. - Approve trusted packages and commit the updated
package.jsonto the repository.
After upgrading to npm 12, only explicitly approved scripts will be executed. Anything left unapproved will be blocked.
It is worth noting that npm previously introduced the min-release-age setting, which allows you to reject package versions published less than a specified number of days ago, as protection against freshly released malicious packages. Disabling scripts by default in npm 12 is a logical continuation of this strategy to strengthen software supply chain security.
npm’s move to an explicit script approval model is a fundamental shift from “trust by default” to “zero trust” in dependency management. Development teams should start auditing dependency scripts now on npm 11.16.0+ so that the upgrade to npm 12 does not result in unexpected failures in build processes.