CLI tool
zplug/zplug avatar
zplug/zplug

zplug pins zsh packages to a revision and lazy loads them

A next-generation plugin manager for zsh — manage plugins, commands, and themes from GitHub, Bitbucket, oh-my-zsh, prezto, and more with parallel installation and lazy loading.

6,054 stars226 forksShellMIT

At a glance

What is it?
zplug is a shell plugin manager for zsh that installs packages in parallel, lazy loads them, and pins each one to a branch, tag, or commit. It can pull from GitHub, Bitbucket, Gist, GitHub Releases, oh-my-zsh, prezto, and local directories, and it requires an awk variant that is not mawk.
Who is it for?
zplug fits a setup where you want several frameworks coexisting, pinned packages that stop moving under you, and a cache that keeps shell startup short. It is the wrong choice if you want a manager with a version number you can point at.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 8 months ago.
What is it written in?
Mainly Shell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • zplug/zplug6,054 ★ · +0
Star history
Repository2026-09-232026-11-14
zplug/zplug6.1k6.1k

0 Stars in the last 52 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

zplug load is what turns your package list into code

zplug splits the job into two steps inside .zshrc. The first step lists packages with zplug commands, and nothing is fetched or sourced at that point. The second is `zplug load`, which sources the plugins and adds whatever they contribute to `$PATH`. Between them sits `zplug install`, which is the step that actually clones repositories, and it does that work in parallel rather than one package at a time. That ordering is what makes the rest worth having: a cache mechanism is described as the way to reduce shell startup time, and lazy loading keeps a package you only need for one command from being sourced on every new shell. The guard the project recommends wraps install in a check, since `zplug check` returns true only when every listed package is installed:

zsh
# zplug check returns true if all packages are installed
# Therefore, when it returns false, run zplug install
if ! zplug check; then
    zplug install
fi

# source plugins and add commands to the PATH
zplug load

# zplug check returns true if the given repository exists
if zplug check babarot/enhancd; then
    # setting if enhancd is available
    export ENHANCD_FILTER=fzf-tmux
fi

fzf, peco, and zaw are named as the interactive pickers that work with it.

The from tag decides whether a package comes from a repo or a framework

`from` says where to get a package, and the default is `github`. The documented values reach well past GitHub: `bitbucket`, `gh-r` for binary artifacts published on GitHub Releases, `gist`, `oh-my-zsh` and `prezto` for plugins and themes that another tool already owns, and `local` for a directory you already have on disk. With `gh-r`, zplug tries to guess which file to use from your operating system and architecture, and the tag table hands you the manual override for when that guess lands on the wrong binary. Sources outside this list are your own, and that path is documented separately in a guide for external sources kept under the doc directory.

as and use decide whether a package is sourced or run

The `as` tag declares what kind of thing a package is, taking `plugin`, `command`, or `theme`, and it defaults to `plugin`. What `use` means then depends on that answer. For a plugin it is a glob pattern for the files to source, and the default glob is `*.zsh`. For a command it is a relative path to add to `$PATH`, which is how one dotfiles repository can supply several binaries at once, with brace and wildcard patterns in the path. `rename-to` renames the command you end up with, and the tag table restricts it to `as:command` only. `ignore` is the mirror of `use`, a glob of files to leave alone. Registering a plugin needs no manifest of its own: unlike antigen, no `*.plugin.zsh` file is required. The catch sits in that default glob, since a package whose entry point ends in .sh is not picked up unless you say so:

zsh
# Use the package as a command
# And accept glob patterns (e.g., brace, wildcard, ...)
zplug "Jxck/dotfiles", as:command, use:"bin/{histuniq,color}"

# Can manage everything, e.g., another person's zshrc
zplug "tcnksm/docker-alias", use:zshrc

# Disable updates using the "frozen" tag
zplug "k4rthik/git-cal", as:command, frozen:1

at, frozen, on, and if decide when a package moves

Four tags govern revisions and timing. `at` names the revision to install, a branch, tag, or commit, and its default is `master`, so an unpinned package follows master. `frozen` stops updates unless you ask for them, and it reads any truthy value, where truthy means `true`, `yes`, `on`, or `1`, with falsy covering `false`, `no`, `off`, and `0`. `on` loads a package only if a different, named package is already installed, which is the mechanism behind zplug's claim of supporting dependencies between packages. `if` takes a condition, such as a directory test, that gates installation and use together. `defer` postpones loading, and a value of 2 or above pushes the source call to after `compinit`. One more tag is informational: `dir` is read only and reports where a package was installed.

hook-build and hook-load are where zplug runs your commands

