leanpack.nvim provides multiple lazy loading mechanisms to optimize Neovim startup time.
Lazy loading defers plugin activation until needed. This reduces startup time by only loading plugins when you use their features.
leanpack.nvim implements four lazy loading trigger types:
- Event - Load when a Neovim event fires
- Command - Load when a user command is called
- Keymap - Load when a key is pressed
- Filetype - Load when a file type is detected
Load a plugin when a Neovim event occurs.
return {
'plugin/name',
event = 'EventName',
}| Event | Description |
|---|---|
VeryLazy |
After UIEnter (default for lazy plugins) |
BufReadPre |
Before reading a buffer |
BufReadPost |
After reading a buffer |
BufNew |
For new buffers |
TabEnter |
When switching tabs |
InsertEnter |
When entering insert mode |
CmdlineEnter |
When entering command line |
-- Load on InsertEnter event
return {
'windwp/nvim-autopairs',
event = 'InsertEnter',
opts = {},
}
-- Load on multiple events
return {
'user/plugin',
event = { 'InsertEnter', 'CmdlineEnter' },
}
-- Load with file pattern
return {
'user/lua-syntax',
event = 'BufReadPre *.lua',
}
-- Load very lazily (after startup)
return {
'user/plugin',
event = 'VeryLazy',
}Load a plugin when a user command is invoked.
return {
'plugin/name',
cmd = 'CommandName',
}-- Single command
return {
'nvim-tree/nvim-tree.lua',
cmd = { 'NvimTreeToggle', 'NvimTreeFocus' },
opts = {},
}
-- Multiple commands
return {
'user/plugin',
cmd = { 'Cmd1', 'Cmd2', 'Cmd3' },
}- leanpack.nvim creates a temporary stub command
- When the user runs the command, the stub loads the plugin
- The stub deletes itself and runs the actual command
Load a plugin when a key is pressed.
return {
'plugin/name',
keys = 'keyseq',
}Or with options:
return {
'plugin/name',
keys = {
{ 'keyseq', function() ... end, mode = 'n', desc = 'Description' },
},
}-- Simple key sequence
return {
'folke/flash.nvim',
keys = 's',
}
-- With function
return {
'folke/flash.nvim',
keys = {
{ 's', function() require('flash').jump() end, mode = { 'n', 'x', 'o' }, desc = 'Flash' },
{ 'S', function() require('flash').treesitter() end, mode = { 'n', 'x', 'o' }, desc = 'Flash Treesitter' },
},
}
-- With command
return {
'user/plugin',
keys = { '<leader>p', '<cmd>PluginCmd<cr>', mode = 'n', desc = 'Run Plugin' },
}- leanpack.nvim creates a temporary keymap
- When the key is pressed, the plugin loads
- The keymap deletes itself and re-feeds the keystrokes
Load a plugin when a file type is detected.
return {
'plugin/name',
ft = 'filetype',
}-- Single filetype
return {
'rust-lang/rust.vim',
ft = 'rust',
}
-- Multiple filetypes
return {
'user/plugin',
ft = { 'lua', 'vim', 'python' },
}When using filetype triggers, leanpack.nvim automatically re-triggers buffer events to ensure LSP/Treesitter attaches:
-- After loading, leanpack.nvim does:
vim.api.nvim_exec_autocmds("BufReadPre", { buffer = bufnr })
vim.api.nvim_exec_autocmds("BufReadPost", { buffer = bufnr })
vim.api.nvim_exec_autocmds("FileType", { buffer = bufnr })This ensures that newly loaded plugins analyze the current buffer.
Load a plugin automatically when its main Lua module is required.
Leanpack natively intercepts require calls matching either:
- The explicit
mainfield defined in the spec. - The implicitly auto-detected main module name.
return {
'nvimtools/none-ls.nvim',
-- Because `opts` is here, if no `main` is present leanpack deduces it as `null-ls`.
-- Thus, `require('null-ls')` automatically triggers loading.
opts = {},
}
-- Or with explicit main
return {
'user/repo',
main = 'custom_module', -- require('custom_module') will load this!
}- leanpack.nvim installs a non-intrusive lookup loader in
package.loadersat startup. - When code calls
require('module_name'), it resolves against the plugin'smainreference. - If it matches an unloaded plugin, it loads it immediately and caches the module.
| Trigger | Best For | Overhead |
|---|---|---|
| Event | General features | Very low |
| Command | CLI tools | Very low |
| Keymap | User-facing features | Low |
| Filetype | Language tools | Low |
| Module | Autoload via require | Very low |
- UI plugins → Command or keymap trigger
- Language servers → Filetype trigger
- General plugins → Event trigger
- Colorscheme → No trigger (load eagerly)
-- Load colorschemes early
return {
'folke/tokyonight.nvim',
priority = 1000,
config = function()
vim.cmd('colorscheme tokyonight')
end,
}Make sure dependencies are loaded before their parent:
return {
'nvim-telescope/telescope.nvim',
cmd = 'Telescope',
dependencies = {
'nvim-lua/plenary.nvim',
},
}leanpack.nvim's lazy loading is optimized:
- Self-cleaning package.loaders - Installs a lightweight loader at position 2 for module-based lazy loading, then auto-removes it once all module-triggered plugins are loaded (unlike lazy.nvim's permanent interception)
- Self-destructing triggers - Autocmds, commands, and keymaps delete themselves after first trigger
- O(V + E) dependency resolution - Efficient topological sorting
- Commands - CLI reference
- Troubleshooting - Common issues