Rust’s dependencies are starting to worry me

vincents.dev

418 points by chaosprint 5 days ago


kion - 5 days ago

IMO any system where taking a dependency is "easy" and there is no penalty for size or cost is going to eventually lead to a dependency problem. That's essentially where we are today both in language repositories for OSS languages and private monorepos.

This is partly due to how we've distributed software over the last 40 years. In the 80s the idea of a library of functionality was something you paid for, and painstakingly included parts of into your size constrained environment (fit it on a floppy). You probably picked apart that library and pulled the bits you needed, integrating them into your builds to be as small as possible.

Today we pile libraries on top of libraries on top of libraries. Its super easy to say `import foolib`, then call `foolib.do_thing()` and just start running. Who knows or cares what all 'foolib' contains.

At each level a caller might need 5% of the functionality of any given dependency. The deeper the dependency tree gets the more waste piles on. Eventually you end up in a world where your simple binary is 500 MiB of code you never actually call, but all you did was take that one dependency to format a number.

In some cases the languages make this worse. Go and Rust, for example, encourage everything for a single package/mod to go in the same file. Adding optional functionality can get ugly when it would require creating new modules, but if you only want to use a tiny part of the module, what do you do?

The only real solution I can think of to deal with this long term is ultra-fine-grained symbols and dependencies. Every function, type, and other top-level language construct needs to declare the set of things it needs to run (other functions, symbols, types, etc). When you depend on that one symbol it can construct, on demand, the exact graph of symbols it needs and dump the rest for any given library. You end up with the minimal set of code for the functionality you need.

Its a terrible idea and I'd hate it, but how else do you address the current setup of effectively building the whole universe of code branching from your dependencies and then dragging it around like a boat anchor of dead code.

socalgal2 - 4 days ago

I'm curious if rust has this problem. The problem I notice in npm land is many developers have no taste. Example, there's a library for globbing call glob. You'd think it would just be a function that does globbing but no, the author decided it should ALSO be a standalone commandline executable and so includes a large commandline option parser. They could have easily made a separate commandline tool that include a library that does the glob but no, this is a common and shit pattern in npm. I'd say easily 25% or more of all "your dependencies are out of date" messages are related to the argument parcing for the commandline tool in these libraries. That's just one example.

Also there's arguably design. Should a 'glob' library actually read the file system and give you filenames or should it just tell you if a string matches a glob and leave the reset to you? I think it's better design to do the later, the simplest thing. This means less dependencies and more flexibility. I don't have to hack it or add option to use my own file system (like for testing). I can use it with a change monitoring system, etc...

And, I'm sure there are tons of devs that like the glob is a "Do everything for me" library instead of a "do one specific thing" library which makes it worse because you get more "internet points" the more your library doesn't require the person using it to be a good dev.

I can't imagine it's any different in rust land, except maybe for the executable thing. There's just too many devs and all of them, including myself, don't always make the best choices.

jerf - 5 days ago

A true enough statement, but "Rust" is unnecessarily specific. Dependencies are getting scary in general. Supply chain attacks are no longer hypothetical, they're here and have been for a while.

If I were designing a new language I think I'd be very interested in putting some sort of capability system in so I can confine entire library trees safely, and libraries can volunteer somehow what capabilities they need/offer. I think it would need to be a new language if for no other reason than ecosystems will need to be written with the concept in them from the beginning.

For instance, consider an "image loading library". In most modern languages such libraries almost invariably support loading images from a file, directly, for convenience if nothing else. In a language that supported this concept of capabilities it would be necessary to support loading them from a stream, so either the image library would need you to supply it a stream unconditionally, or if the capability support is more rich, you could say "I don't want you to be able to load files" in your manifest or something and the compiler would block the "LoadFromFile(filename)" function at compile time. Multiply that out over an entire ecosystem and I think this would be hard to retrofit. It's hugely backwards incompatible if it is done correctly, it would be a de facto fork of the entire ecosystem.

I honestly don't see any other solution to this in the long term, except to create a world where the vast majority of libraries become untargetable in supply chain attacks because they can't open sockets or read files and are thus useless to attackers, and we can reduce our attack surface to just the libraries that truly need the deep access. And I think if a language came out with this design, you'd be surprised at how few things need the dangerous permissions.

