Upcoming breaking changes for NPM v12

Posted by plasma 3 hours ago

Counter148Comment45OpenOriginal

Comments

Comment by tuckwat 48 seconds ago

I bet there have been a hundred different discussions about this inside of NPM since it was disclosed 10 years ago. With Shai Halud it's gotten too big to ignore.

Comment by Tiberium 2 hours ago

I hope GitHub changes their vibecoded badges, what does RETIRED even signify in this context? Why does the preview have to be in ominous red?

Comment by mort96 2 hours ago

Hahaha that's amazing, just a big red "RETIRED" badge above their blog post? What the hell

Comment by petetnt 1 hour ago

Breaking changes have had that tag for ages

Comment by mort96 1 hour ago

Really? Retired? What does that even mean in this context, why not "breaking" or something else that suggests breaking change?

Comment by inopinatus 11 minutes ago

Retired in the Blade Runner sense.

Comment by behindsight 22 minutes ago

> Retired? What does that even mean in this context

"retired" is probably a followup to functionality that was "deprecated".

I agree "breaking" would be clearer

Comment by sheept 1 hour ago

The changelog design has been like that since last year,[0] which predates today's slop design of small caps and monospace text (probably because they both are based on the same design trend). A year ago, vibe coded websites leaned more on sans serif and gradient text.

[0]: https://github.blog/changelog/2025-05-05-improvements-to-cha...

Comment by thatmf 37 minutes ago

> allowScripts defaults to off

Nice that they're following pnpm's lead on this after [checks watch]... 18 months?

Comment by efortis 2 hours ago

this release fixes a vulnerability reported 10 years ago

https://www.kb.cert.org/vuls/id/319816

Comment by karakanb 1 hour ago

It is not obvious from the post but it seems like the allow list for the scripts supports whitelisting packages instead of a global setting. This should make it easier to maintain org-wise rules to allow scripts only for specific packages.

Is there a linter that could be used for scenarios like this to prevent unsafe default on package manager config?

Comment by aniceperson 2 hours ago

didn't know npm was owned by github.. well, that explains things...

Comment by ralph84 25 minutes ago

NPM (the company) was about to go under in 2020. They raised VC but never found a sustainable business model. GitHub acquired them to keep the ecosystem alive. The acquisition hasn't really benefitted GitHub much at all.

Comment by materielle 3 minutes ago

I don’t know if this is the case here, but it’s very hard in general to judge how much software projects ought to cost.

Software projects will grow in complexity to consume whatever budget you give it. If you hire 50 devs and give them a bunch of business objectives, they are going to do what they do and write a ton of software.

It’s not obvious to me that it would be theoretically impossible to build a cheaper package manager.

Comment by shagie 1 hour ago

NPM Is Joining GitHub - https://news.ycombinator.com/item?id=22594549 (March 16, 2020; 571 comments; 1829 points) - https://github.blog/news-insights/company-news/npm-is-joinin...

Some of it aged... interesting.

Top comment:

> Microsoft doesn’t do everything right but the GitHub acquisition has honestly gone better than I ever expected. Rather than forcing GitHub to adopt Microsoft centric policies, Microsoft has adopted more GitHub stuff, especially from a product POV. GitHub still runs as a separate company (different logins and health care and hiring systems) with its own policies and point of view.

> ...

Comment by w29UiIm2Xz 1 hour ago

To be fair, the vibes (at the time) were that Microsoft has changed. Probably, in some way, a zero-interest rate phenomena.

Comment by shimman 53 minutes ago

MSFT acquisition of NPM was a massive shit show, they fired many staff engineers and people that were at github for quite a while. Top comment was a liar.

Comment by joeyhage 2 hours ago

Most people know this but the _real_ reason it explains things is that GitHub is owned by Microsoft. Oh, and Microsoft moved GitHub to Azure

Comment by BowBun 2 hours ago

yes, since 2020

Comment by heldrida 1 hour ago

> The resulting allowlist is written to package.json

Couldn’t this effectively result in the same process we get in pre-12 defaults?

Comment by ComputerGuru 1 hour ago

My big question as an OSS dev distributing some precompiled binaries via npm for easy installation: does allowScripts also default to disabled when directly installing a package (globally or otherwise)?

Comment by Zopieux 1 hour ago

Eh, that only took a few dozen actively exploited supply-chain vulns in the span of two years!

Comment by dawnerd 1 hour ago

Only took Microsoft themselves getting hit with it for things to change.

Comment by cute_boi 2 hours ago

They should have added a 1-day age limit by default, so security scanners have some time.

Comment by geophph 48 minutes ago

The maintainer of pnpm mentioned this on the pod rocket podcast recently. Based on recent npm exploits they decided to (and based on a poll they did most users agreed) set to 1 day by default in v11. Can always choose to change it if you desire.

Comment by KolmogorovComp 1 hour ago

I don't think it'd necessarily be a good decision, sometimes CVE are actively exploited and need quick patching.

A better safety net would be to require active 2FA proof for every package update.

Comment by therealmarv 3 minutes ago

As if supply chain attacks could have been prevented by 2fa or passkeys always.

