Oh My Zsh native plugin loader vs zplug: which should own plugin sourcing when both are configured?
0 reputation · 24 Sept 2026, 17:45 UTC
0 reputation · 24 Sept 2026, 17:45 UTC
I run Oh My Zsh with a handful of plugins listed in the plugins array in .zshrc, and I am evaluating zplug to manage a few additional third-party plugins that are not part of the Oh My Zsh repository. The boundary I cannot resolve is who owns sourcing when the same plugin could be loaded by either side.
My understanding is that Oh My Zsh sources plugins strictly in array order, with ~/.oh-my-zsh/custom/plugins overriding same-named built-ins, and that it has no dependency resolution or deduplication of its own. If zplug also sources a plugin that Oh My Zsh already loaded, I expect duplicate sourcing, but I have found no official guidance on whether the native loader should defer to an external manager, or vice versa.
Assume a current Oh My Zsh release and zsh 5.8+. I can verify behavior with zsh -x or temporary echo statements in plugin files, but I want a design decision before testing.
plugins array and an external manager like zplug?custom/plugins be migrated to the external manager to keep updates clean?35275 reputation · 24 Sept 2026, 23:26 UTC
Let Oh My Zsh own every plugin that lives in its own repository (built-ins and custom/plugins), and let zplug manage only third-party plugins that are not present in Oh My Zsh. Place zplug load after source $ZSH/oh-my-zsh.sh. If a plugin exists in both ecosystems (e.g., zsh-autosuggestions), pick one source—prefer the upstream repo via zplug—and remove it from the other side.
Oh My Zsh documents no policy on external managers. The community pattern that avoids surprises is: Oh My Zsh = framework plugins; zplug = everything else. Oh My Zsh loads its plugins array in order, checking ~/.oh-my-zsh/custom/plugins/<name> before ~/.oh-my-zsh/plugins/<name>. It performs no dependency resolution or deduplication.
When the same plugin file is sourced twice (once by Oh My Zsh, once by zplug):
precmd, preexec, chpwd) are re-registered, so they run multiple times per prompt.These are not theoretical; they appear immediately in $precmd_functions, $preexec_functions, and $path.
~/.oh-my-zsh/custom/plugins/<name> remains under Oh My Zsh control. Migrating to zplug is optional but requires:
zplug "~/.oh-my-zsh/custom/plugins/<name>", from:localplugins array to prevent double loadIf you keep the override in custom/plugins, Oh My Zsh continues to load it; zplug simply ignores that name.
# .zshrc
plugins=(git docker kubectl) # only Oh My Zsh built-ins or custom/plugins
source $ZSH/oh-my-zsh.sh
# zplug manages ONLY external repos not in Oh My Zsh
zplug "zsh-users/zsh-autosuggestions"
zplug "zsh-users/zsh-syntax-highlighting", defer:2
zplug "junegunn/fzf", as:command, use:bin/fzf-tmux
zplug load
Run this once to verify no plugin is sourced twice:
zsh -x -i -c exit 2>&1 | grep -E '(source|\. ).*/(plugins|zplug)/' | sort -u
If any plugin path appears twice, adjust the partition. Which plugin(s) are you currently listing in both the plugins array and zplug? That single list will tell me whether the recommendation needs to change for your case.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.