Oh My Zsh’s biggest trick is that it manages your shell’s behavior not by directly modifying zshrc, but by sourcing a series of smaller files that do modify zshrc for you.

Let’s see it in action. Imagine you’ve just installed Oh My Zsh. Your .zshrc file will look something like this:

# Oh My Zsh overrides
# For a full list of options, see: https://github.com/ohmyzsh/ohmyzsh/wiki/Configuration
ZSH_THEME="robbyrussell"
# INSTALLED_PLUGINS=(git) # Example of how plugins are enabled

# Enable Powerlevel10k prompt
# source $ZSH/oh-my-zsh.sh

# Uncomment the following line to disable auto-correction
# DISABLE_AUTO_CORRECT="true"

# If you come from bash you might have to uncomment these
# AUTO_CD="true"
# CHASE_LINKS="true"

# Uncomment to disable completion caching
# CACHE_COMPLETION="false"

# Uncomment to disable colored completion
# COMPLETION_WAITING_DOTS="true"

# Which plugins would you like to load?
# Standard plugins can be found in $ZSH/plugins/ directory
# for a full list of available plugins, just check them out.
# Always sort output of ls
# if [ "$OSTYPE" = "linux-gnu" ]; then
#   ls_colors='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;36:eo=01;31:ex=01;32:bd=40;33;01:up=40;33;01:if=01;36:ca=01;31:'.
# fi
# plugins=(git) # THIS IS WHERE THE PLUGINS GO

# Add custom plugins to the plugins array above.
# Example: plugins=(git extract brew autojump)

# Oh My Zsh core
ZSH_DISABLE_COMPLETION_REBUILD="true"
ZSH_COMPLETION_COMPACT="true"
ZSH_COMPLETION_IGNORE_ERRORS="true"
ZSH_DISABLE_PROMPT_PROFILING="true"
ZSH_DISABLE_SUMMARY="true"

# Load Oh My Zsh
source $ZSH/oh-my-zsh.sh

# User configuration

# Export PATH for Homebrew
export PATH="/opt/homebrew/bin:$PATH"

When you run zsh, Oh My Zsh does a few key things:

  1. It reads your .zshrc.
  2. It sets up a bunch of internal variables and functions.
  3. Crucially, it finds ZSH_THEME and sources the corresponding theme file (e.g., $ZSH/themes/robbyrussell.zsh-theme). This theme file then defines your prompt.
  4. It iterates through the plugins=(...) array in your .zshrc. For each plugin listed, it sources the corresponding plugin file (e.g., $ZSH/plugins/git/git.plugin.zsh). These plugin files often define new commands, aliases, or functions.
  5. Finally, it sources the actual oh-my-zsh.sh script, which ties everything together and loads Zsh’s completion system, syntax highlighting, and other core features.

The power here is in the modularity. You don’t put all your plugin logic directly into .zshrc. You just list the plugin names, and Oh My Zsh handles loading them. This keeps your .zshrc clean and makes it easy to add, remove, or swap out functionality.

Let’s say you want to add the zsh-autosuggestions plugin. First, you’d typically clone it into the Oh My Zsh plugins directory:

git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions

Then, you edit your .zshrc and add zsh-autosuggestions to the plugins array:

plugins=(git zsh-autosuggestions)

After sourcing your .zshrc (or opening a new terminal), you’ll notice that as you type, Zsh suggests commands you’ve used before, based on your history. This is because the zsh-autosuggestions.plugin.zsh file, when sourced by Oh My Zsh, hooks into Zsh’s completion system to provide these real-time suggestions.

The ZSH_THEME variable is similarly straightforward. If you change ZSH_THEME="robbyrussell" to ZSH_THEME="agnoster", Oh My Zsh will now source $ZSH/themes/agnoster.zsh-theme instead, completely changing your prompt’s appearance and information displayed. Many themes, like agnoster, also require specific fonts (like Meslo LG M for Powerlevel10k) to render correctly.

The one thing most people don’t realize is that the plugins array isn’t just for Oh My Zsh’s built-in plugins. You can add any plugin file that follows the $ZSH/plugins/*.plugin.zsh or $ZSH_CUSTOM/plugins/*.plugin.zsh structure. Oh My Zsh will automatically find and load them. This extensibility is why it’s so popular – you’re not limited to what Oh My Zsh ships with.

The next step is understanding how custom themes and plugins integrate, and the specific configuration options within them.

Want structured learning?

Take the full Zsh course →