Install
# Debian / Ubuntu
sudo apt install ripgrep fd-find bat fzf
# Arch
sudo pacman -S ripgrep fd bat eza zoxide fzf
# macOS
brew install ripgrep fd bat eza zoxide fzf
# Or via mise / cargo / scoop (see /tutorials/mise-polyglot-runtime-versions.html)
cargo install ripgrep fd-find bat eza zoxide
Two Debian quirks: fd is packaged as fdfind (alias it to fd in your shell), and bat on older Debian is called batcat (same).
# Add to ~/.bashrc or ~/.zshrc
alias fd='fdfind'
alias bat='batcat'
ripgrep (rg) — the replacement for grep
What it does differently from grep:
- Recursive by default; no
-rneeded. - Respects
.gitignore,.ignore, and.rgignore; skips.git,node_modules,target, etc. - Uses parallel threads — on a multi-core machine, several times faster than GNU grep.
- Detects binary files and skips them by default.
- Colours matches; shows file path + line number with a sensible format.
# Most uses are just "rg PATTERN"
rg fastify
# Limit to certain file types
rg --type ts 'TODO'
rg --type-list # see available types
# Search in hidden files / ignored files
rg --hidden --no-ignore 'API_KEY'
# Show matches with N lines of context
rg -C 3 'function deploy'
# Replace (preview)
rg 'oldName' --files-with-matches | xargs sed -i 's/oldName/newName/g'
# Or use the experimental --replace + --passthrough
rg 'oldName' --replace 'newName' --passthrough > preview.txt
fd — the replacement for find
What it does differently from find:
- Pattern is a regex (or with
-ga glob), no-namerequired. - Respects
.gitignore. - Colours output; parallel I/O.
- Smart-case: lowercase patterns are case-insensitive; mixed case is exact.
# Find by name
fd readme
# Find by extension
fd -e ts -e tsx
# Find & execute (one call per file)
fd -e py -x black {}
# Find & execute (one call with all results)
fd -e log -X rm
# Include hidden files / ignored files
fd --hidden --no-ignore
# Limit depth
fd -d 2 config.
bat — the replacement for cat
- Syntax highlighting for ~200 languages.
- Line numbers and git-diff annotations in the gutter.
- Falls back to plain cat when stdout is not a terminal (so pipes keep working).
bat src/main.rs
bat -p src/main.rs # plain output, useful in scripts
bat --diff main.rs # only show changed lines
# Use as the man-page pager
export MANPAGER="sh -c 'col -bx | bat -l man -p'"
eza — the replacement for ls
Successor to the older exa (which is unmaintained). What it does:
- Colours by file type, git status, permission bits.
- Tree view (
--tree) builtin — replaces the separatetreecommand. - Per-file git status when run in a repo.
eza -lah
eza --tree --git-ignore -L 3
eza -la --git --no-permissions --no-user --time-style=relative
The aliases worth setting:
alias ls='eza'
alias ll='eza -lah'
alias la='eza -la'
alias lt='eza --tree -L 2'
zoxide — the replacement for cd
zoxide tracks how often you visit directories and lets you jump to any of them by partial match:
# Add to ~/.bashrc or ~/.zshrc
eval "$(zoxide init bash)"
# or for fish:
zoxide init fish | source
# It defines a `z` command (and overrides `cd` only if you tell it to)
z proj # jumps to ~/code/big-project (your most-frecent match)
z proj api # narrows to ~/code/big-project/services/api
# Interactive picker
zi # opens an fzf picker of all known dirs
After a week of normal use, z + 3 letters reliably gets you anywhere. cd still works unchanged.
fzf — the universal fuzzy picker
Not a replacement for one thing — a primitive that composes with everything else. Pipe any list of items into it, fuzzy-search, pick:
# Pick a file to edit
nvim "$(fd -t f | fzf)"
# Pick a Git branch to switch to
git checkout "$(git branch | fzf | tr -d ' *')"
# Pick a recent command to re-run (default Ctrl-R binding)
# Pick a process to kill
kill -9 "$(ps -ef | fzf | awk '{print $2}')"
The shell key-bindings (run $(brew --prefix)/opt/fzf/install on Mac, apt install fzf sets it up on Debian) add three superpowers:
- Ctrl-R — fuzzy-search command history (replaces the default reverse-search).
- Ctrl-T — insert filename(s) from fuzzy picker at cursor.
- Alt-C — fuzzy-cd into a subdirectory.
The next tier worth knowing
- delta — a diff viewer that renders
git diffoutput with syntax highlighting and side-by-side. Configure ascore.pager. - dust — a replacement for
duwith a treemap-style output. - duf — a replacement for
dfwith cleaner formatting. - btop — a replacement for
top/htopwith mouse support, network/disk panels, and themes. - procs — a replacement for
pswith column auto-sizing and TCP/UDP port mapping. - just — a make-style command runner without the tab-quirk syntax.
- direnv / mise — per-directory environment variables (mise's variant covered in that tutorial).
Aliases worth keeping
# ~/.bashrc / ~/.zshrc
alias ls='eza'
alias ll='eza -lah --git'
alias la='eza -la'
alias lt='eza --tree -L 2 --git-ignore'
alias cat='bat -p' # paged when on a terminal, plain when piped
alias grep='rg' # keep the original under /usr/bin/grep
alias find='fd'
eval "$(zoxide init bash)"
[ -f /usr/share/fzf/key-bindings.bash ] && source /usr/share/fzf/key-bindings.bash
None of these break existing scripts that hardcode /usr/bin/grep or /usr/bin/find; the aliases only apply to interactive shells.