A year ago I did the thing everyone eventually does: I swapped out a chunk of my Unix toolkit for the modern set that tops every "modernize your terminal" list. ripgrep for grep, fd for find, bat for cat, eza for ls, zoxide for cd, and delta as the diff pager. The aliases went into the dotfiles, and I waited to see what would survive contact with real work: incidents, laptop rebuilds, ssh into half-forgotten servers, and scripts that have to keep working while I sleep.
A year is long enough for muscle memory to cast its real vote. Hype tells you what is new; twelve months of daily use tells you what earned its keep. Here is the honest accounting, tool by tool, including the two replacements I quietly stopped using without ever uninstalling them.
The short version
- Kept for good: ripgrep (searching), fd (finding), zoxide (navigating), and delta (reviewing diffs). All four are permanent dotfiles fixtures now.
- Quietly dropped: bat left the interactive command line (it survived as the preview pager behind my file picker) and eza lost its aliases entirely (plain ls is fine, and ls is what every server you ssh into actually has).
- The pattern I did not expect: every tool that stuck changed the result of a command: what matches come back, where you land, whether you finish reading a diff. The tools that fell mostly changed how the same output looks.
- Everything below is one sysadmin's experience: no benchmarks, no timing runs, and no claim that your workflow owes them anything different.
What "one year later" actually measures
Adoption is easy to fake in week one, when everything is fast and colorful. A replacement faces three quieter tests:
- The rebuild test. When a laptop dies and you rebuild from dotfiles, is the tool on the list, or had you already forgotten it existed?
- The incident test. At 3am over ssh to a host with none of your tools, does your muscle memory break in a dangerous way?
- The script test. Anything you pipe or redirect has to keep behaving like the boring contract it replaced.
Notice the failure mode: nobody uninstalls a tool at the end of the year. The alias just stops being typed. That is what "quietly stopped using" means, and it is why the drops in this post have no dramatic stories attached, only drift.
ripgrep: the one that changed what searching costs
The old grep workflow always carried a setup cost: decide what to exclude, assemble flags to exclude it, and prune the results by hand. ripgrep deletes most of that setup with three behaviors that sound small and are not: it searches recursively by default, it respects .gitignore, and it skips hidden files and binary files unless you ask it otherwise, so the noise you spent years building flag pipelines to exclude (build output, dependency trees) simply never shows up.
The change I noticed after a year: I construct fewer searches. rg "listen_address" . in an unfamiliar source tree is now a genuinely good first move, in a terminal and in a one-off script alike, because the default answer is already the right one.
Verdict: kept unconditionally. Alongside fd, it is one of the two tools from this set that get installed on any host I will touch more than once, since a single static binary is a small ask for how often it gets used.
fd: the quiet win
find is powerful the way a manual lathe is powerful: you can do anything, and you pay for it every single time. My dotfiles used to carry small wrappers just to make find pleasant: skip directories, sort, print human sizes. fd replaced those wrappers, though not all through its defaults: recursion and the skipping of hidden and ignore-file entries (opt back in with --hidden or --no-ignore) are defaults, but a deterministic sort order and human-readable sizes are not, and fd's own help points at -l/--list-details, the ls -l style listing, when you want both.
Plain find keeps its seat for the jobs where its weirdness is the point: -perm tests, deeply nested boolean expressions, and filesystem plumbing where every option matters. fd even covers exec-style batches with its own -x and -X flags, so that is not find-only territory anymore either. fd did not replace find; it replaced needing find almost every day.
Verdict: kept unconditionally, and it shows up in cron-adjacent one-liners more than any other tool in this set, with one discipline: the same defaults that keep interactive noise down will silently skip gitignored and hidden files, which is the opposite of what automation wants. In scripts and cron I make the implicit filters explicit with fd --no-ignore --hidden (or rg -uu for the same posture in ripgrep), so a job that must see everything actually sees everything.
One portability footnote for those one-liners: on Debian and Ubuntu the apt package is fd-find and it installs the binary as fdfind, not fd, because of a name clash (bat hit the same wall as batcat on older releases, though newer ones ship plain bat). Anything you push to those hosts either calls the distro name or creates the usual symlink.
zoxide: the one that retrained twenty years of cd
The biggest single workflow change of the year, and the surprise of the exercise, because cd seemed too basic to replace. zoxide watches where you actually go, keeps a frecency-ranked database of directories, and hands you z, so z blog lands you where you meant instead of wherever muscle memory used to retype from the filesystem root.
The honest catch: for about a week it felt like skipping stairs in a house you know, and I reached for real cd on reflex. Then the retraining finished, and now the missing-tool feeling appears only on machines I do not control. cd survives in one specific role: paths I have never visited, which was always the case where the old habit worked hard anyway.
Verdict: kept on every machine I own, activated with one zoxide init line in the shell rc. It is purely interactive and never touches scripts, which is part of why it stuck.
delta: the one I did not know I needed
delta is a syntax-highlighting pager for git diffs. You configure it once in .gitconfig, and after that it applies to every repository on every machine that carries your git config; the catch is that the config travels and the binary does not. On a host without delta installed, git prints error: cannot run delta: No such file or directory and then, since git 2.46, aborts with fatal: unable to execute pager 'delta' (older git printed the error, dumped the full diff unpaged, and still exited 0). The failure is loud but honest: install the binary and the config you already carried starts working.
The pitch sounds cosmetic: side-by-side diffs, line numbers, highlighted syntax, n/N navigation between hunks. None of that is on by default, to be clear: side-by-side, line-numbers, and navigate are all opt-in settings, and the setup block at the end of this post turns on the one that earns its line first, navigate = true, which powers the n/N keys.
After a year I would argue the real product is review quality. Reading a two-thousand-line config refactor in the stock pager meant losing your place and eventually surrendering to an editor window. delta makes long diffs navigable, so I finish reading diffs I used to skim, and skim ones I used to ignore outright. For an admin reviewing other people's infrastructure changes, that is a real upgrade, not decoration.
Verdict: kept in .gitconfig, permanently. The best ratio of one hour of setup to a year of payoff in this whole exercise.
bat: a great pager wearing a cat costume
bat is good software: syntax highlighting, line numbers, git gutter marks, sane pager defaults. The drop has nothing to do with quality and everything to do with position. cat's contract in 2026 is dull and load-bearing: print what you were given, compose with everything, never editorialize. bat's entire reason to exist is to editorialize for humans, which is a different job.
So the verdict took a middle path.
A year in, my usage settled honestly: I read files in an editor or in a preview window, and when I cat something it is usually interleaved with other command output, where uniform plain text is right. bat kept the one job where its strengths pay in full: the preview pane of the file picker, where syntax highlighting is worth real seconds. The naked command went back to cat.
Verdict: demoted, not fired.
eza: the quiet drop that taught me the lesson
First the facts, because this family has history: eza is the community-maintained fork of exa, which stalled, and the fork itself is healthy and actively shipping (v0.23.5 was the newest release when I checked; the checked date sits in the version block at the end of this post). Nothing that follows is a complaint about eza's upkeep.
The drop is about me and ls. eza's features are real: aligned sizes, human dates, git status inside eza -l --git, --tree. For the first month I enjoyed the listings. Then three frictions quietly won. Every server I touch carries only ls, so the alias atrophied into something I typed on exactly one machine. Plain ls already showed me what needed showing, and the beauty upgraded nothing but screenshots. And the one command I actually wanted enough to type, directory trees, was a different tool I already had.
Verdict: quietly dropped. The lesson generalizes: an alias that does not travel with you is a usage you will not keep. Tools that demand one are tools you slowly stop invoking on exactly the hosts where you work most.
What the survivors have in common
Four keepers and two drops split cleanly along one seam:
- They change outcomes, not presentation. ripgrep changes which matches come back. fd changes which files match. zoxide changes where you are. delta changes whether long diffs get read to the end. bat and eza sit on the other side of that line, with one honest concession: bat's git gutter and
eza -l --git's status column do surface information plain cat and ls never show. It just was not information that changed what I did next, so the answer itself stayed the same, only prettier. - They stay off the interactive/scriptable seam. rg and fd behave identically in a terminal and in a pipeline. zoxide is interaction-only and comfortable about it. bat and eza straddle both worlds, which is precisely where replacements die quietly.
- They survive the bare server. ripgrep and fd get installed on any host I will touch more than once; zoxide and delta still need their binaries installed per machine, but all of their configuration lives in files that already travel with me (shell rc, .gitconfig). Until that install happens, the traveling
zoxide initline throwscommand not foundat every login, the same config-without-binary failure delta has, which is why the line in my rc is guarded:command -v zoxide >/dev/null && eval "$(zoxide init bash)". After the guard, a new box really is one package install and nothing else. Nothing I kept demands that the whole fleet change.
The scorecard after one year
Tool | Replaces | After one year | The reason |
|---|---|---|---|
| grep | Kept unconditionally | Changes the result: recursion and .gitignore respect mean the first answer is the right one |
| find | Kept unconditionally | Sane defaults for daily finds; find keeps the odd jobs like perm tests |
| cd | Kept on machines I own | Frecency jumping replaced path typing; cd survives for new paths |
| the stock git diff pager | Kept in .gitconfig | Config rides in .gitconfig; long diffs finally get read to the end |
| cat | Demoted to file previews | Plain cat keeps the contract pipes and scripts lean on |
| ls | Quietly dropped | Prettier rendering, same answer, and every server still only speaks ls |
The setup that stuck
Config is the line between a toy and a tool. Here is the entire delta and zoxide setup that survived the year:
$ git config --global core.pager delta
$ git config --global interactive.diffFilter "delta --color-only"
$ git config --global delta.navigate true
$ git config --global merge.conflictstyle zdiff3
$ echo 'command -v zoxide >/dev/null && eval "$(zoxide init bash)"' >> ~/.bashrc
$ z blog
/home/deploy/src/blogThe honest limits
- No benchmarks in this post. Every claim here is about usage survival, not speed. If speed decides your adoption, run your own stopwatch on your own hardware and trust that result.
- A sample size of one. One workstation, a handful of homelab boxes, and assorted rented servers. A GUI-heavy team or an editor-centric workflow may rank these differently and be right.
- Snapshot, not a contract. The versions in the verified block below were read from the projects' release pages on 2026-10-29; I did not check current bat and delta release numbers for this draft.
- Your shell votes too. zoxide's payoff assumes you navigate in a terminal. If you mostly jump between editor panes and open folders by GUI, its value legitimately lands elsewhere.
- ripgrep
15.2.0 - fd
10.5.0 - zoxide
0.10.0 - eza
0.23.5
FAQ
Would you still install the full starter pack today?
Half of it. ripgrep and fd are nearly free: minimal retraining, immediate payoff, and they carry into scripts cleanly (with the ignore-file caveat above). delta is even cheaper in a different way: it is a pager; it never appears in scripts at all; it just makes every interactive diff better once its config lands. zoxide is the highest-value change of the year but costs roughly a week of muscle-memory investment, so it deserves a deliberate yes. bat and eza are fine software, but I would frame them as experiments now, not replacements, and watch honestly whether the habits move at all.
Is eza abandoned?
No, and the confusion is understandable. The original exa is unmaintained; eza is the maintained community fork and was actively shipping as of October 2026. Older articles calling exa "the modern ls" describe a stalled project. eza carried the flag onward.
Why drop bat if it is high quality?
Because quality was never the question; the job was. cat's contract (dumb, byte-exact, always composable) is what pipes and scripts lean on. bat is optimized for human reading. Both jobs are real; they are simply not the same job. The resolution kept bat for reading and cat for everything else.
What did fd actually replace, given find still exists?
The daily cases: pattern finds, extension filters, quick listings. find stays for the work where its power is the point, such as -perm tests, complex boolean expressions, and permission-scoped deletions. The win is small to describe and large to feel: one syntax to hold in your head on almost every day, two only for the odd jobs.
How do you handle hosts without your tools?
The one rule the year produced: muscle memory must survive a bare server. The stock verbs (cd, ls, cat, grep) stay load-bearing, and the modern tools position themselves as enhancements, not dependencies. One worry turned out smaller than it sounds: bash does not expand aliases in non-interactive scripts by default, so an interactive alias cannot silently leak into a script. The real failure mode is a script calling rg or fd directly on a host where the binary was never installed, which is why anything scheduled on machines I do not own sticks to the stock verbs.
Further reading
- ripgrep: https://github.com/BurntSushi/ripgrep
- fd: https://github.com/sharkdp/fd
- zoxide: https://github.com/ajeetdsouza/zoxide
- delta: https://github.com/dandavison/delta
- bat: https://github.com/sharkdp/bat
- eza: https://github.com/eza-community/eza
If you ran the same swap a year ago, I want the other half of the ledger: which replacement did you quietly stop using, and did your falls break along the same presentation-versus-outcome line? Drop it in the comments.
Until next time, keep your systems thoughtful.

No comments yet