Zsh’s z plugin lets you jump to directories you’ve visited frequently.

Here’s z in action. Imagine you’ve cd’d into a few nested directories.

$ cd ~/projects/my-awesome-app/frontend/src/components
$ cd ../../utils
$ cd ~/docs/notes/project-x/meeting-notes
$ cd ~/projects/my-awesome-app/backend/services

Now, you want to go back to the frontend/src/components directory. Instead of typing the full path, you can just type z followed by a part of the path you remember.

$ z components

And just like that, you’re there:

~/projects/my-awesome-app/frontend/src/components$

z works by maintaining a database of directories you’ve visited, weighted by how often and how recently you’ve been there. When you type z <partial_path>, it searches this database for the best match. The "best match" is determined by a scoring algorithm that prioritizes directories that appear later in the path (like components in frontend/src/components) and those you’ve visited more recently or more frequently.

The core concept is "frecency" – a combination of frequency and recency. z uses a simple scoring mechanism. Each time you cd into a directory, its score increases. The score decays over time, meaning older entries have less weight. When you search, z calculates a score for each known directory based on how well it matches your input and its current frecency. The directory with the highest score is selected.

The primary lever you control is the input you provide to z. Shorter, more specific inputs tend to yield better results. For example, z awesome might be too broad if you have multiple projects with "awesome" in their name. z my-awesome-app is better. z frontend is even more precise if that’s your target.

You can also configure z to include or exclude certain directories, or to change how it scores entries. The configuration is usually done in your .zshrc file.

# Example zshrc configuration for z
# Set the data file path (optional, defaults to ~/.zsh_history)
# export _Z_DATA="${ZDOTDIR:-$HOME}/.zsh_data/z"

# Set the number of days to keep history (optional, defaults to 30)
# export _Z_MAX_AGE=365

# Set the maximum number of entries to keep (optional, defaults to 5000)
# export _Z_MAX_COUNT=10000

# Add directories to exclude from tracking (optional)
# export _Z_EXCLUDE_DIRS=(/tmp/* /var/log/*)

The z plugin itself keeps a file (often ~/.zsh_history or a dedicated file like ~/.zsh_data/z) containing a list of directories and their associated scores. When you cd, z intercepts this command, updates the score for the current directory in its database, and then returns control. When you type z <pattern>, it queries this database, finds the best match, and executes a cd command to that directory. The magic is in the scoring and matching algorithm, which is designed to be intelligent about inferring your intent from partial path names.

A common pitfall is not understanding how z weights matches. It doesn’t just find the first directory that contains your pattern; it scores all potential matches based on frecency and relevance. This means if you’ve visited /home/user/development/projectA/src very frequently, and /home/user/documents/projectA/src only once, typing z projectA/src will almost certainly take you to the development one, even if the documents one was entered later. The frecency score can override recency.

Once you’re comfortable with z, you’ll likely want to explore za for adding directories to z’s database manually or zr for removing entries.

Want structured learning?

Take the full Zsh course →