'No way to prevent this,' says only package manager where this regularly happens

25 days ago (kevinpatel.xyz)

I know people have opinions about cooldowns, but they would have saved you from axios, tanstack, and many other recent npm supply chain attacks. If you have Artifactory / Nexus, you probably already have cooldowns, but it's easy to set up if you don't.

Why cooldowns? Most npm (or pypi) compromises were taken down within hours, cooldowns simply mean - ignore any package with release date younger than N days (1 day can work, 3 days is ok, 7 days is a bit of an overkill but works too)

How to set them up?

- use latest pnpm, they added 1 day cooldown by default https://pnpm.io/supply-chain-security

- or if you want a one click fix, use https://depsguard.com (cli that adds cooldowns + other recommended settings to npm, pnpm, yarn, bun, uv, dependabot and, I’m the maintainer)

- or use https://cooldowns.dev which is more focused on, well, cooldowns, with also a script to help set it up locally

All are open source / free.

If you know how to edit your ~/.npmrc etc, you don't really need any of them, but if you have a loved one who just needs a one click fix, these can likely save them from the next attack.

Caveat - if you need to patch a new critical CVE, you need to bypass the cooldown, but each of them have a way to do so. In the past few weeks, while I don't have hard numbers, it seems more risk has come from Software Supply Chain attacks (malicious versions pushed) than from new zero day CVEs (even in the age of Mythos driven vulnerability discovery)

  • The idea that 7 days is overkill is crazy to me. Unless you need a specific new feature, you should usually be fine with a dependency version that was released months ago when starting a new project. Ditto for doing regular dep upgrades.

    The only issue I see is responding to vulnerabilities, where you want to upgrade immediately. But I think in that case it's fine to require the developer to be explicit in the new version they want.

    • I agree, but in most recent cases a 1 day cooldown would have been enough.

      I added a “how to bypass if you have to patch a zero day CVE” section to depsguard for all supported package managers.

  • Doesn’t that just move the problem 7 days down the road? I always assumed these kinds of things just burn themselves because someone gets infected and realizes, not that there is an army of people auditing the changes. If everyone cooldowns for 7 days, it just happens later?

    • A large portion of the time, the maintainer notices what happened a few hours later. Maybe they were asleep or off doing other things for a while, but they eventually come back. And these kinds of takeovers frequently aren't complete enough to cover their tracks.

      So at the very least, adding a cooldown raises the difficulty of these attacks above that threshold.

      6 replies →

  • Seems like you dropped something:

    > Disclaimer: I maintain depsguard

    • Yikes. You are correct. Honest truth, I got a few downvotes (after a few more upvotes), thought this was the cause, but you’re right. Didn’t think that it matters much, I’ll add it back. Had no idea anyone noticed. Fair enough, thanks for keeping me honest.

      Edit: added it back, inline.

  • Release escrow.

    Teams should be able to say "at least N developers have to agree to a release before it happens." This should be a policy they can control and lock down with a non developer account.

    • Interesting idea, but there are so many cases of solo maintainers.

      I think that npm can have its own cooldown and automated security scan. Socket.dev, StepSecurity both close a gap here by spending tokens to scan new popular packages. Whether they do it for marketing or out of the goodness of their heart, is irrelevant. They don’t charge for this service, and it’s something I’d expect Microsoft (who owns GitHub who owns npm) to do.

      1 reply →

  • Why not to create a separate distribution or channel (bleeding edge/stable/long term), like Linux distributions do?

  • I'm not so sure cooldown would be effective. Someone still has to override the cooldown to install the (potentially) questionable releases and discover problems. If no one does, you've only delayed the problems by 3/7/10/14 days.

    After thinking more while typing this:

    I think I'd agree we should indeed have a 10-day cooldown (i.e. don't install anything released in the last ten days.) I suppose I just don't think anyone should expect it to be the only mitigation.

    • I don't think anyone is saying cooldowns are the only thing you need - just that it's a 30sec change that should harden your code.

      Also, most malicious versions seem to be detected by tools scanning new packages. People updating without cooldowns probably aren't manualy inspecting diffs. Giving tools more time to detect things seems pretty obviously good to me. Add to that maintainers reporting they've been pwned, and the floor for sneaking malicious code is much higher.

  • NPM doesn’t make it easy to do cooldowns because their apis prevent it.

    • What do you mean? it's a local config in your .npmrc (min-release-age=days or minimum-release-age=minutes for pnpm compatibility, although pnpm has 1 day by default if you have the latest...)

      1 reply →

  • > Why cooldowns? Most npm (or pypi) compromises were taken down within hours,

    But won't more people on cooldown mean less likelihood to catch the bug, thus extending the need for cooldowns?

  • Honestly I'd prefer a system wide cooldown / age setting across all package managers and installers, with the option to poke holes / allow and also the option to deny / allow post installation runners. Something like a global asdf style installer that tracks and enforces these rules across all of it's managed package managers.

    Something like a proxy that intercepts and depending on the source, is intelligent enough to examine the package for age. That would be cool. Already sounds like a cloud product you could sell.

  • This is like buying something from the grocery store and then waiting a week to eat it in case the FDA put out a warning about it.

    • More akin to letting astronauts stay in quarantine for a day in case they caught space bugs.

      If every other week I would notice the FDA recalls a popular brand that would have taken over my brain and transmit my bank password and SSN to a stranger, I might prefer drinking week old milk.

      Edit: not dismissing your analogy, it’s pretty much it.

      3 replies →

    • If there was a good reason to believe the pop tarts you buy might unexpectedly be contaminated with dioxins, waiting a week would be prudent.

