Published Build3 min read
npm 12 turns install scripts off by default, and the allowlist is now your ticket
Dependency preinstall, install, postinstall and git prepare scripts no longer run unless a project names them. Every repo with native modules or git dependencies has migration work this quarter.
Written for builders.See today for builders
What happened
- npm has released npm 12, shipping with a set of security related default changes to npm install.
- npm 12 also deprecates granular access tokens that bypass two factor authentication.
- npm is the default package manager for Node.js, is maintained by GitHub, ships with Node.js, and hosts the largest software registry in the world.
- npm 12 turns three install behaviours that previously ran automatically into ones developers explicitly opt into.
- The changes were first announced in June and have been available behind warnings since npm 11.16.0, so teams could prepare before upgrading.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
npm 12 is out, and the package manager GitHub maintains and Node.js ships has moved install-time code execution from opt-out to opt-in [1][3]. If your build touches native modules, a git dependency or a CI runner that installs from a clean tree, you now own an allowlist and the work to produce it [6][8][9].
The release bundles security-related default changes to npm install with the deprecation of granular access tokens that bypass two factor authentication [1][2]. Three behaviours that previously ran automatically are now explicit opt-ins [4]. None of this arrived unannounced: the changes were first published in June and have been live behind warnings since npm 11.16.0 [5].
The headline default is allowScripts, now off. Dependency preinstall, install and postinstall scripts do not run unless a project allows them [6]. That includes implicit node-gyp builds for any package containing a binding.gyp, even where no install script is declared [7], which is the clause that will surprise teams who believe they have no postinstalls. prepare scripts from git, file and link dependencies are blocked the same way [8]. The workflow is review what is pending, approve what you trust, and commit the resulting allowlist in package.json [9].
Two further defaults target non-registry sources. --allow-git is now none, closing a code execution path where a git dependency's own .npmrc could override the Git executable even with --ignore-scripts set [10]. --allow-remote is now none, blocking https tarball dependencies [11]. --allow-file and --allow-directory are unchanged [12].
GitHub's migration discussion recommends allowing what is already in the tree first, then tightening, and documents recipes for native modules, Cypress, Playwright, Puppeteer, Electron and Husky [13]. Put two sharp edges in the ticket before anyone starts. Commenters on the thread flagged that an existing ignore-scripts=true takes precedence and silently defeats the allowlist [15], so CI images hardened years ago will report success while approving nothing. And because npm approve-scripts reads from node_modules, a package that is not yet installed errors with ENOMATCH, which makes adding a new dependency a chicken and egg [16]. Global installs and npx cannot use approve-scripts at all and need the config instead, for example npm config set allow-scripts=canvas,sharp --location=user [14].
On the size of the prize: JFrog reports the three vectors were involved in roughly 53 percent of malicious npm attacks observed in the past year [22], which leaves about 47 percent untouched by these defaults [23]. Writing on OpenSourceMalware, one analyst noted that esbuild, sharp, core-js, puppeteer and bcrypt all rely on lifecycle scripts, and warned that repeated broken builds will turn deny by default into 'a click-through prompt' while pushing attacker activity onto surfaces with less visibility [21].
Reaction has been broadly supportive, with the Hacker News thread drawing 484 points and more than 200 comments [17]. atraac wrote that "postinstall scripts should've been removed long time ago, it's the cancer of NPM packages" [18]. gear54rus pointed to legitimate uses such as patch-package [19], and cookiengineer argued the allowlist 'has no scope' and leaves it 'unpredictable if any of your dependencies of dependencies needs a script' [20]. npm is also the last major package manager here: pnpm has offered install script allowlisting for years [24], and on release cooldowns pnpm shipped minimumReleaseAge in 10.16, yarn added npmMinimalAgeGate in 4.10.0 and bun followed in 1.3, ahead of npm's own min-release-age in 11.10.0 [25].
Watch whether committed allowlists get reviewed in pull requests or rubber stamped, whether the ENOMATCH path gets fixed for uninstalled packages, and whether allow-scripts gains the scoping cookiengineer says it lacks [16][20].
Claim ledger
Ranked by verification strength, evidence, and original report placement.
- [1]
npm has released npm 12, shipping with a set of security related default changes to npm install.
ReportedView cited source - [2]
npm 12 also deprecates granular access tokens that bypass two factor authentication.
ReportedView cited source - [3]
npm is the default package manager for Node.js, is maintained by GitHub, ships with Node.js, and hosts the largest software registry in the world.
ReportedView cited source - [4]
npm 12 turns three install behaviours that previously ran automatically into ones developers explicitly opt into.
ReportedView cited source - [5]
The changes were first announced in June and have been available behind warnings since npm 11.16.0, so teams could prepare before upgrading.
ReportedView cited source - [6]
allowScripts now defaults to off: dependency preinstall, install and postinstall scripts no longer run unless they are explicitly allowed in a project.
ReportedView cited source
Sources & coverage · 1 publisher
The reporting this story was synthesized from, earliest first. Every link goes to the original.
- infoq.comDaniel CurtisAug 13npm 12 Released: Install Scripts Off by Default as Registry Moves to Explicit Trust
Additional citations
- commenters on GitHub's migration discussion thread, via InfoQ
- Hacker News commenter atraac, quoted by InfoQ
- Hacker News commenter gear54rus, quoted by InfoQ
- Hacker News commenter cookiengineer, quoted by InfoQ
- an analyst writing on OpenSourceMalware, via InfoQ
- JFrog, via InfoQ

