← All articles
CLI Zoxide: The Smarter cd Replacement That Learns Your ... 2026-02-15 · 6 min read · cli · zoxide · rust

Zoxide: The Smarter cd Replacement That Learns Your Habits

CLI 2026-02-15 · 6 min read cli zoxide rust terminal productivity navigation

Zoxide: The Smarter cd Replacement That Learns Your Habits

You know the routine. You need to get to a project directory buried three or four levels deep, so you start typing cd ~/projects/work/acme-corp/backend/services/auth-service and lean on Tab to autocomplete each segment. Or maybe you keep a mental map of your directory structure and still fat-finger the path halfway through. If you work across multiple projects, the friction compounds -- you're burning keystrokes and attention on something your computer should already know.

Zoxide solves this by learning where you go. It's a Rust-based cd replacement that tracks the directories you visit, ranks them by how frequently and recently you use them (a concept called "frecency"), and lets you jump to the right place with a short fuzzy query. Type z auth and you land in that auth-service directory without spelling out the full path. It works on Linux, macOS, and Windows, supports every major shell, and has earned over 6,000 stars on GitHub for good reason.

Zoxide Smart Navigation

Why Zoxide Over Plain cd

Plain cd is stateless. Every invocation starts from zero -- it doesn't know or care that you visit ~/projects/acme/backend fifty times a day. You type the same paths over and over. Shell history helps a little (cd then arrow-up), but it's fragile and linear.

Zoxide adds memory. After a few hours of normal work, it has a ranked database of your directories. From that point on, partial matches are usually enough. z acme jumps to ~/projects/acme. z back jumps to ~/projects/acme/backend. If there are multiple matches, zoxide picks the one with the highest frecency score. If that's wrong, you refine: z acme back narrows it down.

The friction reduction is small per invocation but massive over a day. It's one of those tools that changes how you move through your filesystem.

How Frecency Works

Zoxide borrows the frecency algorithm from Firefox's address bar (and before that, Mozilla's Places database). Frecency is a portmanteau of "frequency" and "recency" -- directories you visit often get a high score, but directories you visited recently get a temporary boost.

The practical effect:

Zoxide stores this data in a simple SQLite database. The database stays small (a few KB even with thousands of entries) and queries are effectively instant.

Installation

Zoxide is available through most package managers:

# macOS
brew install zoxide

# Fedora
sudo dnf install zoxide

# Ubuntu/Debian (22.04+)
sudo apt install zoxide

# Arch Linux
sudo pacman -S zoxide

# From source via Cargo
cargo install zoxide --locked

# Windows (Scoop)
scoop install zoxide

# Windows (winget)
winget install zoxide

After installing the binary, you need to initialize it in your shell. This is the step most people forget.

Shell Integration

Add the appropriate init line to your shell configuration file. This sets up the z and zi commands.

# Bash (~/.bashrc)
eval "$(zoxide init bash)"

# Zsh (~/.zshrc)
eval "$(zoxide init zsh)"

# Fish (~/.config/fish/config.fish)
zoxide init fish | source

# Nushell (~/.config/nushell/env.nu)
zoxide init nushell | save -f ~/.zoxide.nu
# Then source it in config.nu:
# source ~/.zoxide.nu

# PowerShell ($PROFILE)
Invoke-Expression (& { (zoxide init powershell | Out-String) })

By default, zoxide creates the z command as the smart jump and zi as the interactive picker. If you want to replace cd entirely, pass the --cmd cd flag:

eval "$(zoxide init bash --cmd cd)"

This replaces cd itself, so cd foo becomes a frecency-powered jump. Purists may prefer keeping z separate so cd retains its standard behavior.

Key Commands

Once initialized, you get three main tools:

# Jump to the highest-ranked directory matching "foo"
z foo

# Jump using multiple keywords (all must match path segments)
z proj backend

# Interactive selection (requires fzf)
zi

# Interactive selection with a query pre-filled
zi backend

# Add a directory to the database manually
zoxide add /path/to/directory

# Remove a directory from the database
zoxide remove /path/to/directory

# List all tracked directories with scores
zoxide query --list

# Find the top match without jumping (dry run)
zoxide query foo

# Show the database path
zoxide query --list | head -1  # entries are in _ZO_DATA_DIR

The z command handles the common case: you know roughly where you want to go. The zi command handles the ambiguous case: you want to see the candidates and pick one.

Pairing with fzf