Even a culture of minimizing dependencies is just delaying the inevitable. We've been seeing Go packages getting supply-chain-attacked and it getting into people's real code bases, and that community is about as hostile to large dependency trees as any can be and still function. It's not good enough.

zaptheimpaler - 5 days ago

This is just a modern problem in all software development, regardless of language. We are doing more complex things, we have a much bigger library of existing code to draw from and there are many reasons to use it. Ultimately a dependency is untrusted code, and there's a long road to go in hardening entire systems to make running arbitrary dependencies safe (if its even possible).

In the absence of a technical solution, all others basically involve someone else having to audit and constantly maintain all that code and social/legal systems of trust. If it was pulled into Rust stdlib, that team would be stuck handling it, and making changes to any of that code becomes more difficult.

palata - 5 days ago

Similar feeling here.

Cargo makes it so simple to add tons of dependencies that it is really hard not to do it. But that does not stop here: even if I try to be careful with adding dependencies, a couple dependencies are likely to pull tens of transitive dependencies each.

"Then don't depend on them", you say. Sure, but that means I won't write my project, because I won't write those things from scratch. I could probably audit the dependency (if it wasn't pulling 50 packages itself), but I can't reasonably write it myself.

It is different with C++: I can often find dependencies that don't pull tens of transitive dependencies in C++. Maybe because it's harder to add dependencies, maybe because the ecosystem is more mature, I don't know.

But it feels like the philosophy in Rust is to pull many small packages, so it doesn't seem like it will change. And that's a pity, because I like Rust-the-language better than C++-the-language. It just feels like I trade "it's not memory-safe" for "you have to pull tons of random code from the Internet".

Orangeair - 5 days ago

I think that https://blessed.rs does a pretty good job of providing recommendations for things that probably can't be crammed into the standard library, but which you'll almost certainly end up needing at one point or another. I honestly like that system a lot, it makes it so that the only packages you need to worry much about are usually doing something rather specific.

nemothekid - 5 days ago

I feel like leftpad has given package managers a very bad name. I understand the OP's hesitation, but it feels a little ridiculous to me.

tokio is a work-stealing, asynchronous runtime. This is a feature that would be an entire language. Does OP consider it reasonable to audit the entire Go language? or the V8 engine for Node? v8 is ~10x more lines than tokio.

If Cloudflare uses Node, would you expect Cloudflare to audit v8 quarterly?

neilv - 5 days ago

In the past (not in Rust, but other languages), for important systems, I've instituted policies of minimizing dependencies from these language-specific package repositories, and for the ones you do use, having to copy it to our own repos and audit each update before use.

But that's not practical for all situations. For example, Web frontend developer culture might be the worst environment, to the point you often can't get many things done in feasible time, if you don't adopt the same reckless practices.

I'm also seeing it now with the cargo-culting of opaque self-hosted AI tools and models. For learning and experimenting, I'd spend more time sufficiently compartmentalizing an individual tool than with using it.

This weekend, I'm dusting off my Rust skills, for a small open source employability project (so I can't invest in expensive dependency management on this one). The main thing thing bothering me isn't allocation management, but the sinking feeling when I watch the cast-of-thousands explosion of transitive dependencies for the UI and async libraries that I want to use. It's only a matter of time before one of those is compromised, if not already, and one is all it takes.

schmichael - 5 days ago

We need a term like “Mature” or similar for dependencies that are done. Mature dependencies have two characteristics:

1. Well defined scope

2. Infrequent changes

Nomad has many of these (msgpack, envparse, cli, etc). These dependencies go years without changing so the dependency management burden rapidly approaches zero. This is an especially useful property for “leaf” dependencies with no dependencies of their own.

I wish libraries could advertise their intent to be Mature. I’d choose a Mature protobuf library over one that constantly tweaked its ergonomics and performance. Continual iterative improvement is often a boon, but sometimes it’s not worth the cost.

Charon77 - 4 days ago

One of the good thing in cargo packages are the feature flags. If a repo uses too much dependencies then it's time to open an issue or PR to hide them behind feature flags. I do that a lot with packages that requires std even though it could do with core and alloc.

