home

Canonical Rust library for resolving the home, CARGO_HOME, and RUSTUP_HOME directories used by Cargo and rustup.

Library
Cargo
v0.5.12
15,443stars
MIT OR Apache-2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
83/100Excellent
Development Activity96
Maintenance52
Community84
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
69/100Good
Architecture75
Code Quality58
Innovation82
Learning Curve60

home is the canonical Rust crate for resolving a user’s home directory and the CARGO_HOME/RUSTUP_HOME storage directories that Cargo and rustup rely on. Maintained directly inside the rust-lang/cargo monorepo, it exists to give every piece of Rust tooling the exact same home-directory logic Cargo and rustup use internally, instead of each tool reimplementing (and subtly diverging from) that resolution on its own.

The crate is intentionally minimal: three core functions, cwd-parameterized variants for testability, and an Env trait that lets callers swap in a mock environment for unit tests. It has no dependencies beyond the standard library, and its own maintainers are explicit that it’s built primarily for Cargo and rustup rather than as a general-purpose utility — a scope worth knowing before pulling it into unrelated projects.

What You Get

  • Canonical home_dir(), cargo_home(), and rustup_home() functions matching exactly what Cargo and rustup use internally
  • _with_cwd variants for resolving paths against an explicit working directory rather than the process’s actual cwd
  • An Env trait plus OsEnv implementation for injecting a mock environment in tests
  • A dependency-free surface (only the Rust standard library) so it adds negligible weight to a project’s build graph

Common Use Cases

  • Cargo and rustup resolving their own on-disk storage locations at startup
  • Custom cargo subcommands finding the same CARGO_HOME Cargo itself would use
  • Toolchain-management tools mirroring rustup’s home-directory conventions
  • Unit tests that need deterministic, mockable home/cargo/rustup directory resolution

Under The Hood

Architecture home is architected as a two-file crate: lib.rs exposes five public functions (home_dir, cargo_home, cargo_home_with_cwd, rustup_home, rustup_home_with_cwd) that are thin wrappers delegating to env.rs. The real logic sits behind an Env trait (home_dir, current_dir, var_os) with a single production implementation, OsEnv, that forwards to the real std::env calls; every public function has a hidden _with_env counterpart that takes &dyn Env instead. This dependency-injection seam is the crate’s one real architectural decision — it exists purely so downstream consumers like rustup can substitute a fake environment in their own test suites without mutating real process-global state. Nothing else in the crate would break if this pattern changed, since home has no internal layers beyond this trait boundary and no consumers beyond Cargo and rustup itself.

Tech Stack The crate targets stable Rust and declares zero runtime dependencies in its Cargo.toml — no [dependencies] section is present at all. It now simply forwards home_dir() to the standard library’s own std::env::home_dir, having previously shipped a hand-rolled Windows implementation (via windows-sys) to route around a long-standing std bug that was fixed upstream in Rust 1.85.0. It lives inside the rust-lang/cargo Cargo workspace, inheriting edition, license, and repository fields from the workspace manifest rather than declaring them itself, and ships only a src/ tree plus Cargo.toml, CHANGELOG.md, and license files per its include allowlist.

Code Quality There is no dedicated tests/ directory or #[cfg(test)] module inside the crate — its only executable checks are the doctests embedded in each function’s doc comment. Naming is consistent and minimal (home_dir, cargo_home, rustup_home, each with an _with_cwd and _with_env variant), and every public item carries a full doc comment explaining preference order and failure conditions. Error handling uses plain io::Result with a generic io::Error::new(io::ErrorKind::Other, …) rather than a typed error enum, which is adequate given the crate’s tiny surface but would not scale to a larger API. The crate builds under the parent cargo workspace’s clippy.toml/rustfmt.toml and CI, so it benefits from the monorepo’s linting and testing pipeline even without its own dedicated suite.

API Design The public API is about as low-friction as a Rust crate can be: a handful of functions, no builder patterns, no configuration structs, and every function documented with a runnable usage example. cargo_home() and rustup_home() mirror each other exactly in behavior and naming, so learning one teaches the other. The one deliberate wrinkle for API consumers is the _with_env/Env trait indirection, which trades a small amount of API surface for testability — a pattern more Rust libraries could adopt for anything touching process-global state. The crate’s own docs are explicit that it is scoped narrowly to Cargo and rustup’s needs and “not intended for external use,” unusually honest communication about intended blast radius.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search