Oh My Zsh Tutorial — Plugins, Themes & Custom Functions #25
Video: Oh My Zsh Tutorial — Plugins, Themes & Custom Functions #25 by Taught by Celeste AI - AI Coding Coach
Zsh Lesson 25: Oh My Zsh — Plugins, Themes, Custom Functions
Install via the official curl-pipe-sh. Plugins go in
~/.zshrc'splugins=(...)array. Themes viaZSH_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:
- Clones into
~/.oh-my-zsh. - Backs up your existing
.zshrcto.zshrc.pre-oh-my-zsh. - Installs the new
.zshrctemplate. - 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
.zshrcwith 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.