directories

A tiny Rust library that resolves the platform-specific, user-accessible config, cache, and data directory paths for Linux, macOS, and Windows.

Library
Cargo
v6.0.0
838stars
MIT OR Apache-2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
33/100Needs Attention
Development Activity0
Maintenance0
Community44
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
70/100Good
Architecture78
Code Quality60
Innovation55
Learning Curve85

directories is a minimal-API Rust crate that answers one narrow question correctly across platforms: where should this application put its config, cache, and data files? Rather than hardcoding paths or reinventing per-OS logic in every project, it exposes three small structs — BaseDirs, UserDirs, and ProjectDirs — that compute the correct location by following the XDG base/user directory specifications on Linux, the Known Folder API on Windows, and the Standard Directories guidelines on macOS.

The library is deliberately narrow in scope. It does not create directories, check for their existence, or manage file I/O — it only tells the caller what a given path should be, leaving directory creation and usage decisions to the application. This keeps the crate’s surface area tiny (three structs, four factory functions, plain getters) and its single runtime dependency (dirs-sys) minimal, which is why it has become a common building block for Rust CLI tools and desktop applications that need to behave correctly across operating systems without embedding OS-specific path logic themselves.

What You Get

  • BaseDirs - user-invisible standard directories (cache, config, data, executable, runtime, state) resolved per OS convention
  • UserDirs - user-facing standard directories (audio, desktop, documents, downloads, pictures, videos, etc.)
  • ProjectDirs - per-application cache/config/data directories derived from a qualifier, organization, and application name
  • Zero directory side effects - the library only computes paths; it never creates directories or touches the filesystem
  • Minimal dependency footprint - a single runtime dependency (dirs-sys) handling the low-level OS calls

Common Use Cases

  • CLI tool config storage - a command-line tool computes ProjectDirs::from(...).config_dir() to read and write its settings file in the OS-correct location
  • Desktop app cache management - a desktop application stores downloaded assets or computed caches under the platform’s cache directory instead of a hardcoded path
  • Cross-platform installers/updaters - a Rust binary needs to know where to place logs, state, or runtime sockets consistently across Linux, macOS, and Windows
  • Migrating from ad-hoc path logic - a project replaces its own $HOME-based path guessing with a maintained, spec-compliant implementation

Under The Hood

Architecture The crate is organized around three plain data structs (BaseDirs, UserDirs, ProjectDirs) defined in src/lib.rs, each populated by a platform-specific backend module selected at compile time via cfg attributes — src/win.rs for Windows, src/mac.rs for macOS/iOS, src/lin.rs for Linux and other Unix-likes, and src/wasm.rs as a no-op fallback for wasm32 targets. Each backend module implements the same small function set (base_dirs, user_dirs, project_dirs_from, project_dirs_from_path) which the public structs delegate to via a use ... as sys alias, so the platform selection logic lives entirely in the module import, not in conditional branches scattered through the public API. This keeps the public surface identical across platforms while the underlying resolution strategy — reading XDG_* environment variables on Linux, calling into SHGetKnownFolderPath on Windows, or following Apple’s Standard Directories on macOS — is fully encapsulated per backend.

Tech Stack The crate targets stable Rust with no edition-specific features required, and declares a single runtime dependency, dirs-sys (a companion low-level crate handling raw OS directory calls and is_absolute_path validation), plus bencher as a dev-dependency for its constructor benchmarks. There is no async runtime, no I/O beyond environment-variable reads and OS API calls, and no build step beyond cargo build — the crate is published to crates.io as directories and consumed as a standard Cargo dependency.

Code Quality The crate uses #![deny(missing_docs)] at the crate root, forcing every public struct and method to carry doc comments, and the public API documentation embeds per-platform value tables directly in each getter’s doc comment — a pattern that keeps documentation accurate by co-locating it with the code it describes. Test coverage is limited: src/lib.rs contains a #[cfg(test)] mod tests block with three smoke tests that print the resolved directories rather than asserting expected values, so correctness on unfamiliar environments is really being validated through documentation traceability and the maintained companion dirs-sys crate rather than through exhaustive automated assertions. A GitHub Actions workflow (.github/workflows/rust.yml) runs CI on pushes.

What Makes It Unique directories’ distinguishing choice is its restraint: it exposes exactly three structs and refuses to do anything beyond compute paths — no directory creation, no existence checks, and no directories are returned that only exist as a writable location on some platforms and a read-only system location on others (explicitly avoiding executable_dir and font_dir returning inconsistent semantics across OSes). This narrow, spec-literal scope is what has made it a common low-level dependency other Rust libraries build on rather than a general-purpose “app support” framework.

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