What are the actual guarantees that go/Rust make that Python/npm don’t? It seems like it might just be that Python/npm are juicier targets? I’m starting to try and avoid all third party packages

  • It is 100% up to the package manager's steward to control how ownership of packages and namespaces are granted.

    Maven Central exists for decades the amount of incidents of people stealing namespaces is minimal.

    One can't simply publish a package under the groupId "com.ycombinator" without having some way to verify that they own the domain ycombinator.com. Then, once a package is published, it is 100% immutable, even if it has malicious code in it. Certainly, that library is flagged everywhere as vulnerable.

    It baffles me that NPM for so long couldn't replicate the same guardrails as Maven Central.

    • Also....

      Maven doesn't have "preinstall, install, post install", or " build.rs" for rust, executing arbitrary code during the installation.

      The code that's executing with Maven is in your pom.xml, not some hidden code from a transient dependency.

      That alone is a major design flaw in both npm and cargo.

      Java is boring, because it works. People don't like boring stuff. It's more exciting to play the Russian roulette on each install!

      5 replies →

  • Part of the point the article makes is that most other popular languages have a comprehensive standard library. JS has an astonishingly small on. Rather than have one vetted set of libraries that ship with the language, applications either need to roll it themselves or pull from a 3rd party package repository. We've drilled NIH into people, so they tend to reach for packages. That's not necessarily a bad thing, but it often means they're pulling in more code than they need. The JS ecosystem has also favored smaller modules, so you need many of them. And everyone builds on top of that, leading to massive growth in dependency graphs. It's a huge surface area for things to go wrong, intentionally or not.

    With many other languages, you have a lot of functionality out of the box. Certainly, there have been bugs and security issues, but they're a drop in the bucket compared to what you see in the JS ecosystem. With other languages, you have a much smaller external dependency graph and the core functionality is coming from a trusted 3rd party.

    • What important functionality do you feel is missing from the commonly used JS environments (node and browser) that is causing people to install it as a third party dependency?

      The issue isn’t that the functionality doesn’t exist, it’s always backwards compatibility with versions where it did not yet exist.

      2 replies →

    • > Part of the point the article makes is that most other popular languages have a comprehensive standard library.

      Both the Browser and Node.js standard library are fairly extensive. I don't think there's much you can do with other language you can't do with Node.js. And as a lot of newer languages have demonstrated (like zig and hare), you don't need an extensive one.

      2 replies →

  • > It seems like it might just be that Python/npm are juicier targets?

    Attackers go where the victims are. Frontend is a monoculture with the vast majority using NPM; backend, less so. This isn't an excuse for NPM, but another strike against it.

    You could also argue that the attacks make a deeper point about frontend vs backend devs, but I won't go there.

  • To be honest Rust has the exact same supply chain attack pattern - it's just newer and more maintained at the moment. Give it a decade.

  • I suppose that go's go:generate workflow can also be abused to land a worm like the ones spreading via npm, as you can build programs that just scrape the whole hard drive for git projects and patch the go.mod dependencies there, and you could also just write this in go as a toolchain script, for example.

    NPM's achilles is the pre/postinstall step which can run arbitrary commands and shell scripts without the user having any way to intervene.

    Dependencies must be run in isolated chroot sandboxes or better, inside containers. That would be the only way to mitigate this problem, as the filesystem of the operating system must be separated from the filesystem of the development workflow.

    On top of that most host based firewalls are per-binary instead of per-cmdline. That leads to the warnings and rules relying on that e.g. "python" or "nodejs" getting network access allowlisted, instead of say "nodejs myworm.js". So firewalls in general are pretty useless against this type of malware.

  • Last I checked npm had 2FA for publishing, but cargo didn't. I don't think cargo is any better than npm, just not that of an attractive target.

  • "What are the actual guarantees that <guy leaving his keys on his dashboard> make that <guy leaving his keys on an illuminated blinking sign outside his house> don't make?"

  • Generally, other package managers aren't great either. Notably, crates.io / cargo has some of the same issues as NPM and the verbiage of their excuses for not fixing these problems is oddly similar.

    Something fascinating about the design and architecture of programming languages and their surrounding ecosystems is the enormous leverage that they provide to the "core team":

    For every 1 core language developer[1]...

    ... there may be 1,000 popular package developers...

    ... for which there may be 1,000,000 developers writing software...

    ... for over 1,000,000,000 users.

    This means that for every corner that is cut at the top of that pyramid, the harms are massively magnified at the lower tiers. A security vulnerability in a "top one thousand" package like log4j can cause billions of dollars in economic damage, man-centuries of remediation effort, etc.

    However, bizarrely, the funding at the top two levels is essentially a pittance! Most such projects are charities, begging for spare change with hat in hand on a street corner. Some of the most used libraries are often volunteer efforts, despite powering global e-commerce! cough-OpenSSL-cough.

    The result is that the people most empowered to fix the issues are the least funded to do so.

    This is why NPM, Crates.io, etc... flatly refuse to do even the most basic security checks like adding namespaces and verifying the identity of major publishers like Google, Microsoft, and the like.

    That's a non-zero amount of effort, and no matter how trivial to implement technically or how cheap to police, it would likely blow their tiny budget of unreliable donations.

    The exceptions to this rule are package managers with robust financial backing, such as NuGet, which gets reliable funding from Microsoft and supports their internal (for-profit!) workflows almost as much as it does external "free" users.

    "Free and open" is wonderful and all, but you get what you pay for.

    [1] Most of us can name them off the top of our heads: Guido van Rossum, Larry Wall, Kerningham & Richie, etc.

    • You appear to have missed that NPM is owned by Microsoft.

      In addition, crates.io has not flatly refused to support namespaces, there's an entire accepted RFC for it: https://github.com/rust-lang/rfcs/pull/3243

      At the same time, note that namespacing does nothing to prevent any sort of problem here. Namespacing is great for package organization and making provenance more deliberately obvious, but beyond that it's not a security measure.

      1 reply →

