Replies: 5 comments 5 replies
This comment has been hidden.
This comment has been hidden.
-
|
Will Node 26 eventually ship with npm 12? Or will that wait until Node 27? |
Beta Was this translation helpful? Give feedback.
-
|
Would’ve been nice with a default min package age too👍 |
Beta Was this translation helpful? Give feedback.
-
|
There should be a way out of ignore-scripts, while keeping it for NPM < 11.16.0 In a shared CI environment, we set a global |
Beta Was this translation helpful? Give feedback.
-
|
What is the recommended way to install new packages that include scripts? Current behaviour when Am I missing something? |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi everyone — sharing this so maintainers, application developers, and CI operators have time to prepare for behavioral changes landing in npm v12 (estimated July 2026). Everything below is already available in npm 11.16.0 so you can migrate today.
What is changing in v12
Three
npm installdefaults change, each closing an automatic code-execution or code-fetch path:preinstall,install, andpostinstallfrom dependencies won't run unless explicitly allowed.--allow-gitdefaults tonone. Git dependencies (direct or transitive) won't resolve unless allowed. Available since npm 11.10.0; previously announced Feb 2026.--allow-remotedefaults tonone. Remote URL dependencies (e.g. https tarballs) won't resolve unless allowed. Available since npm 11.15.0.--allow-fileand--allow-directoryexist too, but their defaults are not changing in v12.Most of this post focuses on install scripts, since that's the migration with the most moving parts.
Why install scripts
Install-time lifecycle scripts are the single largest code-execution surface in the npm ecosystem. Every
npm installruns scripts from every transitive dependency, so a single compromised package anywhere in your tree can execute arbitrary code on a developer machine or CI runner. Making script execution opt-in closes that path while keeping it one command away for the packages you trust.The commands
npm approve-scripts— allow scripts for specific dependencies. Writes the allowlist to yourpackage.json.npm deny-scripts— explicitly block scripts for a dependency (survives--alland future review prompts).npm approve-scripts --allow-scripts-pending— read-only: lists every package whose scripts aren't yet covered, without changing anything.allow-scriptsconfig /--allow-scripts=<pkg,...>— the mechanism for global installs andnpx(see below).strict-allow-scriptsconfig /--strict-allow-scripts— opt into the v12 enforcing behavior today (see "Try the breaking behavior now").By default,
npm approve-scripts <pkg>pins the approval to the installed version (pkg@1.2.3). Use--no-allow-scripts-pinif you'd rather allow any future version by name.Recommended first step: allow what you already have
If you're adopting this on an existing project, the fastest safe migration is to allow everything currently in your tree first, then tighten later — rather than agonizing over each package and delaying rollout:
This gets you protected against new, unexpected scripts immediately. You can then
npm deny-scriptsanything you don't actually need."If you have X, do Y" — migration recipes
Native modules (anything built on
node-gyp)Includes
sharp,better-sqlite3,canvas,bcrypt,node-sass,bufferutil,utf-8-validate, and many DB drivers. Note: these are blocked even if they have no explicit install script, because npm runs an implicitnode-gyp rebuildfor any package with abinding.gyp.npm approve-scripts # approve node-gyp + the native packages you useCypress, Playwright, or Puppeteer
These download browser/runtime binaries via
postinstall.npm approve-scripts # approve: cypress / playwright / @playwright/browser-* / puppeteerOr control downloads yourself with each tool's explicit command (
npx playwright install,npx cypress install) afternpm install.Electron
npm approve-scripts # approve: electronHusky (git hooks)
npm approve-scripts # approve: huskyOr move husky setup into an explicit
preparescript you invoke during bootstrap.CI pipelines
npm approve-scriptsso installs are reproducible.--strict-allow-scriptsso CI fails loudly on anything unreviewed (see below).Publishing a package that needs install scripts
Your downstream users won't run your scripts by default in v12. Two things help:
npm approve-scripts.prebuild,prebuildify,node-pre-gyp) or move setup into an explicit command users run after install.If your package has high download volume or many dependents, the npm team may reach out to coordinate — or reach out to us first (see "How to get help").
Try the breaking behavior now
In v11 the default is a warning — scripts still run. If you want the actual v12 behavior today (unreviewed scripts cause a hard failure instead of being skipped), set:
# .npmrc strict-allow-scripts=trueor pass
--strict-allow-scriptson the command line. This is the recommended posture for CI, where you want unreviewed scripts to fail the build rather than silently skip.--ignore-scriptsand--dangerously-allow-all-scriptsboth override it.Global installs and
npxnpm approve-scripts/npm deny-scriptsonly work inside a project with apackage.json— they'll error (EGLOBAL) for global installs andnpx. For those contexts, use theallow-scriptsconfig or flag instead:Migrating from a blanket
ignore-scripts=trueIf you currently keep
ignore-scripts=truein your.npmrc,npm approve-scripts --allow-scripts-pendingwill still list the packages that would need approval, so you can move from a blanket ignore onto a precise allowlist. Note that whileignore-scripts=trueremains set, it takes precedence and no scripts run — the allowlist does not override it. Removeignore-scriptsonce your allowlist is in place.Timeline
strict-allow-scriptsallowScriptsoff by default;--allow-gitand--allow-remotedefault tononeHow to get help
allowScripts.maintainer-outreach.References
allow-scriptsconfignpm approve-scriptsnpm deny-scriptsBeta Was this translation helpful? Give feedback.
All reactions