Repository navigation
Plans for npm 12 #1161
Description
The npm team is working on npm 12, which is estimated to release in July 2026. I'm opening this issue to discuss the planned breaking changes and to work out how we land them in Node.js, following the same process used for npm 9 (#778) and npm 10 (#884).
npm 12 is a security-focused release. Every breaking change turns an npm install behaviour that runs automatically today into one you opt into. The reason I'm filing this early is that a lot of users have asked for these protections to reach the active release lines, specifically Node 24 and Node 26, rather than waiting for the next major to age into LTS. I'd like the release team's input on whether that's possible.
All of these changes are already available behind warnings in npm 11.16.0 and later, so people can test against them before the major lands. They were announced on the GitHub blog on 9 June 2026, and there is an open community discussion for feedback.
Breaking changes
We plan to follow the guidelines on integrating npm with Node, and we consider the changes below to fall within them.
Install scripts are opt-in (allowScripts defaults to off)
npm install will no longer run preinstall, install, or postinstall scripts from dependencies unless you have allowed them in your project. This includes native node-gyp builds: a package that ships a binding.gyp with no explicit install script is still blocked, because npm runs an implicit node-gyp rebuild for it. prepare scripts from git, file, and link dependencies are blocked the same way.
You allow scripts per package through a new allowScripts field in package.json, managed with two new commands, npm approve-scripts and npm deny-scripts. This is RFC 54. It brings npm in line with pnpm, Yarn, Bun, and Deno, which all block dependency install scripts by default already.
Git dependencies are opt-in (--allow-git defaults to none)
npm install will no longer resolve git dependencies, direct or transitive, unless you allow them with --allow-git. This closes a code-execution path where a git dependency's .npmrc could override the git executable, which ran even with --ignore-scripts. The change was announced on 18 February 2026 and is available in npm 11.10.0 and later.
Remote URL dependencies are opt-in (--allow-remote defaults to none)
npm install will no longer resolve dependencies from remote URLs, such as https tarballs, direct or transitive, unless you allow them with --allow-remote. This is available in npm 11.15.0 and later. The related --allow-file and --allow-directory flags keep their current defaults in npm 12.
Why we'd like these in Node 24 and 26
This is the part I most want the release team's input on.
All three defaults exist to cut off code that runs during npm install, before any application code is imported.The supply-chain attacks of the last two years leaned on exactly this. event-stream, the Lazarus campaigns, the chalk and debug compromise, the Shai-Hulud worm, and the Axios hijack in March all used an install script or install-time resolution as the entry point.
Node's LTS policy already allows a semver-major change to ship as a semver-minor when the reason is security. npm took this path in npm 9 for the unscoped _auth change (see the discussion in #778), and backported it rather than holding it for the newest line. The npm 12 defaults are the same category of change. So I think there's a reasonable case for getting them onto the active lines, where most users actually are, instead of only the next major.
I know that shipping breaking changes into LTS has been contentious in past npm updates (#884), which is why I want to raise this now and work through the concerns together rather than at release time.
Testing
We'll hold npm 12 to the integrating-with-node guidelines: no new failures in Node's own test suite, no new failures installing or testing the citgm package set, and no backwards-incompatible changes to existing package-lock.json files.
As with npm 10, we'll run our node-integration workflow in GitHub Actions against every npm 12 prerelease so regressions show up early, and CI runs on every PR the npm team opens.
Timeline
Prereleases are already underway. npm@12.0.0-pre.0 shipped on 20 May 2026, and the next prerelease (12.0.0-pre.1) is pending in the release PR npm/cli#9387. The goal is to make npm 12 testable inside Node as early as possible: CI-only PRs to main during the prereleases, a review-ready PR once npm 12 is stable, then backport PRs for the Node 26 and Node 24 release lines.
| # | Task | Status / target |
|---|---|---|
| 1 | First prerelease (npm@12.0.0-pre.0) |
Done, 20 May 2026 |
| 2 | Further prereleases (12.0.0-pre.1 and later) |
In progress (pre.1 pending in npm/cli#9387) |
| 3 | CI-only PR(s) to Node.js main |
During prereleases |
| 4 | Major release (npm@12.0.0) |
Targeting July 2026 |
| 5 | Open review-ready PR to Node.js main |
With major release |
| 6 | Land npm 12 on Node.js main |
After review |
| 7 | Promote npm@12.0.0 to latest |
July 2026 |
| 8 | Open PR to backport to Node.js 26 | After landing on main |
| 9 | Open PR to backport to Node.js 24 | After landing on main |
| 10 | Release npm 12 in Node.js 26 | Tentative |
| 11 | Release npm 12 in Node.js 24 | Tentative |
Dates are tentative and depend on how prerelease testing goes.
Activity
ljharb commentedon Jun 11, 2026
I think it's definitely worth it for 26, since it's a pretty new major, it's not LTS yet, and anyone impacted can add
to
.npmrcor~/.npmrcto unblock themselves (although hopefully they wouldn't want to).For 24 is a tougher sell, but I'd love to hear releasers' thoughts on it.
richardlau commentedon Jun 12, 2026
My opinion is that this should only land in Node.js 26 and 24 as Node.js security updates. There is a clear Node.js release policy (as mentioned) for this, and there would be more opportunity to communicate the change.
Since there would be options to opt back into the old behaviour, I am in favour of releasing npm 12 in Node.js 24 and 26 in a security release.
wesleytodd commentedon Jun 15, 2026
Landing this on 24/26 breaks the guidance here if you treat it in spirit instead of as written AFAICT:
Specifically this would mean that a package is installed and
ls's just fine but any binary dep was never built and thus the same install prior tonpm@12would be broken despite passing these tests. IMO the spirit of that guideline implies that the install is functional despite not saying that. I can open a PR to fix that gap if necessary, but want to discuss here to see if there is a consensus on this first.Security release or not, this release contains changes with very widespread impact. Saying apps can set
.npmrcconfigs does not mitigate the impact to users who may not understand what these changes even do breaking their builds. As discussed in slack the only way these changes can be done in a way that unimpeachably semver compatible would be if node also shipped a config override in it's default installers. This would scope the breaking change to just folks using non-standard installers (of which I happen to be one) and thus maybe meets the spirit of the policy but still is technically breaking for this smaller set of users.So, while I am very happy with the direction for this npm major I am opposed to this shipping in any existing node.js major lines. Folks can and are already using the configuration features in their apps, but the vast majority of folks rely on the default experience being stable (even at the cost of poor security or hygiene) and that is on the top of the projects technical values.
jenseng commentedon Jun 15, 2026
This is a great change security-wise. That said, I have serious reservations about it landing in an already released major -- particularly v24 given its broad usage.
For example, In CI systems like GitHub Actions, it's extremely common to do something like:
If your tests rely on native deps, your jobs will inexplicably start failing as soon as node 24 ships with npm 12. While you can pin back to 24.16.0, or add the necessary entries to your .npmrc, this will not be obvious. I anticipate this causing a large amount of pain and churn for developers and platform providers alike.
targos commentedon Jun 16, 2026
I don't know how that has been implemented in the end, but the RFC says that the default behaviour would be to print clear warnings to the console about the packages that have install scripts and what to do to allow them. Users wouldn't necessarily be completely lost (I know, many people don't pay attention to warnings).
MikeMcC399 commentedon Jun 16, 2026
wesleytodd commentedon Jun 16, 2026
Why would the same concern and decision logic not apply to Node 26? Despite not being LTS yet it is not usually acceptable to land breaking changes in the
currentphase either.Is anyone taking a strong stance that this is a security release that justifies a mid-major breaking change release? I understand that it could be done, but I would argue that because the feature is usable on
npm@11there is no incentive to rush a change that could have many negative effects like what @Waldenesque points out and what @MikeMcC399 uses to justify this in 24.Again, I am really happy to push forward on driving adoption of the feature and
npm@12. I just don't think folks are presenting a case that justifes breaking the semver contract here. I think rushing this change will not serve to push adoption of the new feature, it is more likely to strand some segment of users and annoy some other segment.richardlau commentedon Jun 16, 2026
+1 Node.js 26 is already released and follows semver. The fact that it is not yet considered Long Term Support is not an excuse to ignore semver outside of the security provision.
To clarify my own earlier comment I'm okay either way, but if we (as a whole) decide that it is worth making the breaking change, then for me it has to be done under the existing provision for security fixes -- even on Node.js 26.
I'm not too keen on the idea of including npm 12 in 26 and/or 24 but Node.js overriding the defaults -- I think we'd be better off sticking with npm 11 in that scenario.
JamieMagee commentedon Jun 22, 2026
Thanks everyone, this is the conversation I was hoping for.
@richardlau and @wesleytodd you make a fair point that "26 is new and not LTS yet" isn't the right framing. 26 follows semver too. If these defaults land in 24 or 26, the only honest justification is the security provision in the release policy, and it has to clear that bar for both or neither.
The policy allows an npm semver major to land as a node semver minor when it's a critical security fix, as long as there's a revert option. I believe all three npm 12 breaking changes fit that criteria. Each one closes a path that runs attacker-controlled code during npm install, before any application code is imported:
preinstall/install/postinstalland the implicitnode-gyprebuild. This is the vector behind event-stream, the Lazarus campaigns, the chalk/debug compromise, the Shai-Hulud worm, and the Axios hijack.--allow-git=none) closes a case where a transitive git dep's.npmrccould override the git binary and run even under--ignore-scripts.--allow-remote=none) closes install-time resolution of arbitrary https tarballs.Every one of these is an entry point that real supply-chain attacks have used in the last two years.
On the revert requirement: it's already handled. Anyone affected can set
allow-scripts,allow-git, andallow-remotein.npmrcor~/.npmrc, or approve individual packages withnpm approve-scripts. The policy asks for a revert option, and npm 12 ships with one at the project, package, and global level.The precedent is #778. npm 9 changed unscoped _auth handling for security, landed as a node semver minor, and was backported to the existing releases rather than held for the next major. Holding npm 12 for the next major to age into LTS would put the protection everywhere except where most users actually are.
theodorejb commentedon Jun 22, 2026
As a longtime Node and npm user I really hope these fixes can make it into Node 24 (or Node 26 at the very latest). Having to wait more than a year before these regularly exploited security loopholes can be closed in an LTS release would be a terrible outcome.
wesleytodd commentedon Jun 23, 2026
While I agree on the fact these close security gaps in
npm(I have been working with the npm team for years now on these exact topics, you and I haven't met yet, but happy to have a new face to continue that tradition with), if it was a "critical" security fix it would have been done years ago. Sorry you are strapped with this history, but the fact is that it was not deemed critical in that time for reasons. We could discuss if they are good reasons or not, but I don't think that is valuable here today.I agree this is met in the letter of the policy, but I think the spirit of the policy is that releasers should judge the impact of the changes to determine a go/no-go on shipping it this way. My case here would be that it has too high of an impact if changed to be worth the improvements that come along with it:
This example explicitly fits in with that last point. FWIW, that change also broke some of our tooling and builds but it was manageable because the scope of impact was small. This change fundamentally breaks every build it touches. Hence my increased concern.
Hey @theodorejb! Thanks for helping give some voice to the user impact of the ongoing security issues surrounding of these decisions. You are absolutely right that it is bad we have been in this state for so long, and waiting longer is not at all desirable. I would strongly suggest you work on your workflows to upgrade npm independently from Node.js releases. It is a helpful feature to have in many cases, and one we use to address issues like this all the time across our fleet.
That said, I think the sentiment here is more for users who cannot or do not know how to do this. Which is likely also the group of folks who would fit into point 3 above (not yourself). For them, we need to consider what folks usually do when their build breaks, for an example I will use peer dependencies. When a build breaks because of a peer dep conflict, a large percentage of users set
--legacy-peer-depsand move on. Not aware, or ignoring, the fact that npm can resolve the peer deps if they are declared correctly.The same applies here, but the impact of that choice is a significantly worse security outcome for both them and the ecosystem. Once allow scripts is set to all for that project, the chance of it being revisited in a timely manner is quite low. From a security posture, we are only as strong as our weakest link and should act to protect that weakest link first. My suggestion to ship this with Node 27 is specifically for this subset of the ecosytem which I consider our "weakest link". And specifically I believe it is a more "terrible outcome" than informed users like all of us here upgrading our projects and setting these configurations judiciously.
wesleytodd commentedon Jun 23, 2026
On a separate note: which group is delegated this decision, is it the releasers group? This decision is an important one and I would like to help bring context/nuance to the decision. If there is an upcoming meeting I can attend I would love to. If there is no meeting time to discuss this in real time, no problem, just want to make sure that I don't miss something on this discussion due to being unable to maintain my GH notifications.
richardlau commentedon Jun 23, 2026
Content of releases is delegated to the Release Working Group.
Security evaluations are the security team (or possibly the separate Security WG as it is more an ecosystem question than core Node.js issue).
This hasn't been tagged for an agenda (yet) so is not scheduled to be discussed in a meeting at present.
JamieMagee commentedon Jun 23, 2026
Thanks @wesleytodd, and good to meet you 👋
Quick status first: I've opened the first CI-only PR against
main, nodejs/node#64096. It's marked not for merge and just runs npm 12.0.0-pre.1 through Node's CI.On "if it were critical it would have been done years ago": the risk was always real, what was missing was a fix that didn't break half the ecosystem. RFC 54 was first written in 2021, and the blocker then was native addons. Too many packages compiled through
node-gypat install time, so turning scripts off by default would have broken a large share of installs. Since then the ecosystem moved to prebuilt platform binaries shipped throughoptionalDependencies. esbuild, sharp, SWC, and Rollup all did it, and Node-API gives the ABI stability that makes prebuilds work without recompiling. The packages that still need an install script are a small and shrinking minority now. So the gap staying open in 2021 says more about what was feasible then than how serious it is, and I'd rather not treat "we lived with it for years" as a reason to keep living with it.On 24 and 26: let me adjust the framing. The security-provision bar still has to be cleared the same way for either line, I'm not backing off that. But on timing I don't think they need to move together. 26 first, after it's been through Node's CI and citgm, then 24 later as its own decision once we can see how 26 landed.
Last, on process: @richardlau Can we get it tagged for a Release WG agenda item and talk it through? I can be there if needed.
20 remaining items
MikeMcC399 commentedon Jul 29, 2026
@ljharb
Could you check
allow-scripts=true? I don't think that is correct and it doesn't follow what https://docs.npmjs.com/cli/v12/using-npm/config#allow-scripts says.ljharb commentedon Jul 29, 2026
@MikeMcC399 have you tried it? i'm pretty confident.
MikeMcC399 commentedon Jul 29, 2026
@ljharb
Yes I tried it and it didn't work for me.
Steps to reproduce
Ubuntu 26.04, Node.js 26.5.0 (bundled npm 11.17.0)
Remediate with:
Or downgrade with:
MikeMcC399 commentedon Aug 1, 2026
MikeMcC399 commentedon Aug 1, 2026
richardlau commentedon Aug 13, 2026
The Release WG has decided not to land npm 12 on Node.js 26, 24 or 22.
reggi commentedon Aug 26, 2026
I work at GitHub on
npm. I find it unfortunate that we aren't able to getnpm@12intonode v26from this decision here, if there's anyway to appeal that decision with a possibleallow-scriptsrelated config update I'm very open to discussing what it would take to get it innode v26. Apr 29, 2029 is a long time to have people continue to run onnpm@v11.theodorejb commentedon Aug 26, 2026
I also wish that npm 12 could be included in Node 26. Otherwise a lot more people will end up compromised by postinstall scripts running by default for any dependency.
manzoorwanijk commentedon Sep 22, 2026
It's such a pity that npm was forced to revert the error on unknown
.npmrcconfigs (npm/cli#9729) to allow it to be considered for Node v26, and then it ended up not being included in the version. 🤦MikeMcC399 commentedon Sep 22, 2026
This already has an impact on Renovate lock file maintenance, which uses the latest version of npm (currently 12.0.2). If this change hadn't been made, then Renovate would already be broken. This is independent of any bundling in Node.js.
MikeMcC399 commentedon Sep 22, 2026
I've requested in npm/cli#9997 for the npm team to submit npm@12 in time for Node.js 27. I don't believe there is any realistic chance of reaching a consensus to revert the decision not to backport npm@12 to Node.js 26. The release of npm@12 was too late for Node.js 26, and there are too many breaking changes in npm@12, as listed on https://github.com/npm/cli/releases/tag/v12.0.0.
Users need to make their own decision about when to upgrade, and not be forced into unexpected breaking changes. npm already allows optionally upgrading in-place - see https://docs.npmjs.com/try-the-latest-stable-version-of-npm
manzoorwanijk commentedon Sep 22, 2026
That is the whole point of breaking changes when it comes to security. The ecosystem would have adapted to the new security standard, but the main push for a revert was made in this thread, without which the WG here wouldn't entertain it for being considered for v26.
simhnna commentedon Oct 15, 2026
I'm also sad about it not making 26, but I guess I can live with that.
I can set CI to use
npm ci --strict-allow-scriptsand addstrict-allow-scripts=truein all project .npmrc files. I personally would add it to my global .npmrc so every project I checkout gets the treatment.The only difference is that it actively blocks install until every dependency is either allowed or denied. Maybe npm@11 could ship another option that behaves like npm@12 in that it doesn't block everything but just the undecided/denied packages.
MikeMcC399 commentedon Oct 15, 2026
Node.js 27 (Alpha) is planned for release on 2026-10-28, and I would expect it to include npm@12.
I already tried it out by installing a Node.js nightly build with with n Node.js version manager installed.
Nightly builds are only for advance testing, not to be relied on, and definitely not for production usage!