# Lazy Loading Strategies in Lazy.nvim: A Complete Guide from jdhao/nvim-config

> Master Lazy.nvim's eight lazy loading strategies event command filetype keymap and conditional triggers to boost your Neovim startup speed. Improve performance now.

- Repository: [jdhao/nvim-config](https://github.com/jdhao/nvim-config)
- Tags: deep-dive
- Published: 2026-03-04

---

**Lazy.nvim supports eight distinct lazy loading strategies—including event-based, command-based, filetype-based, keymap-based, and conditional triggers—that defer plugin initialization until specific runtime conditions are met, significantly improving Neovim startup performance.**

Lazy.nvim has become the de facto plugin manager for Neovim by offering precise control over when plugins are sourced. The jdhao/nvim-config repository demonstrates production-grade implementations of these strategies in [`lua/plugin_specs.lua`](https://github.com/jdhao/nvim-config/blob/main/lua/plugin_specs.lua), where each plugin is configured with specific triggers to minimize startup overhead while maintaining full editor functionality.

## Explicit Lazy Loading with the `lazy` Flag

The most fundamental strategy uses the `lazy` boolean to declare whether a plugin should load immediately or defer. When set to `true`, the plugin waits for other triggers; when `false`, it loads eagerly at startup.

In [`lua/plugin_specs.lua`](https://github.com/jdhao/nvim-config/blob/main/lua/plugin_specs.lua) at lines 25‑26, the configuration explicitly marks completion sources as lazy:

```lua
{"hrsh7th/cmp-nvim-lsp", lazy = true}

```

This flag works in conjunction with other triggers. A plugin with `lazy = true` and no additional specifiers will still load eventually, but combining it with events, commands, or keymaps provides deterministic control over initialization timing.

## Event-Based Lazy Loading

Event-based loading triggers plugin initialization when specific Neovim autocommand events fire. This strategy is ideal for plugins that only need to function during particular editing phases.

The jdhao/nvim-config repository uses `event = "VeryLazy"` for the completion engine at lines 34‑38 of [`lua/plugin_specs.lua`](https://github.com/jdhao/nvim-config/blob/main/lua/plugin_specs.lua):

```lua
{
  "hrsh7th/nvim-cmp",
  event = "VeryLazy",
  -- additional configuration
}

```

Other common events include `BufRead` (triggered when reading a file), `InsertEnter` (when entering insert mode), and `User InGitRepo` for git-specific tools. This approach ensures plugins like status lines or completion engines only load when the user actually begins editing, rather than during initial startup.

## Command-Based Lazy Loading

Command-based loading defers plugins until a specific Ex command is executed for the first time. This strategy suits tools invoked explicitly, such as fuzzy finders or git interfaces.

At lines 15‑17 in [`lua/plugin_specs.lua`](https://github.com/jdhao/nvim-config/blob/main/lua/plugin_specs.lua), Telescope is configured to load only when the `:Telescope` command is called:

```lua
{
  "nvim-telescope/telescope.nvim",
  cmd = "Telescope",
  -- dependencies and configuration
}

```

When the user types `:Telescope find_files`, Lazy.nvim automatically sources the plugin and its dependencies before executing the command. This prevents the fuzzy finder from consuming startup resources when not in use.

## Filetype-Based Lazy Loading

Filetype-based loading restricts plugins to buffers of specific languages or formats. This is essential for language servers, syntax highlighting, and filetype-specific utilities.

The configuration at lines 31‑33 demonstrates this with a Markdown rendering plugin:

```lua
{
  "MeanderingProgrammer/render-markdown.nvim",
  ft = { "markdown" },
  main = "render-markdown",
  opts = {}
}

```

When opening a `.md` file, Neovim detects the `markdown` filetype and triggers Lazy.nvim to load the plugin. This keeps filetype-specific code dormant until actually needed, reducing memory footprint for projects using diverse languages.

## Keymap-Based Lazy Loading

Keymap-based loading activates plugins when specific keystrokes are pressed. This strategy works well for navigation tools and text objects that users invoke manually.

At lines 98‑102 of [`lua/plugin_specs.lua`](https://github.com/jdhao/nvim-config/blob/main/lua/plugin_specs.lua), the Hop motion plugin loads on the `f` keypress:

```lua
{
  "smoka7/hop.nvim",
  keys = { "f" },
  config = function()
    require("config.nvim_hop")
  end
}

```

The plugin remains unloaded until the user attempts to use the `f` motion, at which point Lazy.nvim sources the plugin and executes the configuration function before processing the keystroke.

## Conditional Loading with `cond`

Conditional loading uses a Lua function to determine whether a plugin should load at all. This enables environment-specific configurations, such as disabling GUI-heavy plugins in terminal-only sessions.

Lines 74‑78 of [`lua/plugin_specs.lua`](https://github.com/jdhao/nvim-config/blob/main/lua/plugin_specs.lua) show Lualine configured to load only when not running inside Firenvim:

```lua
local firenvim_not_active = function() return not vim.g.started_by_firenvim end

{
  "nvim-lualine/lualine.nvim",
  event = "BufRead",
  cond = firenvim_not_active,
  config = function()
    require("config.lualine")
  end
}

```

The `cond` function executes during the loading phase; returning `false` prevents the plugin from loading entirely, while `true` allows normal lazy loading to proceed.

## Dependency and Priority Management

While not loading triggers per se, `dependencies` and `priority` influence how and when plugins initialize. Dependencies are installed before the parent plugin and can have their own lazy loading rules.

Lines 40‑52 of [`lua/plugin_specs.lua`](https://github.com/jdhao/nvim-config/blob/main/lua/plugin_specs.lua) demonstrate dependency chains (commented in the source but illustrative):

```lua
{
  "blink.cmp",
  dependencies = {
    "rafamadriz/friendly-snippets",
    -- additional dependencies
  }
}

```

The `priority` field controls load order when multiple plugins share the same trigger. At lines 51‑52, the Modus theme receives high priority to ensure it loads before other UI plugins:

```lua
{"miikanissi/modus-themes.nvim", priority = 1000}

```

Higher numerical values load earlier, ensuring color schemes initialize before status lines or tab bars that depend on color definitions.

## Module-Based and Development Loading

Lazy.nvim supports `module` loading for plugins that should activate when a Lua module is `require`‑d, though jdhao/nvim-config does not currently utilize this strategy. However, the repository does demonstrate **LazyDev** loading at lines 105‑111:

```lua
{
  "folke/lazydev.nvim",
  ft = "lua",
  opts = {
    library = { "lazy.nvim" }
  }
}

```

This provides type annotations and library definitions during Lua development without loading at runtime, using the same lazy mechanism but for development tooling rather than editor features.

## Configuration Architecture

The lazy loading strategies are centralized in [`lua/plugin_specs.lua`](https://github.com/jdhao/nvim-config/blob/main/lua/plugin_specs.lua), which exports a table of plugin specifications. The [`init.lua`](https://github.com/jdhao/nvim-config/blob/main/init.lua) file bootstraps Lazy.nvim and calls `require("lazy").setup({ spec = plugin_specs })`, while [`lua/utils.lua`](https://github.com/jdhao/nvim-config/blob/main/lua/utils.lua) provides helper functions like `firenvim_not_active` for conditional checks.

This architecture separates plugin declarations from implementation logic, allowing each plugin's loading strategy to be adjusted independently without modifying core initialization code.

## Summary

- **Explicit `lazy` flag** controls default loading behavior (`true` for deferred, `false` for eager)
- **Event-based loading** triggers on Neovim autocommands like `VeryLazy`, `BufRead`, or `InsertEnter`
- **Command-based loading** activates when specific Ex commands (`:Telescope`) are executed
- **Filetype-based loading** restricts plugins to specific buffer types (`ft = { "markdown" }`)
- **Keymap-based loading** defers until specific keystrokes are pressed (`keys = { "f" }`)
- **Conditional loading** uses Lua functions (`cond`) to skip plugins based on runtime conditions
- **Dependencies and priority** manage load order and ensure prerequisite plugins are available
- **Development loading** provides type information without runtime overhead

## Frequently Asked Questions

### What is the difference between `lazy = true` and `event = "VeryLazy"`?

Setting `lazy = true` marks a plugin for deferred loading but requires an additional trigger to determine exactly when it loads, while `event = "VeryLazy"` specifically schedules the plugin to load after Neovim finishes startup and enters the main loop. According to the jdhao/nvim-config implementation, `VeryLazy` is the preferred event for UI components that should appear immediately after startup without blocking the initial render.

### How do I lazy load a plugin only for specific filetypes?

Use the `ft` key with a string or table of filetypes in your plugin specification. As shown in [`lua/plugin_specs.lua`](https://github.com/jdhao/nvim-config/blob/main/lua/plugin_specs.lua) lines 31‑33, the render-markdown plugin uses `ft = { "markdown" }` to ensure it only loads when editing Markdown files, keeping it dormant during other editing sessions.

### Can I combine multiple lazy loading triggers for a single plugin?

Yes, Lazy.nvim allows combining triggers such as `event`, `keys`, and `cmd` on the same plugin specification. The plugin loads when **any** of its specified conditions are met first. However, in jdhao/nvim-config, most plugins use a single primary trigger to keep the loading logic predictable and debuggable.

### Where does jdhao/nvim-config define its lazy loading rules?

All lazy loading specifications are centralized in [`lua/plugin_specs.lua`](https://github.com/jdhao/nvim-config/blob/main/lua/plugin_specs.lua), with each plugin entry specifying its loading strategy through keys like `lazy`, `event`, `cmd`, `ft`, `keys`, or `cond`. The [`init.lua`](https://github.com/jdhao/nvim-config/blob/main/init.lua) file bootstraps the Lazy.nvim manager and passes this specification table to `require("lazy").setup()`, while helper functions for conditional logic reside in [`lua/utils.lua`](https://github.com/jdhao/nvim-config/blob/main/lua/utils.lua).