Companion to cli-tools.md. cli-tools.md is the reference (what's available). This file is the directive (which to pick when drafting commands, scripts, install instructions, or docs).
Default to the most modern, canonical tool. Never drift back to legacy aliases just because they're more common in the wild.
This applies whenever you're generating user-facing commands — README install steps, Dockerfile RUN lines, CI workflows, AGENTS.md run-commands tables, scratch shell snippets, anything the user will see or copy-paste.
The user has explicitly built their environment around modern tooling and pre-approved permissions for it. Every legacy fallback you generate is friction the user has to undo. The user notices. They've corrected this drift more than once.
Modern tools are also typically 10–100× faster (uv vs pip, fd vs find, rg vs grep) — defaulting legacy is a measurable cost, not a stylistic preference.
| Don't generate | Generate instead | Why |
|---|---|---|
pip install <pkg> |
uv tool install <pkg> (CLI tool) uv add <pkg> (project dep) uv pip install <pkg> (last resort) |
uv is 10–100× faster; uv tool is the right answer for CLI binaries — isolated env, lands on PATH, supports uv tool upgrade / uninstall |
pipx install <pkg> / pipx run <pkg> |
uv tool install <pkg> / uvx <pkg> |
uvx is the one-shot ephemeral runner; uv tool is persistent |
pip install -e . |
uv sync (uv-managed project) uv pip install -e ".[dev]" (last resort) |
uv sync reads pyproject + lockfile, installs everything, faster |
python -m venv .venv |
uv venv .venv |
Faster |
python -m pip install |
uv pip install |
Same |
VCS install: pip install git+https://... |
uv tool install git+https://... or uvx --from git+https://... <cmd> |
Modern equivalent works identically |
find . -name "*.py" |
fd -e py |
Faster, respects .gitignore, simpler syntax |
grep -r "pattern" |
rg "pattern" |
10× faster, respects .gitignore |
sed -i 's/old/new/g' file |
sd 'old' 'new' file |
No escaping headaches |
cat file.py (for display) |
bat file.py |
Syntax highlighting; for editing, use the Read tool |
ls -la --git |
eza -la --git |
Git status + icons in one command |
man <cmd> |
tldr <cmd> |
Practical examples, 98% smaller |
du -sh * |
dust |
Visual tree |
make <target> |
just <target> |
Simpler syntax, no tab-vs-space pain |
top / htop |
btm (when shown to user) |
Cleaner UI; ps is fine for shell scripts |
Never default to curl <url> for content extraction. Use this priority:
WebFetch tool — built-in, instantr.jina.ai/<url> — fastest fallback (~0.5s avg)firecrawl <url> — anti-bot bypass (Cloudflare, heavy JS)markitdown <url> — simple static pages or local filesWhen writing Dockerfiles, install uv from the official image rather than pip install uv:
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /usr/local/bin/
Then use uv tool install, uv sync, etc. Avoid plain pip in RUN lines.
If a downstream user's environment provably doesn't have uv (e.g. constrained CI runner, system without HOME write access), document the legacy fallback as a footnote, not the default. Default-modern, footnote-legacy.
If the user explicitly asks for a pip/find/grep invocation (e.g. "show me the pip command for X"), give them what they asked for — but mention the modern equivalent in passing.
Before committing any README.md, QUICKSTART.md, DEPLOYMENT.md, Dockerfile, or .github/workflows/*.yml:
rg -n 'pip install|pipx |\bfind \.|^grep |sed -i|^cat ' <file>
If anything matches, ask: is this really the modern way, or am I drifting?
cli-tools.md — reference table (what's installed, syntax cheatsheet)commit-style.md — Conventional Commits enforcement