I used to navigate my filesystem one directory at a time. cd ~/Projects, then ls, then cd websites, then ls, then cd jeffbaileyblog, then ls, then cd hugo. Every trip to a familiar directory cost me four or five commands. Tab-completion helped a little, but I still had to remember the path.
Then I installed zoxide, and cd started reading my mind.
What zoxide actually is
Zoxide is a smarter replacement for cd. It watches where you go in your terminal, ranks those directories by how often and how recently you visit them, and lets you jump to any of them by typing a fragment of the path.
Instead of cd ~/Projects/websites/jeffbaileyblog/hugo, I type z hugo. Zoxide remembers that I live in that directory most days, and it takes me there.
Ajeet D’Souza wrote it in Rust. It’s a single binary with no runtime dependencies. It works in bash, zsh, fish, PowerShell, nushell, and a handful of others. You install it once, add a line to your shell config, and z replaces cd for most of your navigation.
The word that matters here is “frecency,” a blend of frequency and recency. Zoxide doesn’t just track your most-visited directories. It weights recent visits more heavily than old ones, so the ranking adapts as your work shifts. The directory you lived in last quarter fades. The one you’ve been in all week rises to the top.
Why zoxide exists
Traditional cd treats every navigation as a fresh problem. You tell it exactly where to go, and it goes. It has no memory. It doesn’t care that you’ve visited ~/Projects/websites/jeffbaileyblog/hugo six times today. The seventh time, you still have to type it all out (or tab-complete through it).
That’s fine for directories you visit once. It’s wasteful for the ten or so directories you actually live in.
Zoxide started as a Rust rewrite of earlier tools. z came first, written in shell by Rupa Vedula. Then autojump in Python, and fasd as another shell-based variant. Each one had the same idea: the shell should learn where you go, and jumping should take one short command.
Zoxide took that idea and made it fast and portable. Rust gave it near-instant startup (a cold z resolves in microseconds on my machine). The single-binary distribution removed the dependency headaches that plagued the Python and shell versions. And the interface got simpler: one command (z) and one interactive variant (zi).
The mental model: frecency as your shell’s intuition
Zoxide’s core idea is frecency. Every time you cd into a directory, zoxide bumps that directory’s score. Over time, directories you visit a lot and recently float to the top of the ranking. Directories you visited months ago sink.
The ranking is the whole trick. When I type z hugo, zoxide scans its database for every directory whose path contains “hugo,” then returns the one with the highest frecency score. That’s almost always the one I want, because I go there daily.
Zoxide’s algorithm decays old visits using a simple formula. A visit today counts more than a visit yesterday, which counts more than a visit last month. The decay is gradual, so a directory you used heavily last quarter still shows up, but a directory you’ve been hitting all week outranks it.
This matches how humans actually use filesystems. I don’t visit 500 directories evenly. I cycle through ten or fifteen active projects, with the mix shifting every few weeks. Frecency captures that pattern directly.
How the commands work
Zoxide exposes two main commands: z for non-interactive jumps, and zi for interactive selection.
z: jump to the best match
z fragment searches your frecency database and jumps to the top-scoring directory that matches. You can pass multiple fragments to narrow further:
z hugo # jump to the best "hugo" directory
z blog what-x # jump to a directory matching both "blog" and "what-x"
z proj web # disambiguate between multiple projectsFragments don’t have to be contiguous in the path. z proj web matches ~/Projects/websites because both words appear in order. That matters when you have similar directory names across several roots.
If you type z with no argument, zoxide takes you home. If you type z - (a single dash), it takes you to the previous directory, just like cd -.
zi: interactive mode
zi opens an fzf-backed picker showing your top-ranked directories. You type to filter the list, arrow-key through the matches, and hit enter to jump.
I use zi when my query is ambiguous. If I type z config and zoxide sends me to the wrong config directory, I run zi config next, see the full list, and pick the right one. After that, zoxide learns my preference (the selected directory’s frecency bumps up) and z config goes to the correct place next time.
Zoxide and fzf: two filters that compose
Zoxide and fzf solve adjacent problems. Fzf filters any list interactively. Zoxide maintains a ranked list of directories. Put them together and you get the best of both: a small, relevant list of your most-used directories, filtered interactively.
This is what zi does under the hood. It asks zoxide for the ranked list, then pipes that list into fzf for picking. The mental model composes cleanly:
- Zoxide knows where you go.
- Fzf lets you pick from a list.
- Together they let you pick from where you go.
That’s why zoxide lists fzf as an optional dependency. Without fzf, zi falls back to a simpler picker. With fzf, zi feels like the fuzzy finder you’d build for shell navigation if you were designing one from scratch.
Setup in practice
Zoxide ships as a single binary, but it needs a shell hook to intercept cd and keep its database current. The install step is two lines in your shell config.
For zsh:
eval "$(zoxide init zsh)"For bash:
eval "$(zoxide init bash)"For fish, in ~/.config/fish/config.fish:
zoxide init fish | sourceMany people also alias cd to z, so every navigation feeds the frecency database:
eval "$(zoxide init zsh --cmd cd)"After that line, cd is z. The original cd still works for directories zoxide doesn’t know yet (it falls back when the query doesn’t match any ranked directory), and every directory you visit gets recorded.
I run with --cmd cd because I don’t want two navigation commands in my muscle memory. One command that gets smarter over time beats two commands that I have to remember to switch between.
What zoxide is not
Zoxide is not a file finder. It only tracks directories. If you want to find a file inside a directory, that’s fzf’s job, or find, or fd.
Zoxide is not a shell history tool. It doesn’t record commands, only navigation. Ctrl+R (or fzf’s history widget) handles command recall.
Zoxide is not a tool for exploring directories you’ve never visited. It can only rank directories you’ve been to at least once. The first visit still costs you a full cd with a real path, and tab-completion still matters for that first trip.
Understanding those boundaries helps. Zoxide is small on purpose. It does one thing (rank directories by frecency) and composes with other tools for everything else.
Common misconceptions
“Zoxide will mess up my muscle memory.” It won’t if you let it replace cd entirely. The problem comes from running z and cd side by side and switching based on whether you “think” zoxide knows the directory. Pick one, use it always, and your hands adapt within a week.
“Zoxide needs to index my whole filesystem.” No. Zoxide only records directories you actually visit. The database grows as you work, not up front. On a fresh install, zoxide knows nothing and stays out of your way until you’ve visited a few places.
“Zoxide is just another cd alias.” The frecency ranking is the whole point. Without the ranking, it would be a worse tab-completer. With the ranking, it predicts where you want to go from a fragment that would be ambiguous to any other tool.
“Zoxide replaces fzf.” It doesn’t. They solve different problems and compose naturally. Fzf filters lists. Zoxide produces a ranked list of directories. Use both.
Trade-offs and limitations
Zoxide is small and focused, but it has costs worth understanding.
It needs training time. A fresh install is useless. Zoxide gets better as you use it, with the real payoff arriving after a week or two of normal work.
Wrong matches happen. Early on,
z configmight send you to~/old-project/configinstead of~/current-project/configbecause the old one has more history. The fix is to usezionce to pick the right directory, which bumps its score, or to use--removeto delete stale entries.It’s shell-coupled. Zoxide works through shell hooks. If you use a terminal multiplexer or a non-interactive shell, some of the recording might miss. In practice this rarely matters, but worth knowing.
The database can grow. Over years, your frecency database accumulates directories you no longer care about. Zoxide provides
zoxide query -lto list ranked directories andzoxide removeto clean them out. I prune mine maybe once a year.It doesn’t work on fresh machines. Moving to a new laptop means starting from zero unless you copy over the database file. For most people that’s fine (rebuilding frecency is fast once you start working), but it’s a real cost.
The core idea
Zoxide solves a problem you probably don’t notice until someone points it out: you spend a surprising amount of terminal time typing paths you’ve already typed hundreds of times.
The mental model is a single sentence. Zoxide tracks where you go and lets you jump back with a fragment. The frecency ranking makes “the best match” almost always the one you wanted. The composition with fzf (through zi) handles the cases where it isn’t.
Once the database warms up, z replaces cd for most of my navigation. I still reach for cd when I’m exploring somewhere new, but for the ten directories I live in, one short command and a fragment gets me there.
Next steps
- Install zoxide from the official repository and add the init line to your shell config.
- Try aliasing
cdtozwith--cmd cdso every navigation trains the frecency database. - Pair zoxide with fzf if you haven’t already.
zibecomes a fuzzy directory picker that knows where you actually work. - Read about what fzf is to see how the two tools compose.
- Explore shell configuration for more terminal productivity patterns.
References
- zoxide official repository, the source, install instructions, and configuration docs by Ajeet D’Souza.
- z, the original shell-based frecency tool by Rupa Vedula that inspired zoxide.
- autojump, a Python-based predecessor with similar frecency semantics.
- fasd, another shell-based tool that tracks files and directories by frecency.
- What is fzf?, the fuzzy finder that zoxide uses for its interactive
zipicker.

Comments #