
GitHub is flipping npm’s default posture. With npm v12, install-time scripts are off by default to blunt supply chain attacks. Release ships next month.
Why this matters: install-time lifecycle scripts are the largest code-execution surface in the npm ecosystem. npm install runs scripts from every transitive dependency, which means one compromised package anywhere in the tree can execute arbitrary code on a developer machine or CI runner. The new model makes script execution opt-in, not assumed.
What changes in npm v12
npm installwill no longer executepreinstall,install, orpostinstallscripts from dependencies unless they are explicitly allowed in the project.npm installwill no longer resolve Git dependencies, direct or transitive, unless explicitly allowed via--allow-git.npm installwill no longer resolve dependencies from remote URLs (e.g., HTTPS tarballs) unless explicitly allowed via--allow-remote.
This also covers native node-gyp builds: a package with a binding.gyp and no explicit install script is still blocked because npm performs an implicit node-gyp rebuild. Likewise, prepare scripts from git, file, and link dependencies are blocked the same way under the default allowScripts behavior.
By defaulting --allow-git to none, npm also closes a code-execution path where a Git dependency’s .npmrc could override the Git executable—even when using --ignore-scripts.
GitHub’s intent is direct: force explicit user approval before any code runs during npm install. In their words, “Making script execution opt-in closes that path while keeping it one command away for the packages you trust.”
How to get ready
GitHub recommends preparing now:
- Upgrade to npm 11.16.0 or newer.
- Run your normal
npm installand review the warnings. - Use
npm approve-scripts --allow-scripts-pendingto list packages with scripts, approve the ones you trust, and commit the updatedpackage.json.
After that, once you upgrade, only the scripts you approved will continue to run. Anything unapproved will stop.
Related hardening
Earlier this year, npm introduced min-release-age—a setting that tells npm to reject any package version published less than a specified number of days, reducing exposure to newly published malicious packages.
Bottom line: default-deny for install-time code, explicit approval for what runs, and tighter controls on Git and remote dependencies. This is the right direction for software supply chain defense.
Reference: View article