A thin layer on top of Neovim's native vim.pack, adding support for lazy-loading and the widely adopted lazy.nvim-like declarative spec.
Why zpack? | Commands | Spec Examples | Spec Reference | Tips & Migration
-- install with vim.pack directly
vim.pack.add({ 'https://github.com/zuqini/zpack.nvim' })
-- Make sure to setup `mapleader` and `maplocalleader` before loading
-- zpack.nvim so that keymaps referenced from zpack.Spec are aware
vim.g.mapleader = " "
vim.g.maplocalleader = "\\"
-- automatically import specs from `./lua/plugins/`
require('zpack').setup()
Under the default setting, create plugin specs in lua/plugins/:
lua/
plugins/
treesitter.lua
lsp.lua
...
Each file should return a spec or list of specs (see spec examples or spec reference):
-- ./lua/plugins/fundo.lua
return {
'kevinhwang91/nvim-fundo',
dependencies = { "kevinhwang91/promise-async" },
cond = not vim.g.vscode,
version = 'main',
build = function() require('fundo').install() end,
opts = {},
config = function(_, opts)
vim.o.undofile = true
require('fundo').setup(opts)
end,
}
zpack provides a single user command, :ZPack, with subcommands. Rename via cmd_name — a short name like Z or Zp is recommended for ease of use (:Z update, :Zp clean).
| Command | Description |
|---|---|
:ZPack[!] update [plugin] |
Update all plugins, or one; ! skips the confirm buffer |
:ZPack[!] restore [plugin] |
Restore plugins to the lockfile state; ! skips the confirm buffer |
:ZPack clean |
Remove plugins no longer in your spec |
:ZPack[!] build [plugin] |
Run a plugin's build hook; ! runs every plugin's build hook |
:ZPack[!] load [plugin] |
Load an unloaded plugin; ! loads all unloaded plugins |
:ZPack[!] delete [plugin] |
Remove a plugin; ! removes all plugins |
:ZPack sync |
Bulk update + clean (lazy.nvim parity) |
:ZPack reload {plugin} |
Re-source a plugin (lazy.nvim parity) |
require('zpack').setup({
-- { import = 'plugins' } -- default import spec if not explicitly passed in via [1] or spec
defaults = {
confirm = true, -- set to false to skip vim.pack install prompts (default: true)
cond = nil, -- global condition for all plugins, e.g. not vim.g.is_vscode (default: nil)
lazy = false, -- make every spec lazy-load by default unless it sets lazy=false (lazy.nvim parity, default: false)
version = nil, -- default version applied when a spec has no version/sem_version/branch/tag/commit (lazy.nvim parity, default: nil)
},
performance = {
vim_loader = true, -- enables vim.loader for faster startup (default: true)
},
cmd_name = 'ZPack', -- name of the user command (default: 'ZPack'). Use as: :ZPack update, :ZPack clean, etc.
-- set a shorter name like 'Z' or 'Zp' for fewer keystrokes (:Z update, :Zp clean)
})
Plugin-level settings always take precedence over defaults.
-- automatically import specs from `./lua/plugins/`
require('zpack').setup()
-- or import from a custom path `./lua/a/b/plugins.lua` or `./lua/a/b/plugins/`
require('zpack').setup({ { import = 'a.b.plugins' } })
-- or add your specs inline in setup
require('zpack').setup({
{ 'neovim/nvim-lspconfig', config = function() ... end },
...
{ import = 'plugins.mini' }, -- or additionally import from `./lua/plugins/mini/`
})
-- or via the spec field
require('zpack').setup({
spec = {
{ 'neovim/nvim-lspconfig', config = function() ... end },
...
},
})
Neovim 0.12+ includes a built-in package manager (vim.pack) that handles plugin installation, updates, and version management. zpack is a thin layer that adds lazy-loading capabilities and support for a lazy.nvim-like declarative spec while completely leveraging the native infrastructure.
vim.packvim.pack — cloning, updates, lockfile, and version management. Your editor stays aligned with Neovim core's design philosophy and evolves with itvim.pack without the frillszpack might be for you if:
vim.pack as-is, but you miss lazy-loading, build hooks, plugin management commands, or drop-in lazy plugin specsAs a thin layer, zpack does not provide:
dev = true rewrites a spec's source to a local checkout under
setup({ dev = { path } }); live file-watch is out of scope. :ZPack reload {plugin} is a manual command, not an autocmd-driven reload.)If you're a lazy.nvim user, see Migrating from lazy.nvim
See Spec Examples for a full set of examples covering lazy-loading, version pinning, build hooks, dependencies, and more.
See Spec Reference for the full spec definition, including zpack.Plugin, zpack.EventSpec, and zpack.KeySpec.
See Tips & Migration for lazy.nvim migration guide and compatibility notes for popular plugins (Snacks.nvim dashboard, noice.nvim, etc.).
See Public API for the supported introspection surface used by third-party tooling like dashboards and status UIs. Also available as :help zpack-public-api.
zpack's spec design and several features are inspired by lazy.nvim. Credit to folke for the excellent plugin manager that influenced this project.
zpack's logo is designed by DodolCat.