cargo tree helps a lot on viewing dependency tree. I forgot if it does LoC count or not..

> to see what lines ACTUALLY get compiled into the final binary,

This doesn't really make much sense as a lot of the functions that make it to the binary get inlined so much that it often becomes part of 'main' function

rs186 - 5 days ago

I once wanted to contribute to the popular swc project (https://github.com/swc-project/swc). I cloned the repo, ran build, and a whooping 20GB was gone from my disk. The parser itself (https://github.com/swc-project/swc/blob/main/crates/swc_ecma...) has over a dozen dependencies, including serde.

Meanwhile, the heaviest JavaScript parser implemented in JavaScript is more lightweight.

I decided that I should leave this project alone and spend my time elsewhere.

XxiXx - 5 days ago

I think it's a "cultural" thing. With Go you often find developers/projects proudly mentioning that any or just a few non-std dependencies are used. Coming from Go it really feels strange when you see pages of dependencies scrolling over your screen when you build a Rust project.

the__alchemist - 4 days ago

To address a point near the end of the article, here is my [partial] solution that works as a baseline.

Curate a collection of libraries you use and trust. This will probably involve making a number of your own. Wheel-reinvention, if you will. If done properly, even the upfront time cost will save in the long-run. I am in the minority here, but I roll my own libs whenever possible, and the 3rd party libs I use are often ones I know, have used been for, and vetted that they have a shallow tree of their own.

Is this sustainable? I don't know. But It's the best I've come up with, in order to use what I see as the best programming language available for several domains.

There are a lot of light-weight, excellent libs I will use without hesitation, and have wide suitability. Examples:

  - num_enum
  - num_traits
  - bytemuck
  - chrono
  - rand
  - regex
  - bincode
  - rayon
  - cudarc
Heavier, and periodically experience mutual-version hell, but are are very useful for GUI programs:

  - EGUI
  - WGPU
  - Winit
On a darker note, the rust web ecosystem maybe permanently lost to async and messy dependencies. Embedded is going that way too, but I have more hope there, and am doing my best to have my own tooling.
klooney - 5 days ago

> dotenv is unmaintained.

How much maintenance could you possibly need to load secrets from .env into the environment.

QuadmasterXLII - 5 days ago

I wonder how much good a “dependency depth” label on packages would do, at the crates.io level. Like, a package can only depend on a package with a lower declared dependency depth than it, and packages compete to have a low dependency depth as a badge.

cryptonector - 4 days ago

> What's the solution?

Big things you use off-the-shelf libraries for. Small things you open-code, possibly by cribbing from suitably-licensed open source libraries. You bloat your code to some degree, but reduce your need to audit external code and reduce your exposure to supply chain attacks. Still, the big libraries are a problem, but you're not going to open code everything.

This isn't just Rust. It's everything.

sitta - 4 days ago

I recently wrote an extremely basic Rust web service using Axum. It had 10 direct dependencies for a total of 121 resolved dependencies. I later rewrote the service in Java using Jetty. It had 3 direct dependencies for a total of 7 resolved dependencies. Absolutely nuts.

colanderman - 5 days ago

Rust at least has a partial remedy to this problem: feature flags. Many libraries use them to gate features which would otherwise pull in extra dependencies. (In fact I believe there is specific support for flags which correspond to dependency names.)

wpollock - 4 days ago

All the comments and suggestions for improving rust dependency handling seem useful to me. To deal with dependency sprawl now, until the situation changes, I use a number of tools. To avoid having to set this up for each new project, I've made a template project that I simply unzip to create new rust projects.

The tools I have found useful are:

cargo outdated # check for newer versions of deps

cargo deny check # check dependency licenses

cargo about # generate list of used licenses

cargo audit # check dependencies for known security issues

cargo geiger # check deps for unsafe rust

I haven't found a cargo tool I like for generating SBOMs, so I installed syft and run that.

cargo install-update # keep these tools updated

cargo mutants # not related to deps, but worth a mention, used when testing.

Having configured all these tools once and simply unzipping a template works well for me.

Suggestions for different or additional tools welcome!

Disclaimer: I'm not a professional rust developer.

mleonhard - 4 days ago

> I can't rewrite the world, an async runtime and web server are just too difficult and take to long for me to justify writing for a project like this (although I should eventually just for a better understanding).

I did this and it only solved half of the bloat:

https://crates.io/crates/safina - Safe async runtime, 6k lines

https://crates.io/crates/servlin - Modular HTTP server library, threaded handlers and async performance, 8k lines.

I use safina+servlin and 1,000 lines of Rust to run https://www.applin.dev, on a cheap VM. It serves some static files, a simple form, receives Stripe webooks, and talks to Postgres and Postmark. It depends on some heavy crate trees: async-fs, async-net, chrono, diesel, rand (libc), serde_json, ureq, and url.

2,088,283 lines of Rust are downloaded by `cargo vendor` run in the project dir.

986,513 lines using https://github.com/coreos/cargo-vendor-filterer to try to download only Linux deps with `cargo vendor-filterer --platform=x86_64-unknown-linux-gnu`. This still downloads the `winapi` crate and other Windows crates, but they contain only 22k lines.

976,338 lines omitting development dependencies with `cargo vendor-filterer --platform=x86_64-unknown-linux-gnu --keep-dep-kinds=normal`.

754,368 lines excluding tests with `cargo vendor-filterer --platform=aarch64-apple-darwin --exclude-crate-path='*#tests' deps.filtered`.

750k lines is a lot to support a 1k-line project. I guess I could remove the heavy deps with another 200 hours of work, and might end up with some lean crates. I've been waiting for someone to write a good threaded Rust Postgres client.

aliceryhl - 5 days ago

I'm quite careful to tightly control the dependencies of Tokio. All dependencies are under control by members of the Tokio team or others that I trust.

wyldfire - 4 days ago

> Out of curiosity I ran toeki a tool for counting lines of code, and found a staggering 3.6 million lines of rust. Removing the vendored packages reduces this to 11136 lines of rust.

Out of those 3.6 million lines, how many are lines of test code?

endorphine - 4 days ago

What actually surprised me in Rust, is the amount of fragmentation and abandoned libraries. For example, serde_yaml is archived and there are two other libraries that do the same (?) thing. It seems like there's a significant effort required to search for and decide which (if at all) library to use. This is not so much pronounced in Go.

GuB-42 - 4 days ago

The (terrible) solution that we are seeing now is generative AI. Instead of importing a library, you ask an AI to write the code for you, the AI most likely has ingested a library that implements the features you need and will essentially copy-paste that part into your code, transforming it so that it matches the rest of your code.

I believe that it causes more problems than it solves, but it can be a solution to the problem of adding thousands of lines of code of dependency when you could write a 10-line function yourself.

Of course, the proper thing to do is not to be the wrong kind of lazy and to understand what you are doing. I say the wrong kind of lazy because there is a right kind of lazy, and it is about not doing things you don't need to, as opposed to doing them poorly.

gxt - 5 days ago

You can audit your dependencies for crates with security vulnerabilities reported to the RustSec Advisory Database, also block unmaintained crates, and enforce your license requirements using SPDX expressions with cargo-audit and cargo-deny.

You can ensure that third-party Rust dependencies have been audited by a trusted entity with cargo-vet.

And you should have taken a look at where those 3M locs come from, it's usually from Microsoft's windows-rs crates that are transitively included in your dependencies through default features and build targets of crates built to run on windows.

Avi-D-coder - 4 days ago

The solution is strong compile time and runtime guarantees about code behavior.

The author is right there's no way an individual can audit all that code. Currently all that code can run arbitrary build code at compile time on the devs machine, it can also run arbitrary unsafe code at runtime, make system calls, etc..

Software is not getting simpler, the abundance of high quality libraries is great for Rust, but there are bound to be supply chain attacks.

AI and cooperative auditing can help, but ultimately the compiler must provide more guarantees. A future addition of Rust should come with an inescapable effect system. Work on effects in Rust has already started, I am not sure if security is a goal, but it needs to be.

demarq - 5 days ago

> Many call for adding more to the rust standard library much like Go

This is the way.

thrance - 5 days ago

I had the same concerns when I started using Rust, but then I eventually embraced it, for better or worse. Cargo makes it so your build almost never breaks (it's happened maybe twice for the 8 years I've been doing Rust). Plus there are still way less vulnerabilities with Rust projects than non-Rust projects, in spite of the crazy number of dependencies.

If I was to design a Rust 2.0, I'd make it so dependencies need permissions to access IO, or unsafe code, etc.

James_K - 4 days ago

When I am compiling Rust applications, I must admit I'm always rather bemused at the number of dependencies pulled. Even what I'd have thought to be simple tools reach easily about 200 dependent packages. It's nightmarish. One way this becomes particularly apparent is if you're trying to create a reproducible package for Guix or Nix. You end up having to manually specify a package for every different Rust library because of how those system require reproducible builds. The process of writing Guix package for software has been extremely illuminating for me, as to just how deeply nested certain technologies are vs. others. I'd be willing to bet it's a good metric for what sticks around. If you've got 200 dependencies, I don't think your software is gonna last the test of time. It seems a recipe for endless churn.

bsrkf - 4 days ago

Excuse me for not having much to add to the discussion but two interesting references for people to check out, if so inclined of course:

a) Ginger Bill (the Odin language creator, no affiliation) stated on a podcast that Odin will never have an official pkg manager, since what they're, in his opinion, mainly automating is dependency hell, and this being one of the main reasons for rising software complexity and lower software quality; see https://www.youtube.com/watch?v=fYUruq352yE&t=11m26s (timestamped to the correct position) (they mention Rust explicitly as an example)

