"Install-time lifecycle scripts are the single largest code-execution surface in the npm ecosystem. Every npm install runs scripts from every transitive dependency, so a single compromised package anywhere in your tree can execute arbitrary code on a developer machine or CI (continuous integration) runner," said maintainer Leo Balter.
What GitHub is changing in npm 12
GitHub will change npm's defaults in npm 12 (due in July) so that install-time lifecycle scripts no longer run automatically. Scripts configured for preinstall, install, or postinstall will be blocked by default unless an explicit permission is granted via an allowlist mechanism. The change converts previously optional, opt-in flags into the new default posture for npm, with the goal of reducing a long‑exploited code‑execution surface.
Specific defaults that will flip
The release of npm 12 implements three security-oriented default changes described in the announcement:
- preinstall/install/postinstall scripts will not run unless explicitly permitted with allow-scripts;
- the --allow-git flag, which enables pulling dependencies from remote Git URLs, will default to off—closing an attack path where a malicious .npmrc could override the Git executable and achieve arbitrary code execution;
- allow-remote will default to none, blocking dependency downloads from remote URLs entirely.
Allowing scripts will still be possible through an allowlist in the package.json configuration file; that approval will be pinned to the installed version of a package by default.
Compatibility: real packages that require script approval
The change is explicitly breaking for projects that rely on install‑time scripting. Balter cautioned maintainers and developers to run commands to permit scripts for every currently installed package that requires them, saying, "This gets you protected against new, unexpected scripts immediately." He also recommended reviewing those packages afterward and denying scripts where they are not needed.
Packages that typically require script approval include native modules that compile on install, testing tools like Playwright and Puppeteer (which fetch binaries via postinstall), and Electron, which wraps the Chromium browser engine for cross-platform desktop applications.
How developers can prepare with current npm 11.16 and earlier flags
These protections were already available as opt-in flags since npm 11.10.0 (released in February), which also introduced min-release-age to block installation of package versions newer than a specified number of days. The source recommends that developers using the current npm 11.16 set the relevant flags in .npmrc or via environment variables as best practice; doing so both improves immediate safety and prepares projects for the new defaults in npm 12.
An operational caveat: the existing ignore-scripts flag does not support an allowlist (except via an additional tool) and will override allow-scripts. Developers who have ignore-scripts set to true will need to remove it to enable approved scripts to run. The allowScripts setting exists in npm 11 but is advisory only.
Responses, limitations, and alternatives
There is broad agreement that the changes improve npm security and are long overdue, but experts warn they are not a complete fix. "Now all the malware can move from the install script to the module itself where it will inevitably still be run," said one developer, reflecting a common critique.
Some voices recommended switching package managers: pnpm already ships with safer defaults including a minimum release age, and a pull request notes that "npm is the only remaining major package manager that runs dependency install scripts by default. pnpm v10+, Yarn Berry, Bun, and Deno all block them." That comparison frames npm 12 as an effort to bring npm's defaults closer to alternatives that had already taken a more restrictive stance.
What this means for developers, CI teams, and open-source maintainers
- Developers and CI teams: expect breaking behavior when you upgrade to npm 12; temporarily enable allow-scripts for packages you know you need, then review and tighten approvals.
- Open-source maintainers: projects that depend on install-time actions—native builds, browser-driver fetchers, Electron packaging—should document required approvals and consider moving heavy work into safer, explicit build steps where practical.
- Security teams and repo owners: adopt the npm 11.16 flags in .npmrc or environment variables now to gain protections immediately and reduce surprises when npm 12 becomes the default.
GitHub's default flip in npm 12 narrows a long-exploited attack surface—one implicated by malicious packages such as the notorious Shai-Hulud worm—but it does not eliminate avenues for abuse. The immediate, pragmatic task for teams is mechanical: permit and pin the scripts they need, then remove approval where it is unnecessary. The broader question—whether malware authors will simply move their payloads into module code rather than install scripts—remains, and the ecosystem's next steps will show whether these defaults materially reduce supply-chain risk over time.




