Back to Blog

Oh My Zsh Tutorial — Plugins, Themes & Custom Functions #25

Sandy LaneSandy Lane

Video: Oh My Zsh Tutorial — Plugins, Themes & Custom Functions #25 by Taught by Celeste AI - AI Coding Coach

Take the quiz on the full lesson page
Test what you've read · interactive walkthrough

Zsh Lesson 25: Oh My Zsh — Plugins, Themes, Custom Functions

Install via the official curl-pipe-sh. Plugins go in ~/.zshrc's plugins=(...) array. Themes via ZSH_THEME=.... Custom plugins live in ~/.oh-my-zsh/custom/plugins/<name>/<name>.plugin.zsh. Most popular plugins: git, z, zsh-autosuggestions, zsh-syntax-highlighting.

Oh My Zsh (OMZ) is a community framework for managing your Zsh config. Adds plugins, themes, and a sane structure on top of .zshrc.

Installation

sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/HEAD/tools/install.sh)"

The installer:

  1. Clones into ~/.oh-my-zsh.
  2. Backs up your existing .zshrc to .zshrc.pre-oh-my-zsh.
  3. Installs the new .zshrc template.
  4. Switches your default shell to Zsh (if it wasn't already).

After install, restart your terminal — you'll see the default theme and the OMZ welcome.

Directory layout

~/.oh-my-zsh/
  themes/        # 150+ themes
  plugins/       # 300+ official plugins
  custom/
    themes/      # your own themes
    plugins/     # your own plugins
  oh-my-zsh.sh   # main loader (sourced from .zshrc)

The custom/ subtree is yours — edits there survive omz update.

.zshrc structure

The OMZ-installed ~/.zshrc looks like:

export ZSH="$HOME/.oh-my-zsh"

ZSH_THEME="robbyrussell"

plugins=(git)

source $ZSH/oh-my-zsh.sh

# Your customizations go below

The two key lines:

  • ZSH_THEME=... — pick a theme.
  • plugins=(...) — list of enabled plugins.

After editing, reload:

source ~/.zshrc

Themes

ls ~/.oh-my-zsh/themes/ | head
# 3den.zsh-theme  agnoster.zsh-theme  alanpeabody.zsh-theme  amuse.zsh-theme  ...

Hundreds of themes. Pick one in ~/.zshrc:

ZSH_THEME="agnoster"

Reload, see the new prompt. Some popular themes:

  • robbyrussell — default; minimalist.
  • agnoster — powerline-style; needs a powerline-compatible font.
  • bullet-train — info-rich.
  • pure — separate project; very clean.
  • powerlevel10k — feature-rich; the most-installed theme overall.

For Powerlevel10k:

git clone --depth=1 https://github.com/romkatv/powerlevel10k.git \
  ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k
ZSH_THEME="powerlevel10k/powerlevel10k"

Restart, run p10k configure for an interactive setup.

Plugins: the basics

plugins=(git z docker kubectl)

Each plugin name corresponds to ~/.oh-my-zsh/plugins/NAME/. List available:

ls ~/.oh-my-zsh/plugins/ | head

300+ plugins. Add as many as you want — startup time grows linearly.

Essential plugins

git

plugins=(git)

Adds 100+ aliases:

alias gst='git status'
alias gp='git pull'
alias gd='git diff'
alias gco='git checkout'
alias gcm='git checkout master'
alias gcb='git checkout -b'
alias glog='git log --graph --oneline --decorate'
# ... and many more

Worth memorizing the dozen you'll use most.

z (or zoxide)

plugins=(z)

z learns your most-frequented directories. After visiting:

cd ~/projects/myapp
cd /var/log
cd ~/Documents/work

# Later
z myapp           # jumps to ~/projects/myapp
z log             # jumps to /var/log
z work            # ranking by frequency + recency

The modern alternative is zoxide — same idea, faster.

zsh-autosuggestions

Not bundled — install separately:

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

Add to plugins=(... zsh-autosuggestions).

Now as you type, it shows ghost-text suggestions from your history. Press → (or Ctrl-F) to accept. Massive productivity boost.

zsh-syntax-highlighting

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

Add zsh-syntax-highlighting to plugins=. Highlights commands as you type — green if valid, red if not, paths underlined. Catches typos before you Enter.

Must be the last plugin in the list. Add to the very end:

plugins=(git z zsh-autosuggestions zsh-syntax-highlighting)

Other useful ones

  • docker, docker-compose — completion for Docker commands.
  • kubectl — k8s aliases.
  • aws — AWS CLI completion.
  • npm, yarn — package manager.
  • python, pip, virtualenv — Python tooling.
  • command-not-found — suggests packages.
  • colored-man-pages — yes please.

Writing a custom plugin

Custom plugins live in ~/.oh-my-zsh/custom/plugins/NAME/NAME.plugin.zsh.

mkdir -p ~/.oh-my-zsh/custom/plugins/myutils
cat > ~/.oh-my-zsh/custom/plugins/myutils/myutils.plugin.zsh <<'EOF'
# Useful aliases
alias ll='ls -lah'
alias cls='clear'
alias proj='cd ~/Projects'

# Helper functions
mkcd() {
  mkdir -p "$1" && cd "$1"
}

weather() {
  curl -s "wttr.in/${1:-}"
}

extract() {
  case "$1" in
    *.tar.gz)  tar -xzf "$1" ;;
    *.tar.bz2) tar -xjf "$1" ;;
    *.zip)     unzip "$1" ;;
    *) echo "Unknown format: $1" >&2 ;;
  esac
}
EOF