b) another programmer rather seriously worried about software quality/complexity is Jonathan Blow, who's talk "Preventing the Collapse of Civilization" is worth watching in my opinion: https://www.youtube.com/watch?v=ZSRHeXYDLko (it's not talking about package managers specifically, but is on topic regarding software complexity/quality as a whole)

Addendum: And sorry, I feel like almost everyone knows this xkcd by now, but since no one so far seems to have posted it; "obligatory xkcd reference": https://imgs.xkcd.com/comics/dependency_2x.png

weltensturm - 4 days ago

Rust has a million ways to solve a specific problem, as it is not opinionated and gets you down to the lowest level if needed. On top of that there's a million ways to encode your types. Then there's a million ways to bind C libraries.

The solution space is basically infinite, and that's a good thing for a systems programming language. It's kind of amazing how far rust reaches into higher level stuff, and I think the way too easy to use package manager and lively crate ecosystem is a big part of that.

Sometimes I wish for a higher-level rust-like language though, opinionated as hell with garbage collector, generic functions without having to specify traits, and D's introspection.

iainmerrick - 4 days ago

No mention here of binary size (beyond linking out to a ClickHouse blog post on the topic).

The total number of lines of code is relevant, sure, but for most practical purposes, compile times and binary sizes are more important.

I don't know the situation in Rust, but in JS land, there's a pretty clear divide between libraries that are tree-shakable (or if you prefer, amenable to dead code elimination) and those that aren't. If you stick to tree-shakable dependencies your final bundled output will only include what you actually need and can be pretty small.

