Oh My Zsh Plugins: Loading Less to Get More Out of Your Shell
Oh My Zsh only loads plugins listed in your plugins array — which means a bloated, inherited config is costing you startup time for nothing. Here's how to audit, measure, and trim it.
28 Jul 2026, 14:54 UTC

Your shell takes two seconds to start, tab completion occasionally picks the wrong candidate, and your ~/.zshrc has grown into a file you're afraid to edit. In many Oh My Zsh setups the root cause is the same: a long plugins array that was assembled by copy-pasting other people's dotfiles. The fix is not more plugins — it's understanding how Oh My Zsh actually loads them, and then enabling only what earns its startup cost.
Plugins are opt-in, and only opt-in
Oh My Zsh ships with hundreds of plugins in ~/.oh-my-zsh/plugins/, but installing the framework does not activate any of them. A plugin is only sourced if its name appears in the plugins array in your ~/.zshrc:
plugins=(git zsh-autosuggestions)Each enabled plugin contributes some mix of aliases, shell functions, and completion definitions. Everything not listed is ignored entirely — it costs you nothing at startup. This is the key mental model: the plugins directory is a menu, not a buffet that's already on your plate.
You can confirm what is actually active without reading your config, by running this in any interactive shell (no special permissions needed):
omz plugin listOn older Oh My Zsh versions the equivalent command is omz list-plugins. If the output shows entries you don't recognize, that's your first cleanup target.
The real cost: parse time, not disk space
Plugins are cheap on disk and expensive in a subtler way: every enabled plugin's .plugin.zsh file is sourced on every new shell. Most built-in plugins are small — the git plugin is mostly alias definitions — but some third-party plugins run subprocesses, network calls, or heavy loops at load time. Ten of those and your terminal feels sluggish before you've typed a character.
To measure rather than guess, time shell startup from a regular terminal:
time zsh -i -c exitThis launches an interactive zsh that immediately exits and reports how long it took. Run it, remove a plugin from the array, run omz reload (or open a new shell), and measure again. A plugin that adds 100ms+ had better be doing something you use daily. There is no universal "good" number, but the before/after delta per plugin is what matters for your decision.
A worked example: trimming a bloated array
Suppose your ~/.zshrc contains this, inherited from a blog post years ago:
plugins=(git docker kubectl npm yarn pip python brew macos z sudo history)Work through it with one question per entry: "Do I use an alias or completion from this every week?" A realistic outcome:
- Keep:
git(aliases likegst,gcosee constant use) anddocker(its completion for container names is genuinely useful). - Drop:
yarnandpipif you haven't touched those ecosystems in months;historyif you rely onCtrl-Rinstead of its aliases. - Audit: anything you don't recognize at all. Look inside
~/.oh-my-zsh/plugins/<name>/to see what it actually defines before deciding.
After editing, reload and verify:
omz reload
omz plugin list
time zsh -i -c exitThe plugin list should match your edited array exactly, and the startup time should drop roughly in proportion to what you removed. If it doesn't, something else in your ~/.zshrc (often a slow eval from a version manager) is the real bottleneck.
Custom plugins without forking the framework
When you want your own aliases or functions, resist editing files under ~/.oh-my-zsh/plugins/ — those are overwritten on update. Instead, create a custom plugin:
mkdir -p ~/.oh-my-zsh/custom/plugins/myutils
$EDITOR ~/.oh-my-zsh/custom/plugins/myutils/myutils.plugin.zshThe filename must follow the <name>/<name>.plugin.zsh convention. Put your functions inside, add myutils to the plugins array, and reload. Oh My Zsh detects it automatically, and omz update will never touch the custom directory. This is also the right pattern for sharing a small plugin across your own machines via a dotfiles repo.
The trade-off worth stating plainly
Third-party plugins — anything you clone into custom/plugins from GitHub — are arbitrary shell code executed in every session with your full user privileges. Popular ones like zsh-autosuggestions and zsh-syntax-highlighting are widely used, but "widely used" is not an audit. Before enabling one, skim its main .plugin.zsh file, check that it does nothing at load time beyond defining functions and completions, and pin to a commit rather than tracking a moving branch if you want reproducibility.
The other honest limitation: Oh My Zsh's convenience has a ceiling. If you strip things down and still need faster startup, the completion system (compinit) and framework overhead itself become the next targets, and at that point a hand-rolled minimal .zshrc may serve you better than further tuning.
Where to start today
Run omz plugin list, time your startup with time zsh -i -c exit, and remove one plugin you can't justify. Measure again. Repeat until every entry in the array is there because you chose it, not because a stranger's dotfiles said so. Your shell will start faster, and — more valuable — your config will finally be a file you understand.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.