Zoxide's zi command uses fzf (if installed) to present an interactive fuzzy-search interface over your directory database. This is where zoxide becomes truly powerful.

# Install fzf if you haven't
brew install fzf       # macOS
sudo apt install fzf   # Debian/Ubuntu
sudo dnf install fzf   # Fedora

With fzf installed, zi opens a full-screen picker showing all tracked directories ranked by frecency. You type to filter, arrow keys to select, Enter to jump. It's the same interaction model as fzf for file selection, but scoped to directories you've actually used.

You can also pipe zoxide's output into other tools:

# Open a project in your editor by frecency
code "$(zoxide query -l | fzf)"

# cd into a directory and immediately list contents
z proj && ls

Comparison: Zoxide vs the Alternatives

Zoxide isn't the first tool in this space. Here's how it stacks up against the older options:

Feature zoxide autojump z.lua z (rupa/z) fasd
Language Rust Python Lua Shell Shell
Speed Very fast Slow on large DBs Fast Fast Moderate
Algorithm Frecency Frecency Enhanced frecency Frecency Frecency
Shell Support bash, zsh, fish, nu, pwsh bash, zsh, fish bash, zsh, fish, pwsh bash, zsh bash, zsh
fzf Integration Built-in (zi) Plugin Built-in No No
Windows Support Yes Partial Yes No No
Active Maintenance Yes (2024+) Minimal Occasional Archived Abandoned
Database SQLite Flat file Flat file Flat file Flat file
import from others Yes N/A N/A N/A N/A

The verdict: If you're starting fresh, use zoxide. It's faster, better maintained, supports more shells, and the fzf integration is first-class. If you're migrating from autojump or z, zoxide can import your existing database:

# Import from autojump
zoxide import --from autojump /path/to/autojump/db

# Import from z (rupa/z or zsh-z)
zoxide import --from z /path/to/z/data

Configuration

Zoxide is configured through environment variables. Set these before the eval "$(zoxide init ...)" line in your shell config.

# Change where the database is stored (default: platform-specific data dir)
export _ZO_DATA_DIR="$HOME/.local/share/zoxide"

# Print the matched directory before jumping (useful for debugging)
export _ZO_ECHO=1

# Exclude directories from tracking (colon-separated, supports globs)
export _ZO_EXCLUDE_DIRS="$HOME:$HOME/Downloads:/tmp/*"

# Maximum number of entries in the database (default: 10000)
export _ZO_MAXAGE=10000

# Resolve symlinks before storing paths
export _ZO_RESOLVE_SYMLINKS=1

# Use fzf options for zi (customize the picker appearance)
export _ZO_FZF_OPTS="--height 40% --reverse --border"

The most useful of these is _ZO_EXCLUDE_DIRS. By default, zoxide tracks every directory you visit, including $HOME itself (which isn't useful as a jump target since you can just type cd). Excluding home, downloads, and tmp keeps your database focused on project directories.

Tips and Workflows

Bootstrap your database faster

Zoxide only learns directories you've visited since installation. If you want to seed it with your project directories immediately:

# Add all git repos under ~/projects
fd -t d '.git$' ~/projects -x zoxide add {//}

# Add specific directories manually
zoxide add ~/projects/acme ~/projects/personal/blog ~/dotfiles

Use z for project switching

The highest-leverage use of zoxide is jumping between projects. If you work on three or four repos regularly, z acme, z blog, z infra becomes muscle memory within a day.

Combine with tmux or Zellij

If you use a terminal multiplexer, zoxide's database is shared across all panes and sessions. Jump to a project in any pane and the frecency update applies everywhere.

Debug unexpected matches

If z foo is jumping to the wrong directory, check the scores:

zoxide query --list | grep -i foo

You'll see the score next to each path. If an old directory is outranking the one you want, remove it:

zoxide remove /old/path/to/foo

Alias for common patterns

# Quick project opener: jump and open in editor
zc() { z "$@" && code . }

# Jump and list
zl() { z "$@" && ls -la }

The Bottom Line

Zoxide does one thing and does it exceptionally well: it eliminates the tax of typing full directory paths. The frecency algorithm means it gets smarter the more you use it, and the fzf integration covers the cases where you're not sure exactly what you're looking for. Installation takes two minutes, configuration is optional, and it works on every platform and shell you're likely to use. If you haven't replaced cd with something smarter yet, zoxide is the one to pick.