yubblegum - 4 days ago

So asking HN: whatever happened with OSGi? Does that architecture solve the problem, and if no, why not?

https://docs.osgi.org/specification/osgi.core/7.0.0/framewor...

"How OSGi Changed My Life" (2008) https://queue.acm.org/detail.cfm?id=1348594

stefanos82 - 5 days ago

Existing discussion in https://news.ycombinator.com/item?id=43930640

vladkens - 4 days ago

I agree that there are too many dependencies in Rust. I support the idea of adding some of the more popular crates to std. Many applications use something like tracing, tracing-subscriber, and basic server/client functionality. It would be great to have simple, minimal-feature implementations of these in std — similar to how Go does it. If someone needs a more complex system, they can still use an external crate, but having basic building blocks in std would really help.

morsecodist - 4 days ago

I see a lot of concern like this about dependencies, mostly in node. I'm sure it's an issue I'm just not convinced it's as big of a problem as people say. We have scanners that can help keep your dependencies secure automatically. If you take a dependency and it goes unmaintained is it really that much worse than the relevant code in your own codebase going unmaintained?

CraigJPerry - 4 days ago

Vendoring is a step in the right direction, you’ve constrained one side of the equation.

But you’re still open to typo squatting and similar issues like crates falling unmaintained - the article mentions the now famous dotenv vs. dotenvy issue (is this solvable with a more mature governance model for the crates ecosystem? At this point dotenv should probably be reclaimed). So after vendoring a baseline set of dependencies, you need to perform comprehensive auditing.

