Hi everyone! I was thinking about opening an RFC and wanted to test the waters here a little bit. ![]()
In short, I want to propose that we limit the files that are packaged by cargo package by default before uploading a crate to crates.io. This would not only save bandwidth/resources, but also make reviewing crates as part of a supply chain easier. Since that would be a breaking change, I reckon that the upcoming 2027 Edition would be a great opportunity to include such a change.
A bit of context: At my company, it has become part of our routine to review every Rust dependency that is updated in our code base. This means that we have looked at hundreds of project structures and diffs over the months and from time to time we find crates that include files that aren’t really required. Be it gifs or pngs, pdfs, or maybe binary test data. For some of them, it is worth discussing if they should actually be shipped with the crate, e.g. to locally verify that the tests are running, and that is ok, but some files are truly not required and balloon the size of the crate without any benefits.
Whenever we encounter such cases, we try to open PRs to exclude these files from the shipped crate. Here are some examples for the typical three scenarios:
- Logos/Gifs: Use `package.include` to only package necessary files for redistribution & the README.md by 42triangles · Pull Request #2 · iShape-Rust/iKeySort · GitHub (going from over 5MiB down to 15.4KiB in size)
- Scripts: Exclude cherry-pick-stable script from crates.io package by SwishSwushPow · Pull Request #4748 · rust-lang/libc · GitHub (removing a 150 line shell script)
- Binary data: Exclude test DLL's from published package by weiznich · Pull Request #191 · nagisa/rust_libloading · GitHub (removing dlls from the tests)
Optimizing the size of crates saves resources (bandwidth, storage) on both the users’ side and the side of crates.io. The crate-size example linked above is more of an extreme case, yet I believe that many crates exist where such files are included by accident, and that wastes a lot of resources.
On top of that, having more files in a crate also means that reviewing them is more involved, and in the case of binary files, also much harder or impossible to do. Thus reducing the number of shipped files not only saves resources, but also makes it easier to ensure the supply chain safety of the Rust ecosystem by limiting the number of attack vectors and reducing the time needed to review crate updates.
Package managers that include only a limited set of files by default are, for example, pip or the Swift Package Manager. Here the files are limited to mostly python or swift source files, except for the usual suspects like a README or LICENSE file.
For Rust, I would start by proposing the following option: Besides the files that are always required (build.rs, cargo related files), and files we really should include (readme, change log, licenses) we could limit any other files to Rust source files (.rs) and Markdown files (.md). The include = [..] (overwrite the default list) and exclude = [..] behavior could stay the same.
This way, we make sure that any images, binary files, or scripts are included deliberately and not by accident.
Another possible option would be to limit the included files to the typical directories of a Rust project (/src, /tests, /benches), which should reduce the number of unneeded files as well, but in my opinion not as effectively as the first option.
These are not yet 100% technically accurate descriptions since I have only briefly looked at the packaging code, but I think this is enough to convey the general idea here.
In any case, since that would be a breaking change, the upcoming Rust Edition 2027 would offer an opportunity to ship such an adjustment. Since 2027 is not far off, I thought it would be a good point in time to discuss such a change.