zoxide: a cd replacement that only knows where you have already been
GitHub describes it as A smarter cd command. Supports all major shells.. The repository metadata lists Rust as its primary language. The metadata lists the MIT license. This article stays within the project description and details documented in the GitHub repository README.
At a glance
- What is it?
- zoxide is a Rust cd replacement that ranks directories by how often you visit them and jumps there with z or zi. It covers every major shell, but its apt rows for Debian, Ubuntu, Raspbian and Parrot are struck out, and both interactive features need something you install separately.
- Who is it for?
- Adopt zoxide if you work in a fixed set of deep directories and can finish the shell init step, and skip it if you want a package manager to do the whole job, since the install table offers no apt route for Debian, Ubuntu, Raspbian or Parrot. Before you commit, install it on one machine and check the thing the documentation never states: how your shell loads init.fish or zoxide.plugin.zsh, because a binary on your PATH does not give you a z command.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 9 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 26, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Two fragments are an AND, and a trailing slash means a child directory
zoxide turns cd into a ranked lookup: you type a fragment of a path and it changes to the highest ranked directory that matches. The getting-started block draws the matching rules in three lines, and those three lines are the whole grammar.
z foo # cd into highest ranked directory matching foo
z foo bar # cd into highest ranked directory matching foo and bar
z foo / # cd into a subdirectory starting with fooTwo fragments are combined rather than alternated, so z foo bar needs a directory matching both words. That is how you reach a deep project folder without typing its full path. A trailing slash changes the meaning from any path component to a direct child. The same block folds ordinary cd into z, so z .., z - and z foo/ behave like the shell builtin you already type, which is the point: there is no separate navigation mode to learn, only a prefix that shortens what you would have written.
What the ranking does with the numbers lives elsewhere. The README links to a separate page for the matching algorithm, so score decay, tie handling and result ordering sit off this page. That gap has a consequence: when two directories match a fragment equally well, z foo moves you into one of them, and nothing above tells you which until you are already there.
init.fish and zoxide.plugin.zsh are part of the install, not an extra
A packaged binary on your PATH is not a working zoxide. The install guide counts four steps and the first one is the binary itself, which means the shell side has its own step that no package manager can do on your behalf. At the top level of the repository sit init.fish for fish and zoxide.plugin.zsh for zsh, next to src/, contrib/, man/ and templates/. Cargo.toml lists askama 0.16.0, a template engine, as a runtime dependency rather than a build-only one, so the integration files come from the project instead of being forked separately by each distribution.
The packaging metadata shows the cost of that split. The first three deb assets in Cargo.toml place the binary at usr/bin/ with mode 755, the bash completion at usr/share/bash-completion/completions/zoxide with mode 644, and the fish completion in usr/share/fish/vendor_completions.d/. A completion file tells your shell which arguments z accepts. It does not define z. Without the init step the command is simply absent, and the completion is decoration. So when you compare install routes, the honest question is not which one is faster but which one also gets the shell to load the integration file.
The Linux route pipes a GitHub script into sh, and the first jump is z foo
On Linux and WSL the recommended install is a single line that downloads install.sh from the project main branch and hands it to your shell:
curl -sSfL https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | shmacOS leads with package managers instead:
brew install zoxidewith port install zoxide, conda install -c conda-forge zoxide and nix-env -iA nixpkgs.zoxide also listed, and the same install script offered as the alternative. Windows goes through winget, and that section says zoxide works with PowerShell as well as shells running in Cygwin, Git Bash and MSYS2:
winget install ajeetdsouza.zoxideIf you would rather build it, or your platform has no package, the crate is published on crates.io and the install table gives one command for any distribution:
cargo install zoxide --lockedOnce the binary is in place and your shell has loaded the init file, these are the commands you will actually type:
z ~/foo # z also works like a regular cd command
z foo/ # cd into relative path
z .. # cd one level up
z - # cd into previous directoryA fresh machine will not have a ranking yet, so expect the first few calls to feel uninformative until the shell has recorded somewhere you have actually been.
Debian, Ubuntu, Raspbian and Parrot are struck out of the install table
Read the Linux table closely and four rows are drawn with strikethrough: Debian, Parrot OS, Raspbian and Ubuntu, each with its apt command crossed out and a footnote marker attached. The rows that are not struck out carry working commands, among them apk add zoxide for Alpine Linux 3.13+, pacman -S zoxide for Arch Linux, dnf install zoxide for Fedora 32+, emerge app-shells/zoxide for Gentoo, zypper install zoxide for openSUSE Tumbleweed, xbps-install -S zoxide for Void Linux, eopkg install zoxide for Solus, pacstall -I zoxide-deb for Rhino Linux and guix install zoxide for Guix. Devuan 4.0+ keeps its apt install zoxide.
If you are on Ubuntu, that row is your route map and it is crossed out. The package is not offered there through the channel this table describes, so your choice narrows to the install script, a source build with cargo install zoxide --locked, or a third party repository the project does not list. The same holds for Debian and Raspbian, which is a large share of the people who reach for apt first. A footnote marker is attached to all four rows, which suggests the removal is deliberate and explained in a note, but that note is not part of the table. Check what your own distribution ships before you plan around zoxide being one command away.
zi hands selection to fzf, and tab completion stops at three shells
The two interactive features both have prerequisites the project does not install for you. The first is selection with a picker:
zi foo # cd with interactive selection (using fzf)That line depends on fzf, a separate program. zoxide hands its list of candidate directories to fzf and fzf draws the interface, so the feature is only as usable as the fuzzy finder's own configuration and whether you have it installed at all. Nothing in the install guide and nothing in the Cargo.toml dependency list says what zi does when fzf is missing, so on a machine without it you are running a command with no described behaviour.
The second is completion:
z foo<SPACE><TAB> # show interactive completions (bash 4.4+/fish/zsh only)The parenthetical is a hard boundary, and it sits awkwardly next to the claim that zoxide works on all major shells. Completion through the shell is documented for bash 4.4 and newer, for fish, and for zsh. Every other shell gets the binary without that layer, and no fallback is named. If your shell is an older bash, this part of the install simply does not exist, and you find that out at the prompt rather than at install time.
A directory you have never entered cannot be jumped to
zoxide ranks what your shell has already recorded, so it has a cold start that the getting-started block does not warn you about. Until the shell has logged a path there is no entry for it, and a fragment match has no score to rank. The first z foo on a new machine, in a fresh container, or in a checkout you cloned this morning will not take you to the directory you meant. It will fail, or land somewhere you did not ask for, because nothing in the index points at a place you have never been.
The escape hatches are in the same block, and they are the lines most people skip:
z ~/foo # z also works like a regular cd command
z foo/ # cd into relative path
z .. # cd one level up
z - # cd into previous directoryz ~/foo is the one to remember. When the ranking has nothing useful, z degrades into a path-taking cd, so the tool never leaves you worse off than the builtin it replaced. That is the honest shape of the feature: it pays off on directories you visit constantly, and everywhere else it is a slower way to type a path. If you keep a second window for work directories you touch a few times a week, the scores those directories accumulate stay thin, and z keeps handing them back to the cd fallback.
cargo install zoxide --locked stops at rustc 1.88.0
Cargo.toml pins the toolchain floor in two lines. The edition is 2024 and rust-version is 1.88.0, so the source does not build on an older compiler and cargo install zoxide --locked only works where your Rust is 1.88 or newer. That is a real constraint on a distribution with a dated rustc in its repositories, and part of why the binary install path exists at all. The project enforces the floor rather than leaving it to chance, since the justfile lint job runs cargo msrv verify next to cargo clippy --all-features --all-targets -- -Dwarnings, mandoc over man/man1/*.1, shellcheck --enable all, markdownlint and yamlfmt. A repository gated that tightly is not going to be casual about a patch release either.
Windows carries one dependency the other platforms do not list:
[target.'cfg(windows)'.dependencies]
which = "8.0.2"Scoped to cfg(windows), a program resolution crate is compiled in only for Windows builds, which fits the install section naming PowerShell, Cygwin, Git Bash and MSYS2 as the shells supported there. Release builds also set debug = 0, strip = true, lto = true and codegen-units = 1, so the binary you install is stripped. If zoxide misbehaves on your setup, expect to reproduce it from source rather than pull symbols out of the installed copy.
No import path from z or autojump, and eight months between v0.9.8 and v0.9.9
The README names z and autojump as the projects zoxide is inspired by, and stops there. It does not set out what differs. What the repository shows is the shape of the approach: ranking runs inside a Rust binary, the shell integration ships with the project through init.fish and zoxide.plugin.zsh, and Cargo.toml lists no crate for reading either tool's data file. If you are coming from autojump or z, expect to begin with an empty ranking. There is no import step documented and no flag for one, so the learning period starts again from zero.
Maintenance is current. The repository is not archived, Cargo.toml carries a maintenance badge that reads actively-developed, and the last push was on 2026-09-21. The release cadence is slower than that badge suggests. v0.9.8 shipped on 2025-05-26, v0.9.9 on 2026-01-31, and v0.10.0 on 2026-07-04, so one gap between two of the three releases is eight months. The version field in Cargo.toml is 0.10.0, matching the newest tag, which puts main a little ahead of the last release. CHANGELOG.md is the file to read before you move past v0.10.0, and the licence is MIT, so dropping the binary into your own dotfiles carries no copyleft condition.
Editorial conclusion
Adopt zoxide if you work in a fixed set of deep directories and can finish the shell init step, and skip it if you want a package manager to do the whole job, since the install table offers no apt route for Debian, Ubuntu, Raspbian or Parrot. Before you commit, install it on one machine and check the thing the documentation never states: how your shell loads init.fish or zoxide.plugin.zsh, because a binary on your PATH does not give you a z command. If you already keep an autojump or z history, expect that ranking to be discarded rather than imported, and read CHANGELOG.md before you move past v0.10.0.
Frequently asked questions
What is zoxide?
It is a cd replacement written in Rust that remembers which directories you use most frequently and jumps to them in a few keystrokes. The README describes it as a smarter cd command inspired by z and autojump, and it says it works on all major shells.
How do I install zoxide on macOS?
macOS is listed with package managers rather than a preferred script: brew install zoxide, port install zoxide, conda install -c conda-forge zoxide, nix-env -iA nixpkgs.zoxide, or cargo install zoxide --locked. The same install script used on Linux is offered as the alternative.
How do I install zoxide on Ubuntu?
The Ubuntu row in the install table is struck through, as are the Debian, Raspbian and Parrot OS rows, so apt install zoxide is not offered there. The install script or a source build with cargo install zoxide --locked are the routes the table leaves you.
How do I use zoxide day to day?
Type z plus a fragment to move to the highest ranked matching directory, add a second fragment to require both words, and add a trailing slash to search direct children. z also accepts ordinary cd forms such as z .. and z -, and zi opens an interactive picker built on fzf.
How does zoxide compare with autojump and z?
The README names z and autojump as its inspiration without spelling out the differences. The repository shows that ranking runs in a Rust binary with shell integration shipped in the project, and no crate reads either tool's data file, so no import of an existing history is offered.
Is zoxide safe to use?
It keeps a local index of directories you have visited and the repository points at no network service. The step worth reading before running anything is the install line, since the recommended Linux route pipes a script fetched from GitHub straight into sh.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ajeetdsouza-zoxide)