Maybe you can leverage LLMs to make that blob of vendored deps smaller / cheaper to own. Maybe you can distill out only the functionality you need (but at what cost, now you might struggle to backport fixes published upstream). Maybe LLMs can help with the auditing process itself.

You need a stream of notifications of upstream fixes to those vendored deps. Unfortunately in the real world the decision making will be harder than “ooh, there’s a sec fix, I should apply that”.

I always wonder why someone like JFrog don’t expand their offering to provide “trusted dependencies” or something similar. I.e. you pay to outsource that dependency governance and auditing. Xray scanning in the current product is a baby step toward the comprehensiveness I’m suggesting.

Taking a step back though, I’d be really careful not to throw the baby out with the bath water here. Rust has a fairly unique capability to compose work product from across unrelated developers thanks to its type system implementation (think about what happens with a C library, who’s responsible for freeing the memory, you or me?). Composition at scale is rusts super power, at least in terms of the productivity equation for large enterprises - in this context memory safety is not the sales pitch since they already have Java or whatever.

vsgherzi - 4 days ago

author here, thanks for reading and all of your thoughts! Here's another older HN thread with some interesting comments. https://news.ycombinator.com/item?id=43930640

vzaliva - 4 days ago

They should take a look at OPAM (OCaml’s package manager). There was a really impressive talk at the OCaml Workshop at POPL or ICFP a couple of years ago about how it works. Basically, they have a huge CI infrastructure and keep all versions of every package ever published. So, once you’ve found the right set of dependencies for your project, you can be sure the exact versions will always be available via OPAM.

nyuriks - 4 days ago

I see two points: safety - bigger supply chain attack surface, and code bloat/compiler performance. The later has been discussed in numerous posts here (the whole idea of a linker from the start was to get rid of unused functions, so not a big problem imo). The safety is a serious and legit consideration, but we also rely on Linux and build tools to build things. How do you know the compiler that was used to build Linux hasn't been compromised, perhaps several generations ago, and now your Linux has a backdoor that is not in Linux source code? There was a research paper on this IIRC. We trust the ecosystem to validate each tool we use. We just have to do the same with our own projects - only use what's relevant, and we should do dependency hygiene to check if it is coming from a reputable source...

righthand - 5 days ago

Everyone is in such a rush to get their project out the door, no one has time to generate a key and properly code sign releases and begin developing a more secure chain. Now we have JS package "whatever code" ecosystem but for Rust. As if we haven't watched NPM get hacked many times over the last decade or so.

rvz - 4 days ago

> What's the solution?

A proper 'batteries included' standard library in the language and discouraging using too many libraries in a project.

The same mistakes from the Javascript community are being repeated in front of us for Cargo (and any other project that uses too many libraries).

NewJazz - 4 days ago

Out of curiosity I ran toeki a tool for counting lines of code, and found a staggering 3.6 million lines of rust. Removing the vendored packages reduces this to 11136 lines of rust.

Tokei hasn't had a stable release in over 4 years and misreports lines of code in some instances. The author in the past has basically said they would need to be paid to backport one line fixes with no merge conflicts that fix real accuracy issues in their software... Bad look in my book.

https://github.com/XAMPPRocky/tokei/issues/875

ak_111 - 4 days ago

Dependency and build management is a fascinating and still unsolved problem in software engineering (in some sense it is the central problem).

I am wondering if there is a good modern reference that provides a conceptual overview or comparative study of the various techniques that have been attempted.

It is a hard subject to define as it cuts through several layers of the stack (all the way down to the compiler system interface layer), and most book focus on one language or build technology rather than providing a more conceptual treatment of the techniques used.

arp242 - 4 days ago

