SkillAgentSearch skills...

Lz.n

🦥 A dead simple lazy-loading Lua library for Neovim plugins.

Install / Use

/learn @lumen-oss/Lz.n
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<!-- markdownlint-disable --> <br /> <div align="center"> <a href="https://github.com/lumen-oss/lz.n"> <img src="./lz-n.svg" alt="lz.n"> </a> <p align="center"> <br /> <a href="./doc/lz.n.txt"><strong>Explore the docs »</strong></a> <br /> <br /> <a href="https://github.com/lumen-oss/lz.n/issues/new?assignees=&labels=bug">Report Bug</a> · <a href="https://github.com/lumen-oss/lz.n/issues/new?assignees=&labels=enhancement">Request Feature</a> · <a href="https://github.com/lumen-oss/lz.n/discussions/new?category=q-a">Ask Question</a> </p> <p> <strong> A dead simple lazy-loading library for <a href="https://neovim.io/">Neovim</a> plugins </strong> </div> <!-- markdownlint-restore --> <!-- markdownlint-disable MD028 --> <!-- no blank lines between two block quotes -->

It is intended to be used

  • By users of plugin managers that don't provide a convenient API for lazy-loading (vim.pack, nix, paq-nvim, ...).
  • By plugin managers, to provide a convenient API for lazy-loading (rocks-lazy.nvim, NixVim, ...).

[!NOTE]

Should I lazy-load plugins?

It should be a plugin author's responsibility to ensure their plugin doesn't unnecessarily impact startup time, not yours!

See our "DO's and DONT's" guide for plugin developers.

Regardless, the current status quo is horrible, and some authors may not have the will or capacity to improve their plugins' startup impact.

If you find a plugin that takes too long to load, or worse, forces you to load it manually at startup with a call to a heavy setup function, consider opening an issue on the plugin's issue tracker.

:star2: Features

  • API for lazy-loading plugins on:
    • Events (:h autocmd-events)
    • FileType events
    • Key mappings
    • User commands
    • Colorscheme events
  • Works with:
    • Neovim's built-in :h packpath (:h packadd)
    • Any plugin manager that supports manually lazy-loading plugins by name
  • Configurable in multiple files

:moon: Introduction

lz.n provides abstractions for lazy-loading Neovim plugins, with an API that is loosely based on lazy.nvim, but reduced down to the very basics required for lazy-loading only.

:milky_way: Philosophy

lz.n is designed based on the UNIX philosophy: Do one thing well.