Enable in ~/.zshrc:

plugins=(git z myutils)

Reload:

source ~/.zshrc

Now mkcd, weather, extract, and the aliases are available.

Customizing without OMZ updates breaking

Anything in ~/.oh-my-zsh/custom/ survives updates. Don't edit files in ~/.oh-my-zsh/themes/ or ~/.oh-my-zsh/plugins/ directly — they get overwritten.

To override a stock plugin: copy it to custom/plugins/ first, then edit.

Updating

omz update

OMZ also offers to update itself periodically. To control:

# In ~/.zshrc
zstyle ':omz:update' mode auto      # auto-update
zstyle ':omz:update' mode reminder  # ask each time
zstyle ':omz:update' mode disabled  # never
zstyle ':omz:update' frequency 13   # every 13 days

Uninstalling

uninstall_oh_my_zsh

Restores the original .zshrc from the backup.

Lighter alternatives

OMZ is heavy — many plugins, slower startup. Alternatives:

  • Prezto — modular, faster.
  • zinit / antibody — plugin managers, no framework.
  • starship — just the prompt; works in any shell.
  • DIY — a custom .zshrc with the few plugins you actually use.

The "manage just plugins, not framework" approach with zinit:

zinit light zsh-users/zsh-syntax-highlighting
zinit light zsh-users/zsh-autosuggestions
zinit light romkatv/powerlevel10k

Faster, simpler. Worth trying once you know what plugins you actually want.

Performance

OMZ adds startup time — sometimes hundreds of milliseconds. Profile with:

# In ~/.zshrc, at the top:
zmodload zsh/zprof

# At the end:
zprof

Open a new shell; you'll see a function-level breakdown. Disable plugins you don't use.

A custom plugin example

# ~/.oh-my-zsh/custom/plugins/dev/dev.plugin.zsh

# Project navigation
alias dev='cd ~/Projects'

# Git shortcuts (in addition to omz git)
alias gca='git commit -am'
alias gpu='git push -u origin HEAD'

# Run tests
alias t='make test'
alias tw='make test-watch'

# Find a project and cd in
proj() {
  local p
  p=$(find ~/Projects -maxdepth 2 -type d | fzf) || return
  cd "$p"
}

# Quick HTTP request
api() {
  local url="$1"
  shift
  curl -s "$url" "$@" | jq
}

# Python scratch
pyscratch() {
  local f="/tmp/scratch-$(date +%s).py"
  echo "# Python scratch" > "$f"
  $EDITOR "$f"
}

A real working plugin. Your daily commands, named once, available everywhere.

Common stumbles

Slow startup. Too many plugins. Profile with zprof; disable the heavy ones.

Plugin not working. Reload (source ~/.zshrc) or open a new tab. If still nothing, check the plugin name matches its directory name.

zsh-syntax-highlighting errors with custom prompt. Make sure it's the last plugin in plugins=().

Custom changes lost after omz update. You edited files in themes/ or plugins/ directly. Use custom/ for overrides.

Theme breaks with non-powerline font. Themes like agnoster need special glyphs. Install a Powerline-patched font (Nerd Fonts is the modern collection).

z doesn't remember. z builds a database from your cds. Use it for a few weeks; database grows naturally.

p10k icons are squares. Need a Nerd Font + terminal configured to use it.

What's next

Lesson 26: building a CLI tool. getopts, colors, progress bars, a polished todo app.

Recap

OMZ is a Zsh framework. Install via curl-pipe-sh; the ~/.zshrc it generates has ZSH_THEME=... and plugins=(...). 300+ plugins, 150+ themes. Essential plugins: git, z, zsh-autosuggestions, zsh-syntax-highlighting (last). Custom plugins in ~/.oh-my-zsh/custom/plugins/NAME/NAME.plugin.zsh. For lighter alternatives: zinit, Prezto, or just a hand-tuned .zshrc with starship prompt.

Next lesson: building a CLI tool.

Ready? Take the quiz on the full lesson page →
Test what you've learned. Watch the lesson and try the interactive quiz on the same page.