There has been a lot of pain at my various jobs installing a safe global npm config on every developer machine, asking people not to disable it, checking it with mdm tools. A safer out-of-the-box configuration is long overdue.

  • Just dont use npm. Use a package manager which doesn't execute postinstall by default. The switch is incredibly simple.

  • What do you mean by safe config? If you're trying to mandate a cooldown period or a whitelist/blacklist of packages, the correct approach is to configure a company-controlled registry that pulls from the upstream npm registry while enforcing your desired policies.

    • Whether the config is the registry URL or the cooldown timer you still need it on your dev machines and people to use tools that use it (the latter is especially a problem with docker in my experience, people find out testcontainers or whatever is pulling from docker hub rather than the company registry only when their CI build fails from rate limits)

      1 reply →

With the recent high-profile attacks on PyPI packages, it’s no longer true that npm is the “only package manager where this regularly happens”.

In fact, pip is much more dangerous than npm because it lacks a lockfile. uv fixes that, but adoption is proceeding at a snail’s pace.

I think people are overlooking the fact that the javascript ecosystem is run by perpetual beginners who are probably using 5 different SAAS credential managers and still manage to check their creds into a public git repo. No wonder there are so many breaches. Rust developers otoh are typically experts and don't get pwned so easily.

There is no legitimate reason why postinstall scripts need to exist. The npm team needs to grow up and declare "starting with npm version whatever, npm will only run postinstall scripts for versions of packages published before ${today}".

  • I audited several postinstall scripts recently in popular packages. They seem to be mostly around using native binaries, downloading them, detecting if the platform is compatible, linking to it directly instead of having it bootstrapped by node, working around issues in older versions of npm, etc. Since dev toolchains (e.g. esbuild) are now being built in compiled languages and distributed as binaries via npm registry. If you are on a recent version of node/npm and a common/recent OS/platform, you should be able to disable all the postinstall scripts without legitimate issue.

  • With respect, post-install scripts are a total red herring. You're alarmed by them because they are code controlled by someone else that runs on your box, and they could do something bad -- yes, they are, and yes they could.

    But so is the regular code in those packages! It won't run at install time, but something in there will run -- otherwise it wouldn't have been included in the dependencies.

    Thinking that eliminating post-install scripts will have more than a momentary impact on exploitation rates is a sign of not thinking the issue through. Unfortunately the issue is much more nuanced than TFA implies -- it's not at all a case of "Let's just stop putting the wings-fall-off button next to the light switch", it's that the thing we want to prevent (other people's bad code running on our box) cannot be distinguished from the thing we want (other people's good code running on our box) without a whole lot of painstaking manual effort, and avoiding painstaking manual effort is the only reason we even consider running other people's code in the first place.

    • The time difference does matter though. There were some recent worm attacks in NPM that spread very quickly because they used post-install. I don’t remember how long it took NPM to block the packages but it was probably around 30 minutes or so? If it wasn’t for post-install then that same attack would have a much slower spread and thus a smaller blast radius.

      1 reply →

    • > There's a huge difference, because postinstall scripts are almost guaranteed to run in your CI pipeline. Compromised code probably won't (maybe it will if your test cases test a compromised package). Different attack profile. Worse in some ways (your CI likely has NPM push tokens, which is how this single-package worm become a multi-package self-replicating worm) (your CI pipeline also likely has some level of privileged access to your cloud environment; deployed services are more likely to be highly scoped). But, better in some ways.

  • install scripts are a distraction, just like package signatures are a distraction. adding/removing either feature has no significant impact on the wormability of this package ecosystem. installed npm code is run, with nearly zero exceptions.

    • The installed code may be run in different settings, under a different user, with different privileges. Say, it may not run in CI/CD at all, or run only with the test user's privileges.

      Postinstall scripts run at install time, with installer's privileges.

    • A lot of it ends up bundled to run in a browser though, and doesn't end up running in Node.js

    • > There's a huge difference, because postinstall scripts are almost guaranteed to run in your CI pipeline. Compromised code probably won't (maybe it will if your test cases test a compromised package). Different attack profile. Worse in some ways (your CI likely has NPM push tokens, which is how this single-package worm become a multi-package self-replicating worm) (your CI pipeline also likely has some level of privileged access to your cloud environment; deployed services are more likely to be highly scoped). But, better in some ways.

      1 reply →

  • This doesn't really fix the issue though because package code is also executed at build time and during testing. Just maybe restricts the scope a little bit.

    • There's a huge difference, because postinstall scripts are almost guaranteed to run in your CI pipeline. Compromised code probably won't (maybe it will if your test cases test a compromised package). Different attack profile. Worse in some ways (your CI likely has NPM push tokens, which is how this single-package worm become a multi-package self-replicating worm) (your CI pipeline also likely has some level of privileged access to your cloud environment; deployed services are more likely to be highly scoped). But, better in some ways.

      Its childish to believe that because you can't fix everything you shouldn't fix anything. Defense in depth.

      1 reply →

  • Security issues aside, they are a nightmare in enterprise environments where internet and OS access is heavily restricted.

  • ...and only if you invoke it with --dangerously-run-postinstall-scripts; otherwise it will report an error if a postinstall script is found.

    This is definitely going to affect any packages that need to link to native code and/or compile shims, but these are very few.