Two hook tags give you a slot at each moment that matters. `hook-build` runs after installation or an update, and `hook-load` runs after loading, so a build that has to compile something or copy a binary into place belongs in the first, and a check that the binary is on your path belongs in the second. The tag table's own examples are `hook-build:"make install"` and `hook-load:"echo 'Loaded!'"`. The pattern the project puts forward is self-management, letting the normal update path cover zplug itself by registering it as a package whose build hook calls the self-manage option. The line goes in your .zshrc:

zsh
zplug 'zplug/zplug', hook-build:'zplug --self-manage'

What is left afterwards is to run `zplug update`, which is the same command that updates everything else.

Three install routes, and the requirements behind them

There are three documented ways in, and they differ in how much you are trusting. The recommended route pipes an installer script into zsh:

console
curl -sL --proto-redir -all,https https://raw.githubusercontent.com/zplug/installer/master/installer.zsh | zsh

The project links to that script's source so you can read it before running it. Homebrew is the second route, and the README scopes it to macOS:

console
brew install zplug

The manual route sets ZPLUG_HOME yourself, clones the repository to that path, and sources init.zsh afterwards:

console
$ export ZPLUG_HOME=/path/to/.zplug
$ git clone https://github.com/zplug/zplug $ZPLUG_HOME

Three requirements hold for all of them: zsh 4.3.9 or higher, git 1.7 or higher, and an awk variant that must not be mawk. That last requirement is the easy one to miss, because a system awk resolving to mawk is ruled out by name rather than by any error message.

Five options sit beside nine commands

The command set is small and each entry has a narrow job. `install` installs packages in parallel and `update` updates them in parallel. `load` sources installed plugins and adds installed commands to `$PATH`. `check` returns true when all packages are installed, `status` reports whether the remote repositories are up to date, and `list` exposes the associative array `$zplugs`, narrowed by `--installed`, `--loaded`, and `--select`. `clean` removes repositories that are no longer managed and takes `--force` and `--select` to narrow it, `clear` removes the cache file, and `info` prints the source URL and tag values for one package. Five global options come on top of that:

| Option | What it does | |--------|--------------| | `--help` | Display the help message | | `--rollback` | Rollback a failed package | | `--self-manage` | Self management of zplug | | `--version` | Display the version of zplug | | `--log` | Show the report of zplug errors |

The newest release tag is from 2017 and the branch moved in 2026

Two dates frame the project. The most recent tagged release is 2.4.2, published on 28 December 2017, following 2.4.1 in January 2017 and 2.4.0 in December 2016, while the default branch main was last pushed to on 4 March 2026. Those dates sit more than eight years apart, so the tag list is not a picture of what is on main. The repository does carry its own test and release plumbing: a Makefile whose `test` target clones key-amb/shove, marks it executable, and runs it against test/commands in zsh, a `release` target that calls misc/dev/release.zsh, and a Dockerfile that assembles an Ubuntu noble image with zsh, tmux, and a zplug user whose copy of the repository already sits at /home/zplug/.zplug. One flaw shows up in that Makefile: its `install` target carries a comment and no recipe, so running it prints the target and does nothing.

Editorial conclusion

zplug fits a setup where you want several frameworks coexisting, pinned packages that stop moving under you, and a cache that keeps shell startup short. It is the wrong choice if you want a manager with a version number you can point at. Before you commit, check the three requirements on your own machine, in particular that your awk is not mawk, and decide whether installing through a piped script is something you want on that machine at all.

Frequently asked questions

How do I install zplug?

Three routes are documented. The recommended one pipes the installer script into zsh, Homebrew is `brew install zplug` and is scoped to macOS, and the manual route sets ZPLUG_HOME, clones the repository there, and sources init.zsh. All three need zsh 4.3.9 or higher, git 1.7 or higher, and an awk that is not mawk.

How do I use zplug after it is installed?

Add a zplug section to your .zshrc that lists packages with zplug commands, run `zplug install` to fetch them, then `zplug load` to source the plugins and add their commands to $PATH. `zplug check` returns true when every listed package is installed, which makes it a natural guard before the install step.

What is the difference between zplug and antigen?

Unlike antigen, zplug needs no ZSH plugin file, so no *.plugin.zsh is required to register a plugin. It also manages oh-my-zsh and prezto plugins and themes, installs and updates in parallel, and pins a package to a branch, tag, or commit with the `at` tag.

What is zplug?

zplug is a zsh plugin manager written in shell and released under the MIT license. It manages plugins, commands, and themes from GitHub, Bitbucket, Gist, oh-my-zsh, prezto, and local directories, with parallel installation, lazy loading, hooks, and a cache that reduces shell startup time.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. zplug/zplug on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/zplug-zplug.svg)](https://hysenlabs.com/projects/zplug-zplug)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/zplug-zplug.svg)](https://hysenlabs.com/projects/zplug-zplug)

Was this useful?