bin-expire scans common "bin" folders, identifies stale binaries, and can archive/restore them safely.
By default it scans:
~/.cargo/bin~/go/bin
It also detects Windows “App Execution Alias stubs” (0-byte .exe placeholder files) and treats them specially so you don’t accidentally archive them.
-
Install Rust (from rustup)
-
Run
cargo install bin-expire
- Download the asset for your OS from the GitHub Releases page.
- Put the binary in a permanent folder (example):
- Windows:
C:\Users\<you>\AppData\Local\rust-apps\bin-expire.exe
- Add that folder (not the
.exe) to yourPATH. - Verify:
where bin-expire
bin-expire --helpBuild an optimized binary:
cargo build --releaseRun it:
./target/release/bin-expire scan --days 30Or install it into your Cargo bin directory:
cargo install --path .# Scan default locations (~/.cargo/bin and ~/go/bin)
bin-expire scan
# Scan a specific directory
bin-expire scan -p ~/.cargo/bin --days 30
# Archive stale binaries (moves them into your configured archive_path)
bin-expire archive --days 30
# Restore a previously archived binary by name
bin-expire restore old_tool.exe- Default output shows only:
- STALE rows (
✗)- stub rows (
·) (Windows App Execution Alias stubs)
- stub rows (
--verbosealso shows OK rows (✓) and adds:PATHcolumnSRCcolumn indicating wherelast_usedcame from:A=atime,M=mtime,?=unknown
Useful filters:
--only-stale(hides OK + stubs)--hide-ok(mainly useful with--verbose)--hide-stub(hides stub rows)
Moves stale binaries into archive_path and records each move in a manifest so it can be restored later.
Notes:
- App Execution Alias stubs (0-byte
.exe) are never archived. - Archiving avoids overwriting by choosing a non-colliding filename in the archive directory.
- If a direct rename/move fails, it falls back to copy + remove.
Restores the most recent archived entry for the given name (from the manifest).
Safety behavior:
- Fails if the archived file is missing.
- Fails if the destination already exists (it will not overwrite your existing file).
On first run, bin-expire creates a config file under your platform config directory:
- Windows:
%APPDATA%\bin-expire\config.toml - Linux:
~/.config/bin-expire/config.toml - macOS:
~/Library/Application Support/bin-expire/config.toml
You can override the config root with an environment variable:
BIN_EXPIRE_CONFIG_DIR=/some/path
When set, bin-expire reads/writes:
BIN_EXPIRE_CONFIG_DIR/bin-expire/config.tomlBIN_EXPIRE_CONFIG_DIR/bin-expire/archive.json
Example config.toml:
ignored_bins = ["cargo", "rustc"]
default_threshold_days = 90
archive_path = "C:/Users/me/.bin-expire/archive"
windows_use_access_time = trueConfig keys:
ignored_bins: file names to ignore during scan/archivedefault_threshold_days: used when--daysis not providedarchive_path: where archived binaries are movedwindows_use_access_time: Windows-only preference for selectinglast_used
On Windows, access times (atime) are best-effort and can be disabled, delayed, or updated by scanning/listing.
- If results look suspicious, set
windows_use_access_time=falseto use modified time (mtime). - bin-expire may also detect atime “contamination” during a scan and fall back to mtime.
cargo fmt --all
cargo clippy --all-targets -- -D warnings
cargo test
cargo test --release --all-targets