Almost every classic Unix tool now has a Rust or Go rewrite that is faster, colourised, and subtly incompatible. The incompatibility is the part nobody warns you about: alias grep=rg will break scripts, because rg skips gitignored and hidden files by default. Below is what each tool replaces, the flag that justifies installing it, and whether it is safe to alias over the original.
| Tool | Replaces | Flag worth knowing | Binary | Safe to alias? | Licence |
|---|---|---|---|---|---|
| ripgrep (rg) | grep -r | -t py, -uu, --json | ~5 MB | No, ignores gitignored and hidden files | MIT or Unlicense |
| fd | find | -e ts, -x cmd {} | ~3 MB | No, matches the basename with a regex, not a glob | MIT / Apache-2.0 |
| bat | cat | --style=plain --paging=never | ~5 MB | Yes, with those two flags baked into the alias | MIT / Apache-2.0 |
| eza | ls | --git, --tree --level=2 | ~2 MB | Mostly, but column order and -1 behaviour differ | MIT |
| zoxide | cd | --cmd cd, then zi for a picker | ~1 MB | Yes, it falls through to real cd on a literal path | MIT |
| dust | du -sh * | -d 1, -r | ~2 MB | No, output is a bar chart and unparseable | Apache-2.0 |
| ncdu | interactive du | -x to stay on one filesystem | under 1 MB | n/a, it is a TUI | MIT |
| btop | top / htop | + / - to fold process trees | ~2 MB | Yes | Apache-2.0 (htop is GPL-2.0) |
| jq | grep on JSON | -r raw output, -e exit code | ~1 MB | n/a | MIT |
| delta | the git diff pager | --side-by-side --line-numbers | ~7 MB | Yes, set core.pager in gitconfig | MIT |
| sd | sed s/// | -p to preview before writing | ~2 MB | No, it uses normal regex instead of BRE | MIT |
| fzf | nothing, it wraps everything | --preview, --multi, --bind | ~4 MB | n/a | MIT |
Sizes are approximate for a stripped x86-64 build; distro packages with debug symbols run larger. All twelve together are still under 40 MB, which is less than one Electron app.
Four: bat, eza, btop and delta. The rest change semantics enough that shadowing the original name will eventually cost you an afternoon. If you do want cat to mean bat, pin the flags so piped output stays clean:
alias cat='bat --style=plain --paging=never'
alias ll='eza -l --git --group-directories-first'
eval "$(zoxide init bash --cmd cd)"
git config --global core.pager 'delta --side-by-side'
Remember that aliases do not apply in scripts or in non-interactive shells, so a Makefile calling grep is unaffected. That is a feature, not a limitation.
Every other tool on the list makes an existing command nicer. fzf makes commands you never wrote. Bound to Ctrl+R it turns shell history into a fuzzy search, which alone replaces most of what people use a notes file for. Pipe anything into it and you get a picker: git branch | fzf | xargs git checkout, or fd -e md | fzf --preview 'bat --color=always {}'. Set FZF_DEFAULT_COMMAND='fd --type f --hidden --exclude .git' and its file widget stops crawling node_modules.
bash 5.x is the safe default and the one your servers have. zsh is the macOS default; its advantage is completion quality plus a plugin ecosystem you should be sparing with, since each plugin adds startup latency you feel on every new tab. fish has better defaults out of the box but is deliberately not POSIX-compatible, so half the snippets you paste from the internet fail. nushell treats command output as typed tables, which is excellent for data wrangling and a poor fit for other people's install scripts. Interactive shell and scripting shell need not be the same program: keep #!/usr/bin/env bash at the top of every script regardless.
tmux is the default answer: packaged everywhere, scriptable (tmux new-session -d -s api 'npm run dev'), and its config is portable across a decade of machines. The cost is that nothing is discoverable, so budget an hour with a cheat sheet. zellij inverts that: a keybinding hint bar at the bottom, declarative layout files, floating panes out of the box, at the price of a heavier binary that is absent from most servers you SSH into. screen is a fallback for the locked-down box where nothing else exists; learn screen -r and stop. The win is the same either way: a long build survives a dropped SSH session.
Distro repositories lag badly here; the Debian package for ripgrep or bat is often a major version behind. Homebrew, mise, or plain static binaries dropped into ~/.local/bin all beat waiting for the distro. Know the two naming traps: on Debian and Ubuntu bat installs as batcat and fd as fdfind, because those names were taken. Symlink them once and your dotfiles stay identical across machines. For the base commands these replace, the CLI tools guide covers the fundamentals.