You want delays by x days because supply chain attacks get caught very often within 1-2 days. And if you really really want to make an exception for a zero day then that's no problem and you can still quick patch by exclusion of that rule. They don't contradict in a unsolvable problem. You want both, you get both.

Comment by jnwatson 1 hour ago

If you need a quick patch, you pass another parameter to turn off the 1 day. 1 day delay will prevent more problems than it makes.

Comment by alexdns 53 minutes ago

so this parameter can be passed by the attackers also thus making your point pointless

Comment by therealmarv 1 minute ago

that parameter cannot be set by a package, you only can set it

Comment by gbear605 36 minutes ago

The idea of the parameter is stopping the attackers from getting on your system in the first place

Comment by TZubiri 2 hours ago

Looks good? But doesn't this just change the compromise window from first installation to first run?

Comment by semiquaver 1 hour ago

Ok? Not sure what a package manager can do about the fact that eventually you want to run the things you install.

Comment by grassfedgeek 1 hour ago

"First run" doesn't exist for JavaScript libs used only in web apps. So for that entire class of packages this change makes them safe.

Comment by tabwidth 39 minutes ago

Build tooling still runs though. Your bundler plugin or PostCSS transform gets full fs access at build time, nobody's auditing that.

Comment by TZubiri 1 minute ago

Build deps are even disregarded as less critical than runtime deps traditionally. So deps like sphynx for building docs are still a dev side supply chain vector.

https://github.com/kennethreitz/pytheory/issues/47

Comment by TZubiri 4 minutes ago

But this is npm, the execution environment is not the browser, but the server.

Most packages are imported via import/require, even if it's a browser only package. Because of SSR and reasons.

Or maybe not, let's look at a random browser only example, angular and react will use SSR, so they will execute in the server, let's check Jquery:

https://www.npmjs.com/package/jquery

Docs suggest just using a script tag instead of npm, when using npm install, they suggest to run import statement, which can execute arbitrary code.

The bottom line seems to be that if you are using npm, it's cause you are using node, and therefore you will run the imported code in the server, otherwise you would use a script tag.

But maybe there's a way to define a browser only package or .js URL such that it is only downloaded and served but never executed server side?

In any case, not a huge usecase of npm, which again, is designed for node which is backend.

Randome example,

include

Comment by WatchDog 38 minutes ago

"First run" certainly exists in web apps, it's just running JS in a browser rather than a shell script on a developer or CI machine.

There is plenty of malicious stuff you can do from the browser.

Comment by christophilus 2 hours ago

Better than nothing. That’s the same problem every package manager has.

Comment by insanitybit 1 hour ago

Yes, but that's actually a huge win. I can't know what a package needs to do at install time - the dev knows that. But I know what my tests and program need to do at runtime because it's my job to understand those things.

The dev has to be responsible for ensuring that their build scripts are safe, I need to be responsible for ensuring that my runtime is safe.

It'd be great to have more tools for untrusting libraries (iframes are awesome for this on the frontend) but this is still a massive win.

Comment by Someone1234 1 hour ago

I’m sure we’d all welcome your alternative and or superior proposals.

Without that, this just comes across like unconstructive commentary.

This moves the needle a little your proposals or the lack thereof don’t move it at all. So I’ll take this over nothing.

Comment by spartanatreyu 37 minutes ago

We already have alternative and superior proposals, it's called Deno.

It's node + npm compatible and its permission system locks everything down by default.

If you know ahead of time, you can turn on which permissions something is supposed to have in the config file.

Or you can just not use a config file at all. Anytime it needs a permission: it asks you what it wants. You can say yes or no, and those are saved in the config file for next time. If you say no, the script throws an error where it tried to access something it didn't have permission for.

---

Example:

- My linter wants access to my file system?

  - You can have read access to ./src/ts/
- My bundler wants read and write access to my file system?

  - You can have read access to ./src/ts and write access to ./build-output

  - Huh, what's that? The bundler was trying to both read and write a file in ./src/ts?

  - We don't want input files getting overwritten, that's a recipe for hard-to-diagnose race conditions. Looks like the permission system did more than just keep things secure, it's like a type system for IO.

  - Oh, look at that, there was a very subtle bundler misconfig, let me fix that now. How long would that have existed if we didn't use deno...
- Oh what's this? An updated dependency I've been using for 6 months suddenly asking for access to my .env file, and asking to run curl in a separate process? How about "no". Why would a simple DOM utility dependency be asking for those permissions? Ah, looks like it was part of a credential stealing supply chain attack. Glad I wasn't using node.

---

Addendum: Node now has a permission system, but it's broken by design so it's useless.

Comment by mschuster91 1 hour ago

An idea might be to not just pin "package xyz allowed", but "package xyz postinstall allowed with hash <1234>".

Comment by jffry 36 minutes ago

The default behavior for the automated "add everything existing to the allowlist" is to include the specific version: https://docs.npmjs.com/cli/v11/using-npm/config#allow-script...

Together with a lockfile that does achieve "package xyz postinstall allowed with hash <1234>"

Comment by themafia 45 minutes ago

The "aw geez, enough is enough" release.

Finally.