This link is clearly an AI laundered version of the long running joke from Xe Iaso. Shame.

https://news.ycombinator.com/item?id=40438408

Every node js project starts with npm install and suddenly you have a 500 packages you didnt ask for. Half of them haven't been touched in years.

It's a cultural issue, always feeling the urge to update to the newest possible package for things that are already working fine, without even reading the changelog to see if it's applicable. Cooldowns are only a way to force a bit of patience onto the maintainers... and they work.

  • That, and package owners updating stuff that needs no updating just to look not stale/unupdated. I can use lisp packages without changes for 15 years fine, but a js one is unmaintained! oh no! Even though it was done 15 years ago, so they add nothing, sometimes a breaking change, to up a version on npm and github and look maintained. And then everything will update.

  • If you have some sort of compliance requirements, you need to update because of the onslaught of CVE vulnerabilities in the older versions. They are mostly bogus like "regexp DOS" but you have to satisfy the process and update anyway.

A 7-day cooldown feels like a low-effort band-aid. The real fix is probably reproducible builds + signed attestations, but most teams won't pay that tax until they've already been burned.

There is a good old time, before rust and go mindset ruined everything pushing people to wget|bash --install random crap on the spot, when experienced people used to rely on linux OS distributions like debian and co to source package and libraries and ensure to have "stable" and "safe" software procurement for professional and serious infrastructure and deployment.

