How to Conditionally Enable Plugins in Neovim with Lazy.nvim

Lazy.nvim lets you conditionally enable plugins using the cond and enabled keys in your plugin specification, where enabled filters plugins once at startup and cond checks conditions right before loading.

To keep your Neovim configuration fast and portable, you need to load plugins only when they are actually needed or available. In the jdhao/nvim-config repository, conditional plugin activation is implemented using Lazy.nvim's cond and enabled options to handle different operating systems, external dependencies, and UI contexts.

Understanding the cond and enabled Keys

Lazy.nvim processes your plugin list in two stages, giving you fine-grained control over what gets loaded and when.

The enabled Key: Static Startup Filtering

Use enabled when you want to completely omit a plugin from Neovim's runtime based on conditions that will not change during the session. You can assign a Boolean value or a function that returns true or false. Lazy.nvim evaluates this once during startup; if the result is false, the plugin is discarded entirely and never appears in your :Lazy list.

The cond Key: Dynamic Loading Conditions

Use cond when you want to defer the decision until the plugin is about to load. This key accepts a function that Lazy.nvim evaluates immediately before triggering the plugin (on an event, cmd, keys, or other lazy-loading trigger). Returning false aborts the load for that session, but the plugin remains in the manager's index and can be loaded manually later.

Practical Examples from jdhao/nvim-config

The file lua/plugin_specs.lua demonstrates both approaches for different scenarios.

Skip UI Plugins When Running Inside Firenvim

When Neovim runs as a browser editor via Firenvim, heavy UI plugins like status lines are unnecessary. The configuration uses cond to check vim.g.started_by_firenvim at the moment the plugin would load:

{
  "nvim-lualine/lualine.nvim",
  event = "BufRead",
  cond = function()
    return not vim.g.started_by_firenvim
  end,
  config = function() require("config.lualine") end,
}

This pattern appears in lua/plugin_specs.lua (lines 18-21), where a helper function firenvim_not_active wraps the same logic.

Load OS-Specific Plugins Like gx.nvim

The gx.nvim plugin opens URLs with the system browser, but the configuration only installs it on Windows or macOS. This uses enabled with a function checking global variables set elsewhere in the config:

{
  "chrishrb/gx.nvim",
  keys = { { "gx", "<cmd>Browse<cr>", mode = { "n", "x" } } },
  enabled = function()
    return vim.g.is_win or vim.g.is_mac
  end,
  config = function() require("config.gx") end,
}

You can find this specification in lua/plugin_specs.lua (lines 48-51).

Require External Dependencies Like ctags

The vista.vim plugin provides symbol navigation but requires ctags to be present on the system. The configuration uses enabled with a utility function to verify the binary exists before adding the plugin to the list:

{
  "liuchengxu/vista.vim",
  cmd = "Vista",
  enabled = function()
    return utils.executable("ctags")
  end,
  init = function()
    -- plugin configuration...
  end,
}

The utils.executable function is defined in lua/utils.lua and checks the system PATH for the executable. This example is located in lua/plugin_specs.lua (lines 75-77).

How Conditional Loading Works Internally

Lazy.nvim handles conditional plugins in four distinct steps according to the jdhao/nvim-config implementation:

  1. Specification Parsing: Lazy.nvim reads the plugin_specs table from lua/plugin_specs.lua.
  2. Startup Filtering: For each entry, if enabled is present, it evaluates the Boolean or function immediately. When false, Lazy.nvim removes the entry from the plugin list entirely.
  3. Pre-load Checks: If the entry survives, Lazy.nvim evaluates cond (if present) immediately before loading the plugin on its designated trigger (e.g., BufRead, CmdlineEnter).
  4. Load Abortion: Returning false from cond prevents the plugin from loading for that session, though it remains available for manual :Lazy load commands.

This two-stage filtering ensures that static conditions (OS type, missing binaries) skip processing overhead entirely, while dynamic conditions (Firenvim detection) allow context-aware loading without polluting your startup time.

Summary

  • Use enabled in your plugin spec to discard plugins permanently at startup based on static conditions like operating system or missing external tools.
  • Use cond to evaluate dynamic conditions right before a plugin loads, ideal for context-dependent UI components.
  • Reference lua/plugin_specs.lua in jdhao/nvim-config for real-world implementations of both patterns.
  • Leverage helper functions like utils.executable in lua/utils.lua to check for system binaries when using enabled.
  • Remember that enabled functions run once during Neovim startup, while cond functions run every time the plugin's lazy-loading trigger fires.

Frequently Asked Questions

What is the difference between cond and enabled in Lazy.nvim?

enabled evaluates once during startup and completely removes the plugin from the internal list if it returns false, saving memory and processing time. cond evaluates immediately before the plugin would load on its specified trigger; returning false aborts that specific load attempt but keeps the plugin registered so you can load it manually later.

Can I use enabled to check for external binaries like ctags?

Yes. Define a function for enabled that returns the result of a utility check such as utils.executable("ctags"), as demonstrated in lua/plugin_specs.lua (lines 75-77). If the binary is missing, Lazy.nvim omits the plugin entirely, preventing configuration errors.

Where should I define conditional logic for my Neovim plugins?

Place your plugin specifications in a central file like lua/plugin_specs.lua and define cond or enabled keys directly in each plugin's table. For reusable condition logic, create helper functions in lua/utils.lua and reference them in your specs to keep the configuration DRY and maintainable.

Does cond affect Lazy.nvim's startup time optimization?

No. Because cond is evaluated only when a plugin's lazy-loading trigger (such as an event or cmd) fires, it does not impact the initial startup time. However, since enabled runs at startup, complex functions there can add milliseconds to launch time; keep those checks lightweight or cache results in global variables.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →