需在交互式 zsh 会话中执行安装命令;延迟加载仅对声明支持 zsh-defer 的插件有效;静态加载文件需在 .zsh_plugins.txt 更新后重新生成
git clone --depth=1 https://github.com/mattmc3/antidote.git ${ZDOTDIR:-$HOME}/.antidote
source /path-to-antidote/antidote.zsh
antidote load ${ZDOTDIR:-$HOME}/.zsh_plugins.txtREADME 未说明,仅需可运行 Zsh 的环境,无 GPU 或显存要求
Zsh 插件管理器,兼容 antibody/antigen 写法,解决插件加载慢的问题
用纯 Shell 实现的 zsh 插件管理器,通过并行加载和静态缓存解决 zsh 启动慢、插件管理卡顿的问题。
核心能力
- 沿用 antibody/antigen 的 .zsh_plugins.txt 插件清单写法
- 用静态插件文件实现极快的插件加载
- 支持 kind:defer 延迟加载兼容的插件
- 可直接引用 Oh My Zsh 的 lib 与 plugins 路径
- 附带 bat 的 .zsh_plugins.txt 语法高亮定义
容易踩的坑
- v2.3.0最新正式版2026-08-07 · 2026-08-07 17:29 UTC
[v2.3.0]
- Add a
preset:directive setting fallback annotations for every later entry of a bundle, sopin:and the like need not repeat on each line. Keyed by clone directory, so the short, https, and ssh spellings share one set. Line-level andusing:values win. - Speed up dynamic mode by resolving
antidote initin the parent shell instead of a subprocess, and dropping four forks from everyantidoteinvocation. A warmsource <(antidote init)startup goes from roughly 50ms to 35ms, andantidote inititself from 13.5ms to 1ms. - Read the config file once per shell instead of once per command.
antidote-setupsources it into the parent shell so parent-side code sees its zstyles; anything set before antidote loads still wins. - Make a lone
antidote.zshusable when sourced, falling back to a shim that routes commands to the subprocess.antidote loadand dynamic mode still need the full install. - Fix a config file's
zstyle ':antidote:home' dir ...being invisible to parent-shell code.antidote homereported the default path and the rebundle checkfile landed there, soantidote updatenever cleared it and the forced rebundle after an update stopped happening. - Fix a static
.zwcbuilt by a different Zsh version never being rebuilt, leaving every shell on that version silently parsing the source. - Fix
kind:autoloadfunctions never loading underksh_arrays. The generated script indexed$fpath[1], which is not a subscript under that option, soautoloadgot no arguments. - Fix nested dispatch (
loadcallingbundle) dropping the user'sKSH_ARRAYSandSH_GLOB. - Fix
ANTIDOTE_CONFIGnot crossing the process boundary, and an exportedANTIDOTE_TMPDIRbeing clobbered byTMPDIR. - Fix
antidote updateand bundle zcompilation failing whenANTIDOTE_HOMEcontains spaces. - Fix
antidote installwriting:valuegarbage to the plugins file for unknown long flags. It now errors. - Fix a
preset:not carrying across dynamic-modeantidote bundlecalls. - Fix bundles that failed to parse still being cloned, and parse errors on a path-style
using:line being lost with the dropped entry. - Add misc/grammar.md documenting the plugins file format: tokenization, directives, annotations, bundle type resolution, and errors. Document
using:andpreset:in theantidote-bundleman page and the syntax highlighter. - Internal: discover parser contexts by name instead of listing each by hand in four places, where a missed edit failed silently.
Full Changelog: https://github.com/mattmc3/antidote/compare/v2.2.2...v2.3.0
- Add a
- v2.2.22026-08-04 · 2026-08-04 21:41 UTC
查看更新说明
[v2.2.2]
- Fix git's own output during a clone leaking into the generated static file, where a line like
warning: redirecting to https://...becomes a command at shell startup. - Fix
pre:andpost:hooks not running forkind:clonebundles. Clone-only bundles still emit no load script unless a hook is present. - Fix dynamic-mode heredoc bundles leaking
__adote_script=''to stdout at shell startup. - Fix concurrent
antidote loadshells racing while rebuilding the same static file. Rebuilds now use per-process temp files, fall back to the last known-good static file on failure, and clean up stale temp files from interrupted builds. - Improve color detection by asking terminfo for terminal color support, honoring
FORCE_COLOR, and treatingCLICOLOR=0as an opt-out. - Speed up internal helpers by replacing fork-heavy paths with Zsh builtins for bundle discovery, JSON escaping, and command checks.
- Add test fixtures for submodules and non-
maindefault branches, covering clone/update paths that were previously untested. - Update the architecture guide with cloning and update sequence diagrams and refreshed implementation notes.
Full Changelog: https://github.com/mattmc3/antidote/compare/v2.2.1...v2.2.2
- Fix git's own output during a clone leaking into the generated static file, where a line like
- v2.2.12026-07-28 · 2026-07-28 14:08 UTC
查看更新说明
[v2.2.1]
- Fix a cold dynamic-mode startup stalling on bundles with a big history.
- Fix
antidote updateintermittently failing withfatal: Cannot rebase onto multiple branchesright after a fresh clone (#273). Git appends toFETCH_HEADwithout locking it, so the background deepen started by a clone could corrupt whatgit pullread on the same repo. Update now rebases onto the remote-tracking ref instead ofFETCH_HEAD. - Fix
antidote updatefailing on a bundle whose shallow clone is grafted so git cannot see its commit as an ancestor of upstream. The rebase replayed commits that were already upstream and conflicted; update now takes upstream as-is for that case, keeping local changes that no longer apply in the stash rather than writing conflict markers into a plugin file. - Fix
antidote updateprinting no commit list under theupdated:line whenever the old commit had no parent in the clone, which is any shallow bundle and any repo updated from its root commit. The list also no longer repeats the commit you were already on. - Fix antidote commands failing with
function definition file not foundafter a package manager upgrade (#271). Setup resolved its own install path through symlinks, so a Homebrew shell recorded the versioned keg directory instead of the stableshare/antidotelink. Upgrading deleted that keg out from under every running shell, breaking any function not yet autoloaded.
- v2.2.02026-07-27 · 2026-07-27 03:30 UTC
查看更新说明
[v2.2.0]
- Add
zstyle ':antidote:bundle:*' min-age <days>to keep bundles a fixed number of days behind upstream, giving a bad push time to be noticed before it reaches your shell. Clones and updates stop at the newest commit that has been upstream long enough. A plugin with no commit that old is still installed at its latest commit. Pinned bundles ignore it. Commit dates are attacker-controlled, so treat this as a cushion, not a supply chain guarantee, and usepin:when you need a fixed commit. - Clone bundles shallow, then deepen them with a background fetch, so the first run stays fast but full history is available afterward. Set
zstyle ':antidote:bundle:*' shallow 'yes'to hold a bundle at its shallow clone. - Make dynamic bundling dramatically faster by caching each
antidote bundleline's generated script under$ANTIDOTE_HOME/.dynamic, sosource <(antidote init)shells reuse the cached script instead of forking a subprocess per line. On local fixtures that takes a warm bundle line from roughly 30ms to under 0.5ms! Setzstyle ':antidote:dynamic' zcompile 'yes'to also compile the cached scripts. - Fix a theme repo sourcing every
.zsh-themeit ships when none is named for the repo directory. Bundlingromkatv/powerlevel10ksourced bothpowerlevel10k.zsh-themeand thepowerlevel9kcompatibility shim. - Fix
antidote updatereporting success when a worker failed, and fix bundles with the same short name overwriting each other's reports. - Fix
antidote update --dry-rundeepening shallow clones, a permanent side effect from a dry run, and repair the temp dir cleanup trap. - Fix
antidote updatetreating ashallow.lockheld by a background deepen as an update failure rather than contention. - Fix
antidote loaddiscarding the existing static file when regeneration failed.
Full Changelog: https://github.com/mattmc3/antidote/compare/v2.1.1...v2.2.0
- Add
- v2.1.12026-07-26 · 2026-07-26 15:52 UTC
查看更新说明
[v2.1.1]
- Fix
antidote.zshexiting the shell when sourced from compiled.zwcbytecode (#270). Zsh reports the eval context asfilecoderather thanfilein that case, so the sourced check fell through to the CLI branch. - Fix
antidote bundleexiting 1 for bundle files containing onlykind:cloneentries, and make it exit non-zero when a clone or a parallel script generation job fails. Previously those failures printed to stderr but still exited 0. - Fix
antidote loadreturning 0 when the static file was missing or could not be sourced. - Fix
antidote updateprinting "self-update complete" after a failed self-update. It now reports the error and returns 1. - Fix
antidote purgecommenting out unrelated bundles in the plugins file when one bundle name was a prefix of another (eg: purgingfoo/baralso matchedfoo/barbaz). Names now match literally, whole word only. - Fix
antidote installsilently writing:valuegarbage to the plugins file for unknown short flags. It now fails with an error. - Fix
antidote snapshot restorereporting success when restores failed, and fix pinned restores always failing under ephemeral pins. - Fix
antidote list --jsonlproducing invalid JSON when values contained quotes, backslashes, or control characters. - Fix
antidote-dispatchandantidote-helpleaking private usage helper functions into the user's shell. - Fix the non-Zsh guard misreporting the shell name, and tolerate a
pswithout-p(busybox). - Speed up
antidote updateby only probing for bat when the snapshot picker actually runs. - Ehance completions:
installgains arg specs, a--pinvalue, and bundle positionals;pathcompletes installed bundles;helpcompletes topics;loadandsnapshotcomplete files. - Remove unused git config isolation from
updatethat would have broken credential helpers andinsteadOfrewrites had it ever taken effect. - Add an ARCHITECTURE.md guide covering file layout, the parent/subprocess boundary, and the bundle pipeline.
- Internal: rename globals so
ANTIDOTE_*means externally managed only, decompose oversized functions, and makeantidote.zshclean underwarn_nested_var. No behavior changes. - Internal: migrate the test suite from clitest markdown files to bats (
tests/bats), with network tests split out underjust test-real.
Full Changelog: https://github.com/mattmc3/antidote/compare/v2.1.0...v2.1.1
- Fix
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
antidote
Meet antidote, a feature-complete Zsh implementation of the legacy Antibody plugin manager, which in turn was derived from Antigen. It not only aims to provide continuity for those legacy plugin managers, but also to delight new users with high-performance, easy-to-use Zsh plugin management.
Usage
Basic usage should look really familiar to you if you have used antibody or antigen.
Bundles (aka: Zsh plugins) are stored in a file typically called .zsh_plugins.txt.
# .zsh_plugins.txt
rupa/z # some bash plugins work too
sindresorhus/pure # enhance your prompt
# you can even use Oh My Zsh plugins
getantidote/use-omz
ohmyzsh/ohmyzsh path:lib
ohmyzsh/ohmyzsh path:plugins/extract
# add fish-like features
zsh-users/zsh-syntax-highlighting
zsh-users/zsh-autosuggestions
zsh-users/zsh-history-substring-search
A typical .zshrc might then look like:
# .zshrc
source /path-to-antidote/antidote.zsh
antidote load ${ZDOTDIR:-$HOME}/.zsh_plugins.txt
The full documentation can be found at https://antidote.sh.
Help getting started
If you want to see a full-featured example Zsh configuration using antidote, you can have a look at this example zdotdir project. Feel free to incorporate code or plugins from it into your own dotfiles, or you can fork it to get started building your own Zsh config from scratch driven by antidote.
Installation
Install with git
You can install the latest release of antidote by cloning it with git:
# first, run this from an interactive zsh terminal session:
git clone --depth=1 https://github.com/mattmc3/antidote.git ${ZDOTDIR:-$HOME}/.antidote
Install with a package manager
antidote may also be available in your system's package manager:
- macOS homebrew:
brew install antidote - Arch AUR:
yay -S zsh-antidote - Nix Home-Manager :
programs.zsh.antidote.enable = true;
Performance
antidote supports ultra-high performance plugin loads using a static plugin file. It also allows deferred loading for plugins that support it.
# .zsh_plugins.txt
# some plugins support deferred loading
zdharma-continuum/fast-syntax-highlighting kind:defer
zsh-users/zsh-autosuggestions kind:defer
zsh-users/zsh-history-substring-search kind:defer
# .zshrc
# Lazy-load antidote and generate the static load file only when needed
zsh_plugins=${ZDOTDIR:-$HOME}/.zsh_plugins
if [[ ! ${zsh_plugins}.zsh -nt ${zsh_plugins}.txt ]]; then
(
source /path-to-antidote/antidote.zsh
antidote bundle <${zsh_plugins}.txt >${zsh_plugins}.zsh
)
fi
source ${zsh_plugins}.zsh
bat syntax highlighting
If you use bat, antidote includes a syntax definition
for .zsh_plugins.txt files. To install it:
bat_syntax_dir="$(bat --config-dir)/syntaxes"
mkdir -p "$bat_syntax_dir"
curl -fsSL https://raw.githubusercontent.com/mattmc3/antidote/main/misc/zsh_plugins.sublime-syntax \
-o "$bat_syntax_dir/zsh_plugins.sublime-syntax"
bat cache --build
Benchmarks
You can see how antidote compares with other setups here.
Plugin authors
If you authored a Zsh plugin, the recommended snippet for antidote is:
antidote install gh_user/gh_repo
If your plugin is hosted somewhere other than GitHub, you can use this:
antidote install https://bitbucket.org/bb_user/bb_repo
Credits
A big thank you to Carlos for all his work on antibody over the years.