Zsh Setup & Configuration
A curated Zsh configuration with oh-my-zsh, essential plugins, aliases, and performance optimizations. Copy-paste ready for a productive terminal setup.
Published March 21, 2026
Overview
A well-tuned Zsh config turns your terminal from a command prompt into a productivity multiplier. This setup includes oh-my-zsh as the foundation, four essential plugins, practical aliases, and performance tweaks that keep startup time under 200ms.
Prerequisites
- macOS or Linux (WSL works too)
- Homebrew (macOS) or apt (Linux)
Install Zsh if not already present:
# macOS (usually pre-installed)
brew install zsh
# Ubuntu/Debian
sudo apt install zsh
# Set as default shell
chsh -s $(which zsh)
Oh-My-Zsh Setup
Oh-my-zsh provides a plugin framework and theme system. Install it with:
sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
This creates ~/.zshrc and ~/.oh-my-zsh/ with the default configuration.
Essential Plugins
These four plugins cover 90% of what you need. Each one earns its startup cost.
zsh-autosuggestions
Inline suggestions from your command history as you type. Accept with right arrow.
git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
zsh-syntax-highlighting
Real-time syntax coloring — green for valid commands, red for typos.
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
zsh-completions
Additional completion definitions for hundreds of CLI tools.
git clone https://github.com/zsh-users/zsh-completions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-completions
fzf
Fuzzy finder for file search (Ctrl+T), history search (Ctrl+R), and directory navigation (Alt+C).
# macOS
brew install fzf
$(brew --prefix)/opt/fzf/install
# Linux
sudo apt install fzf
.zshrc Configuration
A complete .zshrc with sensible defaults:
# Path to oh-my-zsh
export ZSH="$HOME/.oh-my-zsh"
# Theme — robbyrussell is fast and clean
ZSH_THEME="robbyrussell"
# Plugins — keep this list short for fast startup
plugins=(
git
zsh-autosuggestions
zsh-syntax-highlighting
zsh-completions
fzf
docker
node
npm
)
source $ZSH/oh-my-zsh.sh
# ─── Aliases ──────────────────────────────────────────────
alias ll="ls -la"
alias la="ls -A"
alias l="ls -CF"
# Git shortcuts
alias gs="git status"
alias gc="git commit"
alias gp="git push"
alias gpl="git pull"
alias gco="git checkout"
alias gb="git branch"
alias gd="git diff"
# Development
alias dev="npm run dev"
alias build="npm run build"
alias lint="npm run lint"
alias test="npm run test"
# Directory navigation
alias ..="cd .."
alias ...="cd ../.."
alias ....="cd ../../.."
# ─── Node Version Manager ────────────────────────────────
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
# ─── Path additions ──────────────────────────────────────
export PATH="$HOME/.local/bin:$PATH"
Performance Tips
Lazy-load nvm
nvm adds 300-500ms to shell startup. Lazy-load it instead:
# Replace the standard nvm init with this
lazy_load_nvm() {
unset -f node npm npx nvm
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
}
node() { lazy_load_nvm; node "$@"; }
npm() { lazy_load_nvm; npm "$@"; }
npx() { lazy_load_nvm; npx "$@"; }
nvm() { lazy_load_nvm; nvm "$@"; }
Compile completions
Rebuild the completion cache periodically:
# Add to .zshrc — only rebuilds once per day
autoload -Uz compinit
if [ $(date +'%j') != $(stat -f '%Sm' -t '%j' ~/.zcompdump 2>/dev/null) ]; then
compinit
else
compinit -C
fi
Measure startup time
Profile your shell startup to find bottlenecks:
# Time your shell startup
time zsh -i -c exit
# Detailed profiling
zsh -xv -c exit 2>&1 | head -50
Target: under 200ms for a snappy experience. Each plugin adds 10-50ms — keep the list lean.