- splitting up a package into smaller compilation units to speed up builds as llvm doesn't like large compilation units, e.g. I'm assuming this is why uv is split up
- splitting semver concerns (easiest if different parts of the api are versioned independently), e.g. one hope for splitting out `serde_core` is to allow breaking changes of `serde_derive`
- splitting out optional parts to improve build time (`features` can also be used but usability isn't as great), e.g. `clap` (cli parser) and `clap_complete` (completion support)
- less commonly run tests or benches that have expensive dependencies, e.g. `toml` splits out a benchmark package for comparing performance of `toml`, `toml_edit`, an old version of `toml`, and `serde_json`
- proc-macros generally have a regular library they generate code against
- lower development overhead to develop them together, e.g. anstyle has a lot of related packages and I wouldn't be wanting to maintain a repo per package
Something this doesn't mention is that Cargo workspaces allow for sharing parts of the manifest through "workspace inheritance", including package metadata like the repo, dependency version requirements, lint configuration, or compilation profiles.
There seems to be some misinformation about Yarn and how it is worse than pnpm when it comes to workspaces.
— Yarn does not hoist anything in PnP mode, which I think is the default and is better than the old node_modules approach for other reasons.
— Yarn most certainly supports the workspace: protocol in dependency version specs.
Is pnpm better than Yarn in some significant ways? Judging by the name I would assume pnpm has PnP mode just like Yarn, but does it also have zero-installs mode?
Rust has the nicest workspaces of any language I've dealt with. It makes monorepos naturally easy to build. No manually cobbled together Pants or Bazel or hacks - it's first class out of the box.
Here's a rather large workspace with desktop apps, server apps, CLI tools, and libraries:
- splitting up a package into smaller compilation units to speed up builds as llvm doesn't like large compilation units, e.g. I'm assuming this is why uv is split up
- splitting semver concerns (easiest if different parts of the api are versioned independently), e.g. one hope for splitting out `serde_core` is to allow breaking changes of `serde_derive`
- splitting out optional parts to improve build time (`features` can also be used but usability isn't as great), e.g. `clap` (cli parser) and `clap_complete` (completion support)
- local development tools, e.g. https://github.com/matklad/cargo-xtask
- less commonly run tests or benches that have expensive dependencies, e.g. `toml` splits out a benchmark package for comparing performance of `toml`, `toml_edit`, an old version of `toml`, and `serde_json`
- proc-macros generally have a regular library they generate code against
- lower development overhead to develop them together, e.g. anstyle has a lot of related packages and I wouldn't be wanting to maintain a repo per package
Packages also let you mix a library with bins and examples. We talked about multi-purpose packages vs libraries at https://blog.rust-lang.org/inside-rust/2024/02/13/this-devel... (this was before workspace publishing was supported).
Something this doesn't mention is that Cargo workspaces allow for sharing parts of the manifest through "workspace inheritance", including package metadata like the repo, dependency version requirements, lint configuration, or compilation profiles.
reply