which-rs

Rust crate that locates executable binaries on PATH, mirroring the Unix which command cross-platform

Library
Cargo
v8.0.6
271 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
55 /100 Fair
Development Activity 40
Maintenance 32
Community 68
Maturity 60
Momentum 20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
74 /100 Good
Architecture 78
Code Quality 76
Innovation 62
Learning Curve 80

which-rs is a Rust library that implements the behavior of the Unix which(1) command as a typed, embeddable function rather than a shell-out. Given a binary name, it searches $PATH (and honors PATHEXT on Windows) to return the absolute path of the first matching executable file, correctly handling absolute and relative paths, symlinks, and platform-specific executable-permission checks.

It supports Linux, macOS, Windows, and WASI targets, with an optional regex feature (which_re) for finding every executable on PATH matching a pattern — useful for discovering all cargo-* subcommands, for example. The crate abstracts platform differences behind a Sys trait, so callers needing full control (or running in restricted/sandboxed environments without direct filesystem access) can disable the default real-sys feature and supply a custom system implementation.

What You Get

  • A which() function that resolves an executable name to its absolute path using PATH lookup rules
  • A which_all() iterator returning every matching executable on PATH, not just the first
  • Optional regex-based lookup (which_re) to find all executables matching a pattern, e.g. every installed cargo-* subcommand
  • Cross-platform support for Linux, macOS, Windows (including PATHEXT), and WASI
  • A pluggable Sys trait so the default filesystem-backed implementation can be swapped for sandboxed or test environments

Common Use Cases

  • A build tool or CLI checking whether a required external binary (e.g. git, ffmpeg, rustc) is installed before invoking it
  • A cross-platform Rust application that needs to locate a companion tool without hardcoding OS-specific PATH logic
  • Discovering all installed Cargo subcommands or plugin binaries via the regex feature
  • Test or sandboxed environments that inject a mock Sys implementation to simulate PATH contents without touching the real filesystem

Under The Hood

Architecture - The crate splits responsibilities cleanly across small modules: finder.rs (391 lines) owns the core PATH-walking algorithm and iterator logic, checker.rs verifies a candidate path is actually an executable file (permission bits on Unix, extension matching via sys.rs on Windows), error.rs defines the crate’s Result/Error types, and sys.rs (330 lines) abstracts OS-specific behavior (reading PATH/PATHEXT, permission checks, WASI/Redox variants) behind a Sys trait so the finder logic itself stays platform-agnostic. lib.rs (745 lines, mostly public API and doc examples) exposes which, which_all, which_in, and the regex variants as thin wrappers over Finder. Tech Stack - Pure Rust, 2021 edition, MSRV 1.70. Dependencies are minimal and mostly optional: libc (Unix-only, gated behind the default real-sys feature) for permission checks, regex behind the regex feature, and tracing behind an opt-in feature for diagnostic logging; win_ffi.rs adds a small amount of raw Windows FFI for Windows-specific path resolution. Dev-dependencies are limited to tempfile for filesystem-based tests. Code Quality - The crate ships a real test suite (tests/basic.rs, tests/windows_no_pathext.rs) plus clippy.toml and deny.toml configuration, indicating active lint and dependency-auditing discipline; a RELEASE_STEPS.md and maintained CHANGELOG.md show a deliberate release process across 15 published versions. The Sys trait abstraction is a clean invariant boundary between deterministic PATH-search logic and OS-specific filesystem calls, which also makes the core algorithm independently testable. API Design - The public API is small and predictable: which(name) for the common case, which_all for every match, and _in variants that accept an explicit PATH/cwd override for testing or sandboxing, all documented with runnable doc-examples in lib.rs. Feature flags (regex, tracing, real-sys) are additive and off-by-default where appropriate, keeping the default dependency footprint minimal for the common case of just resolving one binary name.

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