This is spot on. I am extremely uncomfortable with the large number of transitive dependencies that end up in pretty much any non-trivial rust application. No amount of memory safety will save us if a tiny, ubiquitous library that nobody scrutinizes because it’s nested eight layers down the dependency graph gets compromised.

I think Go apps tend to have better dependency hygiene because the language has a better standard library, which results in better culture around dependencies.

I also think it’s frustrating that both cargo and npm totally ignore the decades of prior art from Linux distributions that have figured out good ways to improve dependency management. We’d be in better shape if there was a community curated subset of known-good dependencies that are release-managed together that the broader ecosystem could build on, sort of like Ubuntu having “main” and “universe”.

I learned programming from C# which has an excellent standard library. Just recently started using Go which seems to have a good standard library. Been using python for years, can't say I ever had a complaint about the standard library.

Rust meanwhile seems to be following some "no standard library" philosophy.

I feel like there's an opportunity out there to become like an amoeba: fund and build a third party Rust standard library, absorb absolutely everyone who is so grateful to have a library, and then get so big absorb Rust itself.

I think one thing that has made Go have better dependency hygiene is not merely having "batteries included" in the standard lib, but the early focus on having production-ready implementations of a lot of stuff in the standard lib, as opposed to minimum viable implementations. I used to get a long way with one or two dependencies that would barely fan out at all. It's been a while since I worked on a Go project, so I'm not sure if it's still that way.

I think Go ends up with fewer dependencies mostly because there is more friction in finding them. With rust (and npm) you just "cargo search xxx", then "cargo add xxx". Go makes you web search and poke around github looking for something. It's not onerous or anything, but just that extra step slows things down just a bit. C projects tend to have the least because it's even more annoying to add them and you have to create build commands that deal with slightly different distributions (and learn makefile+pkg-config or cmake, or autoconf).

Certainly having a larger stdlib helps Go projects keep their deps down, but I don't think it's the real reason.

Actually I think this is more of a culture thing. Or maybe "is also" a culture thing.

One of the core tenets of early Go was the maxim "a little copying is better than a little dependency".

Probably because of this stance, they didn't even HAVE a dependency-management solution for years

I strongly agree the fewer dependencies the better, on average.

Perhaps, but I think it depends on where the Go devs are coming from. In my experience the lack of proper dependency management in older versions of Go didn't really lessen dependencies, it just made teams have to deal with annoying $GOSRC issues. But then I worked at a place where the devs used PHP (w/composer) and node before Go was introduced.

Personally I came from a C background so I tended to use deps more sparingly.

In the end it's a bit of a balancing act—lots of dependencies is a larger opportunity for these kind of supply chain attacks to affect you. Copying stuff into your repo protects you from that, but it also makes it way more likely that you'll miss security fixes, unless you're actively looking for them. Re-implementing what you need is also viable but it slows down the dev process.

I agree. Java has the same ability to quickly add deps, and in some case they can be sprawling, but it's still perfectly possible to develop complex apps without a lot of deps coming in.

Culture has a lot to do with it.

> Certainly having a larger stdlib helps Go projects keep their deps down, but I don't think it's the real reason

I disagree: having a big stdlib that encompasses a huge chunk of common functionality (logging, a plethora of network server/client protocols, etc) means that for basic needs, the question of 3rd party libs never arise, whereas for other language, the question is not if you need a dep, but which one. Making gorilla easier to find won't undo the cultural reluctance of adding a 3rd party dep when using the (very pragmatic, IMO) stdlib server is adequate to the task.

Go has an official package search at https://pkg.go.dev/

There’s no poking, unless you are into that sort of thing

Every Rust crate is heavily scrutinized these days using LLMs (which also caught this issue). The days when no one looked at dependencies are gone.

If those transitive dependencies are baked into the language runtime, how is anything materially different? You just shift the vector around.

Because the standard library of a programming language has a lot more eyes on it than one of the many small dependencies does.

You are just shifting where the eyes are, the amount of eyeballs (developer time) is the same. Unless the proposal is to increase the amount of (other) developers time.

The proposal ends up amounting to either shifting stuff around, or asking to other people to put in more effort? Into a project that usually doesn't pay (programming languages and runtimes)

Which by the way, asking other people to do stuff for free IS the attack vector, if you are the kind of dev or company that gets hit by these, your ultimate root cause is that your business strategy is using code without paying for it. No such thing as a free lunch, you will pay for it, among other things, with an increased cybersecurity risk.