You can navigate your filesystem by just typing a directory name, even if it’s nested, without cd or any other explicit command.

# Example: Navigate to a deeply nested directory
# Current directory: /Users/you
# Target directory: /Users/you/projects/my-awesome-project/frontend/src/components

# Instead of:
# cd projects/my-awesome-project/frontend/src/components

# You can just type:
projects/my-awesome-project/frontend/src/components

This magic is powered by Zsh’s AUTO_CD option and a bit of clever globbing. When AUTO_CD is enabled, Zsh doesn’t just look for commands when you type something. If the first word you type isn’t a command, it checks if it’s a directory. If it is, Zsh implicitly prepends cd to it.

But AUTO_CD alone is a bit blunt; it only works if the directory you type is the very next thing on the command line. To get the truly "navigate without typing cd" experience, especially for nested directories, you need Zsh’s extended globbing. Specifically, the ** glob pattern.

This ** pattern, when used with AUTO_CD, allows Zsh to match zero or more directories. So, when you type projects/my-awesome-project/frontend/src/components, Zsh, with AUTO_CD and appropriate globbing, sees this as a potential path. It then tries to resolve this path, effectively performing a cd into that directory.

To enable this, you need to configure your Zsh. Open your ~/.zshrc file and add or ensure these lines are present:

# Enable AUTO_CD
setopt AUTO_CD

# Enable extended globbing
setopt EXTENDED_GLOB

# This is the crucial part for nested navigation.
# It tells Zsh to expand '**' to match any number of directories.
# When AUTO_CD is on, and AUTO_CD_NEGATE is off, Zsh will try to cd into
# a path specified by a glob.
setopt AUTO_CD_NEGATE # Not strictly needed for this basic case, but good practice for other auto-cd behaviors.

After saving ~/.zshrc, reload your Zsh configuration by running source ~/.zshrc or by opening a new terminal window. Now, try typing a path to a directory that’s not your current one.

Let’s see it in action with a concrete example. Imagine your home directory has the following structure:

/Users/you/
├── projects/
│   └── my-app/
│       ├── frontend/
│       │   └── src/
│       │       └── components/
│       └── backend/
└── docs/
    └── project-notes.md

If you are in /Users/you/, and you want to go to /Users/you/projects/my-app/frontend/src/components/, you can now type:

projects/my-app/frontend/src/components

Zsh will interpret this as a directory path and cd into it.

The real power comes when you combine this with other Zsh features. For instance, if you have a directory named configs in your home directory and another configs inside your projects directory, Zsh’s AUTO_CD will typically pick the first one it finds in your PATH or current directory. However, by explicitly typing the path, you disambiguate.

Consider a scenario where you have two directories named temp in different locations: /Users/you/downloads/temp/ and /Users/you/projects/temp/. If you type temp, Zsh might default to one. But typing downloads/temp or projects/temp ensures you go to the correct one.

The mechanics behind this involve Zsh’s WORD_FUNCTIONS and COMPLETION_TYPE settings, but for most users, AUTO_CD and EXTENDED_GLOB are the primary drivers. When you type a string and press Enter, Zsh performs a series of checks. If AUTO_CD is set, and the string isn’t found as a command, Zsh checks if it’s a directory name. If EXTENDED_GLOB is enabled, Zsh’s globbing engine can interpret patterns like ** to match multiple directory levels, allowing for the seamless navigation of deeply nested structures by simply typing their relative or absolute path.

The AUTO_CD_NEGATE option, while not directly used for the simple cd behavior, is important for more advanced AUTO_CD usage. If AUTO_CD_NEGATE is enabled, Zsh will not cd if the first character of the word is !, which is used for history expansion negation. Keeping it off in many configurations simplifies the direct path navigation.

The true elegance is that Zsh handles the directory traversal implicitly. You don’t need to tell it how to find components within src within frontend, etc. It just does it. This is a significant departure from how many other shells operate, where you’d explicitly use cd for each level or rely on tab completion to build the path.

One subtle point is how Zsh handles cases where the typed string could be a command but also a directory. Zsh prioritizes commands. So, if you had a command named projects in your PATH, typing projects would execute that command, not cd into a directory named projects. However, when you type a full path like projects/my-app/frontend/src/components, Zsh is much more likely to interpret it as a directory path because it’s a specific file system location.

The next hurdle for many users after mastering AUTO_CD is understanding Zsh’s powerful alias and function system, which allows for even more sophisticated command substitution and workflow automation.

Want structured learning?

Take the full Zsh course →