Jump between directories with zoxide

Install zoxide, load it in bash, zsh or fish, jump with z and zi, import your autojump or z history, and replace cd with --cmd cd.

how-to7 steps

Updated

in short

Install zoxide, add zoxide init to the end of your rc file, then type z plus part of a directory name. Add fzf for the zi picker, and use --cmd cd if you want zoxide behind the plain cd command.

zoxide records the directories you visit and ranks them by how often and how recently you used them. z proj then jumps to the highest-ranked directory matching "proj", wherever it is.

This guide installs it for bash, zsh and fish, covers the z and zi commands, imports history from autojump or z, and shows how to make cd itself use zoxide.

Tools used

Before you start

  • bash, zsh or fish (zoxide also supports PowerShell, elvish, tcsh, xonsh, any POSIX shell and others)
  • A package manager such as Homebrew, pacman, dnf or winget, or curl for the install script
  • fzf 0.51.0 or newer if you want zi and interactive completions

Steps

  1. Step 1: Install zoxide

    Install it from your package manager or with the project's install script. The project advises against the Debian and Ubuntu apt packages because they lag far behind; use the script on those distributions.

    sh
    # macOS or Linux with Homebrew
    brew install zoxide
    
    # Arch Linux
    sudo pacman -S zoxide
    
    # Any Linux, macOS or WSL, official install script
    curl -sSfL https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | sh
    sh
    # Windows
    winget install ajeetdsouza.zoxide
  2. Step 2: Load zoxide in your shell

    Add the line for your shell to the end of its rc file. In zsh it must come after compinit, or completions will not work.

    bash
    # ~/.bashrc
    eval "$(zoxide init bash)"
    zsh
    # ~/.zshrc
    eval "$(zoxide init zsh)"
    fish
    # ~/.config/fish/config.fish
    zoxide init fish | source
  3. Step 3: Jump with z

    Open a new shell and keep using cd for a while so zoxide can learn your directories. It adds a directory every time you change into it. Then use z with one or more keywords. Matching ignores case, every keyword has to appear in the path in order, and the last keyword has to match the final directory name, so z bar finds /foo/bar but not /bar/foo.

    z also accepts normal paths, .. and -, so you can use it in place of cd for everything.

    sh
    z proj          # highest-ranked directory matching "proj"
    z work api      # matches "work" and then "api"
    z ~/code        # a normal path, like cd
    z ..            # one level up
    z -             # previous directory
  4. Step 4: Pick interactively with zi

    Install fzf, then run zi with an optional keyword to choose from every match in a fuzzy list. In bash 4.4+, zsh and fish you can also type z proj followed by a space and Tab to get the same picker as a completion.

    sh
    brew install fzf
    sh
    zi proj
  5. Step 5: Import history from autojump or z

    If you used another directory jumper, import its data so you do not start from zero. zoxide 0.10.0 and newer find the data file on their own; supported sources are autojump, z, zsh-z, z.lua, fasd and atuin. Add --merge if your zoxide database already has entries, otherwise the import stops with an error.

    Older releases (0.9.x) take the source as --from and need the data file path, and only support autojump and z.

    sh
    # zoxide 0.10.0+
    zoxide import autojump --merge
    zoxide import z --merge
    sh
    # zoxide 0.9.x
    zoxide import --from z ~/.z --merge
  6. Step 6: Replace cd with --cmd cd

    The --cmd flag renames the commands. --cmd cd makes cd the jumping command and cdi the interactive one, so existing habits and scripts that call cd in your interactive shell go through zoxide. Change the init line you added in step 2.

    --cmd j would give you j and ji instead.

    bash
    # ~/.bashrc
    eval "$(zoxide init --cmd cd bash)"
    zsh
    # ~/.zshrc
    eval "$(zoxide init --cmd cd zsh)"
    fish
    # ~/.config/fish/config.fish
    zoxide init --cmd cd fish | source
  7. Step 7: Inspect and clean the database

    zoxide query shows what zoxide has learned. Use zoxide remove for directories you never want to jump to. To keep directories out entirely, set _ZO_EXCLUDE_DIRS (colon-separated globs on Linux and macOS) before the init line.

    sh
    zoxide query --list --score proj
    sh
    zoxide remove ~/old/project
    sh
    export _ZO_EXCLUDE_DIRS="$HOME:$HOME/private/*"

Troubleshooting

  • zoxide: no match found: the directory is not in the database yet. cd into it once, or run zoxide add <path>.
  • zsh prints "zoxide: detected a possible configuration issue": something after the init line replaced zoxide's hook. Move eval "$(zoxide init zsh)" to the very end of ~/.zshrc.
  • Tab completion does nothing in zsh: the init line runs before compinit. Move it below, then run rm ~/.zcompdump*; compinit to rebuild the cache.
  • zi fails or shows no picker: fzf is missing or older than 0.51.0. Check with fzf --version.
  • zoxide import autojump is rejected: your zoxide is older than 0.10.0. Use the --from form with the data file path, or upgrade.

Tips

  • _ZO_ECHO=1 prints the matched directory before z jumps to it.
  • _ZO_FZF_OPTS passes extra options to fzf for zi. Like the other _ZO_ variables, set it before zoxide init.
  • Several file managers and terminal session managers read the zoxide database, so the same ranking follows you there.

Also worth a look

  • atuinShell history tool; zoxide 0.10.0+ can import directories from its database.
  • yaziFile manager with built-in zoxide support for jumping to ranked directories.

FAQ

Does --cmd cd break scripts that use cd?
Not in bash or zsh: scripts run in a non-interactive shell that does not read ~/.bashrc or ~/.zshrc. fish reads config.fish for scripts too, so put the init line inside an if status is-interactive block.
Where does zoxide store its database?
In $XDG_DATA_HOME or ~/.local/share on Linux, ~/Library/Application Support on macOS and %LOCALAPPDATA% on Windows. Set _ZO_DATA_DIR before zoxide init to change it.
Do I need fzf?
Only for zi and the Space-Tab interactive completions. The z command works without it.

related