But young blood mocked the fact to have to wait for Manual human review, safe gpg signatures, cool down periods and weeks of "testing" stage before being considered "stable".

And now most companies data are leaked and on the wide, hackers and ransomware are thriving...

This is crazy when you think about it because after so many years of software dev crafting experience, "modern safe" languages like go and rust, ..., typing, ... You would expect most software stack to be pretty solid and safe compare to 15 years ago.

I use C++ and Conan with my own recipes and pre-built artifacts.

This mitigates things to a great extent.

I do not know who thought that having your dependencies depend on the internet with a zillion users doing stuff to each package was a good idea for enterprise environments...

It is crazy how much things can get endangered this way.

This reads like an onion article

> residents of the Node.js ecosystem stood unified in their belief that the malicious remote-code execution was a completely unpredictable tragedy

Does anyone believe that claim? There's been so many counterexamples.

It's a great dig on the ecosystem's failings but only entertainment. Perhaps a prompt for marketers to present their wares? Kinda like the maintainer of depsguard who removed, re-added, and then re-removed that admission from their post? At the time of this writing they have the top post.

  • I’m sure you mean well but I re-added it and kept it :) (It was re-added inline, right after the link. It says “I’m the maintainer”. I never re-removed it).

    I shouldn’t have removed it in the first place, and I re-added it right when someone called me out on it, and explained why I did it (https://news.ycombinator.com/item?id=48156765). But again, it’s not like it’s hidden, it’s right in my bio. But let’s say I didn’t add a disclaimer in the first place, and didn’t even disclose it in my bio, would it matter much?

    If the maintainer of pnpm would link to the first link I shared, would i care if they disclose it or not? If it works, it works. It’s a free tool. I know depsguard is not pnpm, and I do think disclosing “plugs” is the ethical thing to do, and that’s why I re-added it, but I don’t understand the obsession with disclosures on free and open source tools that are helping people. You get hated if you disclose it (people hate plugs…) and hated if you don’t.

    Again I understand the criticism, but I’m not a marketer, I’m someone who is tired of everyone posting on these attacks on LinkedIn for marketing (yes including me), and decided to do something about it (I put my company logo as I used my company laptop and resources) If the tool works, is free, and asks for nothing in return, is clear in my bio that I’m the maintainer, has now a clear disclaimer (inline) is it really that bad of a crime to build something useful for free and link to it in 2026?

    • Hrm, I'm very sorry. There it is, a little buried but I missed it, and it sucks that I falsely impugned your honor. The entirety of my criticism was based on my failure and I made it while you are helping fix things.

      FWIW, if anything, my invalid criticism was only a footnote to my comment. I was irritated by the article. It felt like a low blow on a dynamic that is a terrible, if minor, example of how small but impactful set of people are shitty to others in the world. Their accumulated behaviors mean we don't have nice things and we get stuck on defense rather than dreaming and creativity. It went further and made universal false claims about the users of npm and what we say and believe. Impugning you was just a mistaken tack on. Again, I apologize. The article hit some sore spots and it sucks that I added to the pile of crappiness in the world. I try hard not to and to improve things instead.

      No, it's certainly not a crime to promote your project. Especially if it's free and open source and you won't be attempting to bleed your adopters in the future. Promoting your tool is marketing IMO, even if not financially motivated, and regardless of your job title. I'm going to just avoid the scree I'm thinking about with regards to open source and it's role in the industry that I am more and more distant from anymore.

      Would it matter if you hadn't disclosed? I think it's complicated. I'm definitely from the camp that thinks one should. Being an expert on the thing, likely having better insight in the space, and the bias inherent therein are important signals. I always disclosed on comments about my own projects though I don't list them in my bio. They're mostly outdated these days. Of course you get your own opinion and should act accordingly.

      1 reply →

I’m using nix for managing npm dependencies in a project and it seems like I accidentally got some protection from these attacks because of the nix sandbox. Looks like I got more than I begged for.

I really don't understand why the npm project cannot embrace PGP as an ambulatory 'good enough' solution.

  • The NIH mentality in the ecosystem would result in a JavaScript pgp library which itself would be an npm package and subject to supply chain attacks. lol.

    • A good part of it is already implemented in web crypto, which is supported by browsers and node. There is a chance that npm could implement something there without extra dependencies. Maybe I'm too optimistic?

  • Would that help? Most of these recent attacks, the attackers have gained access to the system that builds the packages. So it would have just signed the malicious build the same.

    • nope, doesn't help. signatures and removal of script points have zero net effect on the value of the target that the ecosystem has, or how easy/hard it is to write a worm. the package code gets run, this is statistically true, and the exploited developers/environments will sign packages, this is also statistically true.

    • In some ways the push towards trusted publishing has made these attacks more likely as the credentials are sitting in a standardized, always on CI system, rather than in a locked down corporate CI system for big packages or a developers machine or developers head for smaller open source packages.

  • Probably the same reason that pretty much no other package manager (or even major email provider, when email is ostensibly the most famous use-case for it) has adopted it: the UX is atrocious.

The answer is LLM inspection. Which, sadly, raises the cost of software, especially once evil LLMs start hiding the backdoors better. Long term the answer should be CHERI, in my opinion.

Lately the security vulnerabilities around Node.js have been pretty rough, and at work I've been scrambling to deal with them.

Ah yes, only `npm` has ever suffered an attack. Ever.

RubyGems: https://www.sonatype.com/blog/anatomy-of-the-rubygems-rest-c... PyPi: literally the latest attack included publishing malicious packages on PyPi XZ Tools, a part of nearly every Linux distribution nearly merged in code to backdoor SSH: https://www.akamai.com/blog/security-research/critical-linux...

It is just easy pickings to blame npm specifically. Yes, while they do share some part of the blame, no package manager is immune from attack and certainly not ones where the attackers exploited being able to extract out secrets from a developer's environment variables or files. Seems more like developers should be managing their secrets better?

I also find that using the meme that this title snowclones is in bad taste too.

  • XZ attacker spent half a year earning trust, doing real maintenance.

    Different order of magnitude effort spent during XZ attack.

  • Security doesn't exist in absolute. It's about relative effort. Exploiting Debian's package management requires quite a bit of effort, NPM, while being funded by Microsoft, only need to have a token stolen. And postinstall scripts were decried as a security risk for a long time

No surprise here. That's what you get when you have a language/ecosystem where core devs refuse to fix fundamental flaws, cuz for them breaking backwards compatibility is the worse crime that can ever be committed. And so all that happens in JS-land will eternally be layering lipstick on the pig in the cesspool. Too afraid of going through something similar to the Python 2 -> 3 fiasco, I guess because too many web devs and site admins would be incensed at being forced to fix their broken universe; as if it isn't already broken in its current condition.

[flagged]

  • I read it as a comparison of the attitude of helplessness around it, not the acts themselves. So it was a bit meta, but unremarkably inoffensive.

  • I don't think it's comparing them directly or arguing for equivalent seriousness. It is identifying a similarity of mindset where those who have their hands on the levers of power that could materially improve the situation act like there's nothing they can do.

  • But it's not comparing to school shootings, it's satirizing supposedly responsible parties who continue to deny responsibility despite repeated catastrophic failures which are their responsibility.

  • You’re right. Major supply chain attacks affect far more people than school shootings do, and can potentially cost more lives through downstream effects.

    It’s 2026. Software is critical infrastructure for global civilization now. Lives and livelihoods depend on it working reliably. The “it’s just bits on a computer” quip has been outdated for 20 years now.

Do not fucking use npm. Stay the fuck away from it. Want to write JS? AI can now write vanilla JS for you with no libraries. Own your code.

Vendorizing using git submodule should be a robust mitigation for this problem.

  • Wouldn't locking dependencies be far more likely for dependency-users to do, and be approximately as effective for those that do?

  • subtree is better for this case, you want to encourage actual reading before running. reading won't catch everything but it catches a lot, and the burden isn't as high as people always complain about before they try it.

  • This feels like the modern analog of the king, the mice, and the cheese. What cats do I need to bring in to eat my git submodules?