CLI Toolbox
These tools are basically common knowledge now, but the specific aspects that truly change daily workflows are often more nuanced than just "faster X." Let's go through the features I use every day.
rg (ripgrep) replaces grep — The biggest difference isn't speed, but defaults: it automatically respects .gitignore/.ignore, skips hidden files and binaries, so searching within a repo always hits only the source code you care about, without being drowned out by node_modules or target/. To also search ignored files, add -uu (add another u to include binaries). Commonly used flags include -t rust to filter by file type, -g '*.toml' for glob patterns, -A/-B/-C for context, and rg foo -r bar to preview replacements. It's fast because Rust's regex engine uses finite automata + multithreading + skipping irrelevant content, not brute force.
fd replaces find — fd pattern directly performs smart-case regex matching on filenames, sparing you from memorizing the find . -name '*.x' -type f syntax; it also respects .gitignore by default (-H to include hidden files, -I to ignore .gitignore). The real convenience lies in -x/-X for batch execution: fd -e jpg -x convert {} {.}.png runs in parallel for each result, while -X feeds all results at once to a single command.
bat replaces cat — Syntax highlighting is just the surface; it also shows git add/delete gutters next to line numbers and auto-paginates (using less). Crucially, it is pipe-safe: once it detects that output is not a terminal, it automatically falls back to plain cat, preventing escape codes from polluting downstream processes. So using it as an alias for cat is zero-friction, and it can also serve as the rendering backend for MANPAGER (bat -l man) and fzf previews.
eza replaces ls — eza -l --git --icons displays each file's git status directly in the list, and --tree --level=2 acts as tree while respecting .gitignore. I've replaced my entire ls family (ls/ll/tree) with it; specific aliases are in the Zsh post.
zoxide makes z jump directories — It maintains a directory table sorted by frecency (frequency × recency). z dow jumps to your most frequently visited Downloads directory, z foo bar narrows matches with multiple keywords, and zi brings up an interactive fzf selector. It learns entirely from your cd history, requiring no manual path configuration.
just acts as make in projects — It is not a build system: no file dependency graphs, no timestamp checks; it's simply a "project command alias table." Write those long, hard-to-remember commands as recipes, and run them with one line like just deploy or just test --release. It supports variables, .env files, and allows specifying shebangs for individual recipes to write them in other languages. It's less hassle than Makefiles because there's no tab hell, no .PHONY pitfalls, and no implicit rule traps.
fastfetch / tldr — The former is a faster neofetch, great for screenshotting system info; the latter provides practical examples for commands (tldr tar directly shows the most common usages), which is much faster than reading the full flag list in man pages, with offline caching.
Among these, bat, eza, and fzf also serve as the backend for Zsh completion previews.
The one thing truly worth spending a few minutes configuring is git's diff. I use delta:
[core] pager = delta
[interactive] diffFilter = delta --color-only
[delta] navigate = true # n / N to jump between files
line-numbers = true
[merge] conflictStyle = zdiff3
[diff] colorMoved = default
Two settings make a significant difference. zdiff3 changes merge conflict markers from "side-by-side" to "three-way" — it displays an additional common ancestor section, making it immediately clear who changed what, reducing the effort needed to resolve conflicts. colorMoved gives moved blocks of code distinct coloring, preventing "relocation" from being misread as "rewrite" during code review. Using delta with lazygit makes viewing diffs in the terminal more comfortable than on the web.