Soft question: curb your dependencies

Relevant: Cull your dependencies | Hacker News

Anyone else experiencing something like this? Running cargo-tree and looking for things to eliminate? I find myself often doing this for (1) compile time, (2) reducing malicious code injection vectors, and (3) comprehending the overall code.

Interested to hear other experiences.

I often review cargo tree -d, because duplicates are the most obvious waste, and a sign of unmaintained dependencies.

2 Likes

I do this, and try to minimize deps at the start. It's a time sink though.

A part of the process I wish was more streamlined is culling feature flags. [1] Let's take image as an example -- 27 flags, 18 by default. I'm going to definitely need many of these -- jpeg, gif, png. Do I really need exr, which pulls in all of flume? Unlikely, but now I have to futz around to decide which of the flags I do need. [2] Repeat for every dep.


  1. Or I'm just unfamiliar with the proper tools to do this well; feedback welcome. ↩︎

  2. To image's credit, they have at least made all these functionalities modular enough to remove. ↩︎

5 Likes

Is there anything that can be done about any duplicates that are found? Or is it mainly a prompt to seek out better-maintained deps? (I should add '.. or to offer help with the under-maintained crate', but of course we can't always do that, and as a Rust newcomer I would be wary of inflicting my 'help' ...)

I'm normally pretty strict about not pulling in unnecessary dependencies for once-off things and try to get my team into the same habit[1]... However, the problem is when you want to build a larger application and the handful of dependencies you use pull in hundreds of transitive dependencies.

For example, at work we're making a graphical tool for doing ML and data analysis, using WebAssembly as a way to package up and distribute different computations. For this we might pull in wasmer for the WebAssembly bit (161 total dependencies), tracing_subscriber for logging (29 total dependencies), tauri for the UI (177 total dependencies), tensorflow for ML (69 Rust dependencies plus a gigantic C dependency), reqwest for retrieving data from the internet and communicating with a central server (101 total dependencies), and so on.

Sure, these numbers might be inflated because a lot of these dependencies are shared between projects. However, you can see how just adding a handful of direct dependencies to your crate can blow out to 500+ transitive dependencies and massive build times.

Often there's no way around it either, because something like Wasmer or Tauri is a core parts of the application that can't reasonably be replaced :disappointed:


  1. Go has a nice proverb here - A little copying is better than a little dependency ↩︎

1 Like

I have used cargo udep in the past to find unused dependencies.

4 Likes

As a minor point, but perhaps not quite off-topic, would ureq be better for your case?
https://lib.rs/crates/ureq

There isn't any universal solution. Sometimes you can switch to another, smaller crate. Sometimes you can disable default-features in your dependencies to avoid pulling in extra crates. Sometimes you have to ask others upgrade their deps and/or disable unused Cargo features in their crates.

Right, that makes sense, thanks. I'm just learning Rust, but if I were introducing the language to a workplace, I'd be a little scared of the crates ecosystem (shades of npm).

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.