Don’t get me wrong – Oh My Zsh is an excellent product. It’s well-maintained, feature-rich, and has helped millions of developers enhance their shell experience. But here’s the thing: you don’t need it to have a great zsh experience.
When I recently set up a new workstation, I decided to skip Oh My Zsh entirely and configure zsh manually. The result? A lightweight, fast, and fully customized shell that does exactly what I need – nothing more, nothing less.
The Oh My Zsh Bloat Problem
Oh My Zsh comes with a lot of features out of the box. Themes, plugins, aliases, functions – it’s a complete ecosystem. But here’s the catch: most of us only use a tiny fraction of what it provides.
When you install Oh My Zsh, you get:
- Hundreds of themes (when you’ll only use one)
- Dozens of plugins (when you need maybe 3-4)
- Tons of aliases (many of which you’ll never remember)
- Complex initialization scripts that slow down shell startup
- A configuration system that abstracts away the underlying zsh mechanics
This bloat has real consequences:
- Slower shell startup: Every plugin and theme adds initialization time
- Complexity: It becomes harder to understand what’s actually happening in your shell
- Dependencies: You become reliant on Oh My Zsh’s structure and conventions
My Lightweight Alternative
Instead of Oh My Zsh, I built a minimal zsh configuration that focuses on the essentials. Here’s what I actually need:
1. Smart Autosuggestions
The zsh-autosuggestions
plugin suggests commands as you type based on your history:
# Installation
git clone https://github.com/zsh-users/zsh-autosuggestions ~/.zsh/zsh-autosuggestions
2. Syntax Highlighting
The zsh-syntax-highlighting
plugin highlights commands as you type, showing invalid commands in red:
# Installation
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ~/.zsh/zsh-syntax-highlighting
3. Enhanced History Search
Instead of Oh My Zsh’s history plugin, I use simple key bindings that let me search through history using arrow keys:
bindkey '\e[A' history-beginning-search-backward
bindkey '\e[B' history-beginning-search-forward
Now when I type git
and press the up arrow, it only shows commands that start with git
from my history. This is incredibly useful for finding that complex command you ran last week.
4. Tool-Specific Autocompletion
Instead of generic Oh My Zsh plugins, I load completions only for tools I actually use:
# Docker completion
source <(docker completion zsh)
# kubectl (with kubecolor if available)
if command -v kubecolor >/dev/null 2>&1; then
alias kubectl=kubecolor
compdef kubecolor=kubectl
fi
# Google Cloud SDK
if [ -f '/opt/homebrew/share/google-cloud-sdk/completion.zsh.inc' ]; then
source '/opt/homebrew/share/google-cloud-sdk/completion.zsh.inc'
fi
Smart Word Navigation
One thing that frustrated me about default zsh was word jumping. When you press Alt+→
to jump forward by word, it doesn’t behave intuitively with paths or complex strings.
I fixed this with:
autoload -Uz select-word-style
select-word-style normal
zstyle ':zle:*' word-style unspecified
Now when I have a path like /usr/local/bin/my-script
and I’m at the beginning:
- Before:
Alt+→
jumps to the end of the entire path - After:
Alt+→
jumps to each segment:/usr
→/local
→/bin
→/my
→-script
This makes editing long paths or URLs much more efficient.
Intelligent Completion System
Instead of Oh My Zsh’s completion system, I configured zsh’s built-in completion with smart behaviors:
# Initialize completion system
autoload -Uz compinit
compinit
# Smart case matching - lowercase matches both cases
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'
# Menu selection for multiple matches
zstyle ':completion:*' menu select
# Error tolerance in completion
zstyle ':completion:*' completer _complete _approximate
Menu Selection in Action
When I type cd Pro
and hit tab, instead of just completing to the first match, I get a visual menu:
cd Pro
> Projects/ Programming/ Profile.txt
I can use arrow keys to select the right one. If I make a typo like cd Porjects
and hit tab, zsh’s approximate completion suggests:
cd Porjects
correct to: Projects/ _
Starship: Prompt Done Right
For my prompt, I chose Starship instead of Oh My Zsh themes. Starship is a single-purpose tool that does one thing exceptionally well: creating beautiful, informative prompts.
eval "$(starship init zsh)"
Why Starship over Oh My Zsh themes?
- Fast: Written in Rust, it’s significantly faster than shell-based themes
- Cross-shell: Works with zsh, bash, fish, and more
- Single responsibility: Only handles prompts, doesn’t mess with other shell functionality
- Highly configurable: Easy-to-understand TOML configuration
- No dependencies: Doesn’t require Oh My Zsh or any other framework
Essential Aliases (But Not Too Many)
Oh My Zsh comes with hundreds of aliases. I keep mine minimal and memorable:
alias ls='ls --color=auto'
alias ll='ls -alF'
That’s it. I could add more, but I’ve found that too many aliases make you forget the actual commands, which hurts you when working on systems that don’t have your config.
Understanding What’s Happening
Let me explain the key components of my setup:
The compinit
Function
autoload -Uz compinit
compinit
This initializes zsh’s completion system. The autoload -Uz
tells zsh to load the function when needed (lazy loading), and the U
flag ensures it’s loaded even if there are aliases for the same name.
Script Sourcing with Error Handling
Instead of blindly sourcing files that might not exist, I check first:
local scripts_to_source=(
~/.zsh/zsh-autosuggestions/zsh-autosuggestions.zsh
~/.zsh/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
# ... more scripts
)
for script_file in "${scripts_to_source[@]}"; do
if [ -r "$script_file" ]; then
source "$script_file"
else
print -P "%F{yellow}Warning:%f Script not found: $script_file"
fi
done
This approach:
- Prevents errors when scripts don’t exist
- Gives clear feedback about missing dependencies
- Makes the config portable across different systems
Making the Switch
If you’re currently using Oh My Zsh and want to try this approach:
- Backup your current config:
cp ~/.zshrc ~/.zshrc.backup
- Start minimal: Begin with just the essentials (autosuggestions, syntax highlighting)
- Add incrementally: Only add features as you realize you need them
- Understand each piece: Don’t copy-paste without understanding what each line does
The goal isn’t to recreate Oh My Zsh – it’s to build exactly what you need and understand every piece of it.
Conclusion
Oh My Zsh is a great project that has introduced countless developers to the power of zsh. But once you understand what you actually need from your shell, you might find that a custom configuration serves you better.
My lightweight setup gives me everything I need: smart completions, helpful suggestions, a beautiful prompt, and fast performance. Most importantly, I understand every line of my configuration and can modify it without fear of breaking some complex framework.
Sometimes the best tool is the one you build yourself – even if it’s simpler than the popular alternative.
Here you can find my complete zsh configuration: zshrc