The core Unix commands — grep, cat, ls, find, curl — were written decades ago. They work. But modern rewrites (mostly in Rust) are faster, have better defaults, and respect things like .gitignore out of the box.
Here's every classic command and its modern replacement. Every tool links to its clihub listing with install commands.
grep → ripgrep
What changes: ripgrep recursively searches directories by default, respects .gitignore, skips binary files, and runs significantly faster than grep -r. Regex by default, multi-line search, and colored output.
Before:
grep -rn "TODO" --include="*.py" .
After:
rg "TODO" --type py
brew install ripgrep
cat → bat
What changes: Syntax highlighting for 100+ languages, line numbers, git diff markers in the gutter, and automatic paging for long files. Drop-in replacement — same arguments work.
Before:
cat src/main.rs
After:
bat src/main.rs
brew install bat
ls → eza
What changes: Color-coded file types, git status column, tree view built in, human-readable file sizes by default. A maintained fork of the now-abandoned exa.
Before:
ls -la
After:
eza -la --git --icons
brew install eza
find → fd
What changes: Simpler syntax, ignores hidden files and .gitignore by default, regex patterns, colorized output, and significantly faster on large directories.
Before:
find . -name "*.json" -type f
After:
fd "\.json$"
brew install fd
cd → zoxide
What changes: Learns your most-used directories and lets you jump with partial names. z proj goes to ~/code/my-project. After a few days of use, you never type full paths again.
Before:
cd ~/code/projects/my-project
After:
z proj
brew install zoxide
curl → xh
What changes: Syntax-highlighted JSON output, automatic content-type detection, shorter syntax for common operations. Think of it as curl with sensible defaults for API work.
Before:
curl -s -H "Content-Type: application/json" https://api.example.com/users | python3 -m json.tool
After:
xh get api.example.com/users
brew install xh
See also: httpie — another modern HTTP client, Python-based with a slightly different syntax.
sed → sd
What changes: Uses familiar string/regex syntax instead of sed's cryptic commands. No need to escape slashes or remember -i flag differences between macOS and Linux.
Before:
sed -i '' 's/foo/bar/g' file.txt
After:
sd 'foo' 'bar' file.txt
brew install sd
du → dust
What changes: Visual bar chart of disk usage, sorted by size, with directory depth control. Instantly shows what's eating space.
Before:
du -sh * | sort -rh | head -20
After:
dust
brew install dust
top → btm
What changes: CPU, memory, network, and disk I/O in a single graphical terminal UI. Written in Rust, lighter and more visual than htop.
Before:
top
After:
btm
brew install bottom
See also: htop (the classic improved top) and btop (another visual monitor).
diff → delta
What changes: Syntax-highlighted diffs with line numbers, side-by-side view, and git integration. Configure as your git pager and every git diff, git log -p, and git show looks better.
Before:
diff file1.txt file2.txt
After:
delta file1.txt file2.txt
brew install git-delta
man → tldr
What changes: Community-maintained practical examples instead of formal documentation. tldr tar gives you the 5 most common tar commands instead of a 4,000-line manual.
Before:
man tar
After:
tldr tar
brew install tldr
cut → choose
What changes: Simpler column selection with human-friendly syntax. No more counting field positions or remembering -d and -f flags.
Before:
echo "one two three" | cut -d' ' -f2
After:
echo "one two three" | choose 1
cargo install choose
df → duf
What changes: Colorized, table-formatted disk usage overview. Groups filesystems by type, shows usage bars, and is actually readable.
Before:
df -h
After:
duf
brew install duf
ps → procs
What changes: Colorized output, human-readable formatting, tree view of process hierarchy, and keyword search built in.
Before:
ps aux | grep node
After:
procs node
brew install procs
Quick Reference
| Classic | Modern | Language | Key Improvement |
|---|---|---|---|
grep | ripgrep | Rust | .gitignore aware, significantly faster |
cat | bat | Rust | Syntax highlighting, git markers |
ls | eza | Rust | Git status, icons, tree view |
find | fd | Rust | Simpler syntax, ignores .gitignore |
cd | zoxide | Rust | Learns directories, fuzzy matching |
curl | xh | Rust | Highlighted JSON, shorter syntax |
sed | sd | Rust | Normal regex, cross-platform |
du | dust | Rust | Visual bars, sorted by size |
top | btm | Rust | Graphs, lightweight |
diff | delta | Rust | Syntax highlighting, git pager |
man | tldr | Multi | Practical examples only |
cut | choose | Rust | Human-friendly column selection |
df | duf | Go | Colorized tables, usage bars |
ps | procs | Rust | Color, tree view, search |
You'll notice a pattern: almost everything is written in Rust. That's not a coincidence — Rust gives you C-level performance with memory safety, which is exactly what you want for tools that run thousands of times a day.
How to Switch
You don't need to replace everything at once. Start with these three — they give you the biggest daily improvement:
- ripgrep — you search code every day, and this is dramatically faster
- bat — you read files every day, and syntax highlighting helps
- fd — you find files every day, and the syntax is simpler
Then alias them in your shell config:
alias cat="bat"
alias ls="eza"
alias find="fd"
alias grep="rg"
alias du="dust"
alias df="duf"
alias ps="procs"
Browse all these tools and more on clihub — or see the full Best CLI Tools for Developers list.
Why Are All These Tools Written in Rust?
Eleven of the fourteen tools in this list are written in Rust. That's the defining pattern of the modern Unix movement.
Classic Unix tools were written in C. They're fast, but they're also 30-40 years old, with accumulated complexity and platform-specific quirks (try using sed -i on both macOS and Linux). Rust gives you the same performance with memory safety, modern error handling, and cross-platform consistency.
Rust also has excellent support for CLI argument parsing (via clap), colored terminal output, and cross-compilation. The result: these tools install as a single binary, run on every OS, and crash less than their C predecessors.
The Go tools on this list (like duf) follow a similar pattern — single binary, cross-platform, modern defaults. The common thread isn't the language, it's the philosophy: take a classic tool, keep the core purpose, and rebuild with modern defaults and better UX.
FAQ
Do modern Unix alternatives break existing scripts?
No. These tools don't replace the originals — they install alongside them. Your existing scripts that use grep, cat, and find keep working. The aliases in the section above only affect your interactive shell. If you want to be safe, alias with a different name: alias rg="ripgrep" instead of alias grep="rg".
Are these available on Linux, macOS, and Windows?
Most of them, yes. Rust and Go binaries are cross-platform by default. Tools like ripgrep, bat, fd, eza, and zoxide run on all three operating systems. A few (like duf) have minor differences on Windows. Check each tool's clihub listing for platform-specific install instructions.
What about exa vs eza?
exa was the original modern ls replacement, but its maintainer stopped updating it in 2023. eza is the community-maintained fork that continues active development. Use eza — it has all of exa's features plus ongoing bug fixes and new features.
Can I use these in Docker containers and CI/CD?
Yes. Since most are single binaries, they're easy to add to Dockerfiles or CI pipelines. For example, RUN curl -LO https://github.com/BurntSushi/ripgrep/releases/... or install via the distro package manager. Some tools like bat and eza are available in Alpine Linux's package repository.
Where can I find more tools like these?
clihub lists hundreds of command line tools across 15 categories — including all the tools in this article. You can also check the Best AI CLI Tools list for AI-powered alternatives.
All tools listed here are available on clihub — the directory for discovering command line tools.