:zzz: Comparison with lazy.nvim

  • lz.n is not a plugin manager, but focuses on lazy-loading only. It is intended to be used with (or by) a plugin manager.
  • The feature set is minimal, to reduce code complexity and simplify the API. For example, the following lazy.nvim features are out of scope:
    • Merging multiple plugin specs for a single plugin (primarily intended for use by Neovim distributions).
    • lazy.nvim completely disables and takes over Neovim's built-in loading mechanisms, including adding a plugin's API (lua, autoload, ...) to the runtimepath. lz.n doesn't. Its only concern is plugin initialization, which is the bulk of the startup overhead.
    • Automatic lazy-loading of Lua modules on require.
    • Automatic lazy-loading of colorschemes. lz.n provides a colorscheme handler in the plugin spec.
    • Heuristics for determining a main module and automatically calling a setup() function.
    • Heuristics for loading plugins on require. You can use lzn-auto-require for that.
    • Plugin spec fields (like lazy.nvim's dependencies) for influencing the order in which plugins are loaded. See also: Plugin dependencies.
    • Abstractions for plugin configuration with an opts table. lz.n provides simple hooks that you can use to specify when to load configurations.
    • Features related to plugin management.
    • Profiling tools.
    • UI.
  • Some configuration options are different.

:pencil: Requirements

  • Neovim >= 0.10.0

:wrench: Configuration

You can override the function used to load plugins. lz.n has the following default:

vim.g.lz_n = {
    ---@type fun(name: string)
    load = vim.cmd.packadd,
}

:books: Usage

require("lz.n").load(plugins)

[!TIP]

  • You can call load() as you would call lazy.nvim's setup(). Or, you can also use it to register individual plugin specs for lazy loading.

  • See also: :h lz.n

[!IMPORTANT]

Since merging configs is out of scope, calling load() with conflicting plugin specs is not supported.

Plugin spec

<!-- markdownlint-disable MD013 --> <!-- markdownlint-disable MD060 -->

| Property | Type | Description | lazy.nvim equivalent | |----------|------|-------------|------------------------| | [1] | string | The plugin's name (not the module name). This is what is passed to the load(name) function. | name[^1] | | enabled | boolean? or fun():boolean | When false, or if the function returns false, then this plugin will not be included in the spec. | enabled | | beforeAll | fun(lz.n.Plugin)? | Always executed before any plugins are loaded. | init | | before | fun(lz.n.Plugin)? | Executed before a plugin is loaded. | None | | after | fun(lz.n.Plugin)? | Executed after a plugin is loaded. | config | | event | string? or {event?:string\|string[], pattern?:string\|string[]}\ or string[] | Lazy-load on event. Events can be specified as BufEnter or with a pattern like BufEnter *.lua. | event | | cmd | string? or string[] | Lazy-load on command. | cmd | | ft | string? or string[] | Lazy-load on filetype. | ft | | keys | string? or string[] or lz.n.KeysSpec[] | Lazy-load on key mapping. | keys | | colorscheme | string? or string[] | Lazy-load on colorscheme. | None. lazy.nvim lazy-loads colorschemes automatically[^2]. | | lazy | boolean? | Lazy-load manually, e.g. using trigger_load. Will disable lazy-loading if explicitly set to false. | lazy | | priority | number? | Only useful for start plugins (not lazy-loaded) to force loading certain plugins first. Default priority is 50. | priority | | load | fun(string)? | Can be used to override the vim.g.lz_n.load() function for an individual plugin. | None. |

<!-- markdownlint-enable MD013 -->

[^1]: In contrast to lazy.nvim's name field, a lz.n.PluginSpec's name is not optional. This is because lz.n is not a plugin manager and needs to be told which plugins to load. [^2]: The reason this library doesn't lazy-load colorschemes automatically is that it would have to know where the plugin is installed in order to determine which plugin to load.

User events

  • DeferredUIEnter: Triggered when load() is done and after UIEnter. Can be used as an event to lazy-load plugins that are not immediately needed for the initial UI[^3].

[^3]: This is equivalent to lazy.nvim's VeryLazy event.

keymap(<plugin>).set

To provide a familiar UX that is as close as possible to the built-in Neovim experience, lz.n has a helper function that lets you lazy-load plugins with keymap triggers using the same signature as :h vim.keymap.set().

Examples:

-- You can pass in a plugin spec or a plugin's name.
local keymap = require("lz.n").keymap({
  "telescope.nvim",
  cmd = "Telescope",
  after = function()
    require("telescope").setup()
  end,
})
-- Now you can create keymaps that will load the plugin using
-- the same UX as vim.keymap.set().
keymap.set("n", "<leader>tp", function()
  require("telescope.builtin").find_files()
end)
keymap.set("n", "<leader>tg", function()
  require("telescope.builtin").live_grep()
end)

Plugin dependencies

This library does not provide a lz.n.PluginSpec field like lazy.nvim's dependencies. The rationale behind this is that you shouldn't need it. Instead, you can utilise the trigger_load function in a before or after hook.

However, we generally do not recommend this approach. Most plugins primarily rely on the Lua libraries of other plugins, which can be added to the :h package.path without any noticeable impact on startup time.

Relying on another plugin's plugin or after/plugin scripts is considered a bug, as Neovim's built-in loading mechanism does not guarantee initialisation order. Forcing users to think about the order in which they load plugins that extend or depend on each other is even worse. We strongly suggest opening an issue or submitting a PR to fix this upstream. However, if you're looking for a temporary workaround, you can use trigger_load in a before or after hook, or bundle the relevant plugin configurations.

[!NOTE]

  • This does not work with plugins that rely on after/plugin, such as many nvim-cmp sources, because Neovim's :h packadd does not source after/plugin scripts after startup has completed. We recommend bundling such plugins with their extensions, or sourcing the after scripts manually. In the spirit of the UNIX philosophy, lz.n does not provide any functions for sourcing plugin scripts. For sourcing after/plugin directories manually, you can use rtp.nvim. Here is an example.

  • Why not p

View on GitHub
GitHub Stars261
CategoryDevelopment
Updated7h ago
Forks11

Languages

Lua

Security Score

100/100

Audited on Apr 5, 2026

No findings