3.6M lines of code seems so much that it sets off my "are you sure that's counted right?" alarm.

I'm not very familiar with Rust, but all of Go is 1.6M lines of Go code. This includes the compiler, stdlib, tests for it all: the lot.

Not that I doubt the sincerity of the author of course, but maybe some irrelevant things are counted? Or things are counted more than once? Or the download tool does the wrong thing? Or there's tons of generated code (syscalls?)? Or ... something? I just find it hard to believe that some dependencies for web stuff in Rust is twice all of Go.

kirici - 4 days ago

> This whole fiasco led me tho think .... do I even need this crate at all? 35 lines later I had the parts of dotenv I needed.

"A little copying is better than a little dependency." - grab the parts that you need and then include the library only in a test to ensure alignment down the line, an idea I liked a lot.

https://www.youtube.com/watch?v=PAAkCSZUG1c&t=9m28s

amelius - 5 days ago

I think the main problem is that you should be able to run dependencies inside their own sandbox, and the language focuses only on memory safety within a monolithic program.

conradludgate - 5 days ago

As a fellow rust developer, I love our dependencies but I put a lot of effort into pruning the ones I want to use. If I see a crate using too many I might contribute to it or find a replacement.

If you want to use dependencies, I wouldn't be surprised when you realise they also want to use dependencies. But you can put your money/time in the right places. Invest in the dependencies that do things well.

philsnow - 4 days ago

> do I even need this crate at all? 35 lines later I had the parts of dotenv I needed.

I'm not saying you copy-pasted those 35 lines from dotenvy, but for the sake of argument let's say you did: now you can't automatically benefit from dotenvy patching some security issue in those lines.

lmm - 4 days ago

A thought experiment for this writer: imagine if Tokio (and all its dependencies) were moved into the Rust standard library, so that it was more like Go. Would that make them more comfortable depending on it (not that they'd have a choice any more)? If so, why?

anothernewdude - 4 days ago

Python is in the same spot now you can't easily install packages globally. I don't have the hard drive space to develop multiple projects anymore. Every single project takes up multiple gigs in just dependencies.

bradley13 - 4 days ago

This is a general problem: devs pulling in libraries instead of writing a few lines of code. Those libraries pull in more dependencies that have even more dependencies.

There's no good solution...

- 4 days ago
[deleted]
ThouYS - 4 days ago

I'm using fewer and fewer libs, thanks to ChatGPT. Just write me whichever function I currently need

hedora - 4 days ago

Has anyone had good luck with cargo vet?

It lets security professionals cryptographically vouch for the trustworthiness of rust packages.

swoorup - 4 days ago

This feels like a pointless issue. At best perhaps establish a good trust model, than blaming the tooling.

hedora - 4 days ago

What about cargo vet?

It lets security professionals audit rust packages, and cryptographically attest to their trustworthiness.

viktorcode - 4 days ago

A large removable standard library seems to be the optimal solution. It is there by default for everyone, but if needed for embedded scenario it can be removed, leaving only the core language features.

Alex_001 - 4 days ago

[dead]

fucker42069 - 4 days ago

[dead]

oldpersonintx - 5 days ago

[dead]

- 5 days ago
[deleted]
srikanth767 - 5 days ago

True

1vuio0pswjnm7 - 5 days ago

"Not thinking about package management careful makes me sloppy."

Isn't the point of a memory safe language to allow programmers to be sloppy without repercussions, i.e., to not think about managing memory and even to not understand how memory works.

Would managing dependencies be any different. Does Rust allow programmers to avoid thinking carefully about selecting dependencies.

csomar - 5 days ago

> when checking a rust security advisory mentioning that dotenv is unmaintained

This is a problem with all languages and actually an area where Rust shines (due to editions). Your pulled in packages will compile as they previously did. This is not true for garbage collected languages (pun intended).

> Out of curiosity I ran toeki a tool for counting lines of code, and found a staggering 3.6 million lines of rust .... How could I ever audit all of that code?

Again, another area where Rust shines. You can audit and most importantly modify the code. This is not that easy if you were using Nodejs where the runtimes are behind node/v8 or whatever. You compile these things (including TLS) yourself and have full control over them. That's why Tokio is huge.