github github
stars 34
issues 1
subscribers 2
forks 1



last month


lazyflex.nvim is an add-on for lazy.nvim, a modern plugin manager for Neovim.

Its main objective is to make it easier to test and troubleshoot a Neovim configuration.



The code used in the demo can be found here


  • Easier troubleshooting/testing from one central location.
    • Enable/disable multiple plugins by keyword.
    • Define and use custom presets for your own configuration.
    • Has presets for each default plugin module in LazyVim.
    • Has options to skip loading the configuration modules (options, autocmds, keymaps) provided by LazyVim
  • Helps to verify the independence of the components in the configuration.
  • When creating an issue, facilitates writing a concise reproducible configuration.
    • Contains examples for minimal configurations using lazyflex.




The plugin must be the first item in the spec!

  spec = {
      version = "*",
      cond = true,
      import = "lazyflex.hook",
      opts = {},
    -- your plugins:
    -- { "LazyVim/LazyVim", import = "lazyvim.plugins" },
    -- { import = "plugins" },

Note: The cond property in the snippet above is practical for quickly toggling lazyflex on or off, whilst still keeping the plugin installed. Lazyflex is heavily optimized, and can also be kept enabled.

Note: It is not possible to configure multiple fragments of the plugin.

Note: See examples/lazyflex_spec.lua for a more complete lazyflex spec.




  1. Returns immediately when there are no keywords or presets supplied to enable or disable
  2. Only operates on plugins that are not unconditionally disabled(plugin.enabled = false)

Important properties

  • filter_modules.kw: when enabled, only import a selection of the modules in use, thereby reducing the number of plugins to consider. See lazy.nvim's import
  • kw: a list of words matching names of plugins.
  • preset: a predefined list of words matching names of plugins
  • enable_match:
    • true(enable incrementally, default): enable all plugins that match keywords, disable the others.
    • false(disable incrementally): disable all plugins that match keywords, enable the others
  • override_kw: invert enable_match on a plugin when its name has a match in both this list of words and in kw including presets

When using presets: References to a non-existing preset will be ignored.


Important: The name of the colorscheme must be in the keywords when enable_match = true


  1. Add the name to property kw in the opts: kw = { "toky" }
  2. Add the name to property kw_always_enable in the opts: kw_always_enable = { "toky" }
  3. When using LazyVim: Use the colorscheme preset.
  4. When using custom presets: Create a colorscheme preset.

Use cases

Using a personal configuration

The plugin can be used when the user's configuration is not build upon a community setup like LazyVim. It is possible to configure custom presets.

Using a community setup like LazyVim

Prerequisite: Add the LazyVim plugin

Reusing specs from a collection of plugins

LazyVim can be used without loading its options, autocommands or keymappings. The settings of the resulting configuration will default to stock Neovim.

Scenario's where this can be useful:

Prerequisite: Add the LazyVim plugin

Add to opts:

lazyvim = { settings = { enabled = false } }


  -- Enable harpoon, plenary and tokyonight. Disable all other plugins.
    import = "lazyflex.hook",
    opts = { kw = { "har", "plen", "tokyo" } },

  -- Disable telescope and harpoon. Enable: all other plugins.
    import = "lazyflex.hook",
    opts = { enable_match = false, kw = { "tele", "har" } },

  -- Only use lazy.nvim, LazyVim, and tokyonight, without LazyVim's settings.
  -- An alternative would be a lazy.nvim spec, addding tokyonight.
    import = "lazyflex.hook",
    opts = {
      lazyvim = { settings = { enabled = false } },
      kw = { "tokyo" },

  -- All plugins except the ones defined in LazyVim's ui module
  -- Plugins: approximately 10 disabled
    import = "lazyflex.hook",
    opts = {
      lazyvim = { presets = { "ui" } },
      enable_match = false,

  -- Enable plugins in LazyVim's editor module and plugins matching `cmp`,
  -- except nvim-spectre(editor), flash.nvim(editor) and cmp_luasnip
  -- Plugins: approximately 30 disabled
    import = "lazyflex.hook",
    opts = {
      lazyvim = { presets = { "editor" } },
      kw = { "tokyo", "cmp" },
      override_kw = { "spectre", "fla", "luasn" },

  -- Enable all plugins, excluding plugins from other modules than
  -- either "lazyvim.plugins" or "plugins"
  -- To do this manually, one would need to comment out all "other" imports...
    import = "lazyflex.hook",
    opts = {
      filter_modules = { enabled = true },
      enable_match = false,

  -- Enable the minimal amount of plugins needed for running neotest-python
    import = "lazyflex.hook",
    opts = {
      filter_modules = { enabled = true, kw = { "py", "test" } },
      lazyvim = { presets = { "treesitter"} },
      kw = { "toky", "test", "plen" },


lazyflex.nvim comes with the following defaults:

  -- when enabled: only import a selection of the modules in use
  filter_modules = {
    enabled = false,
    kw = {}, -- contains keywords for module names to import
    always_import = {}, -- always contains "lazyvim.plugins" and "plugins"

  lazyvim = {
    presets = {}, -- example: { "coding" }: matches all plugins in the coding module

    settings = { -- load lazyvim's settings by default:
      enabled = true, -- quick switch. Disables the three options below:
      options = true, -- use config.options
      autocmds = true, -- use config.autocmds
      keymaps = true, -- use config.keymaps

  user = {
    -- optional: functions implementing presets and change_settings
    get_preset_keywords = nil,
    change_settings = nil,

    presets = {}, -- example, when implemented: { "editor" }

    settings = { -- passed into function change_settings:
      enabled = true, -- quick switch. Disables the three options below:
      options = true,
      autocmds = true,
      keymaps = true,

  -- either enable or disable matching plugins:
  enable_match = true,

  -- keywords matching plugins to always enable:
  kw_always_enable = {}, -- the "lazy" keyword is always included

  -- keywords matching plugins, as specified by the user:
  kw = {}, -- example: "line" matches lualine, bufferline and indent-blankline

  -- when the name of a plugin is matched and also has a match in override_kw:
  -- invert enable_match for that plugin
  override_kw = {},

Custom presets and settings

As an optional step, the user can add custom functions for handling presets and changing settings to the user section in opts. The following functions are used by lazyflex:

  • presets: get_preset_keywords(name, enable_match)
    • name: the name of the preset
    • enable_match: true when enabling, false otherwise
    • returns: a list with keywords or {}
  • settings: change_settings(settings)
    • settings: the settings provided in opts
    • returns: a spec(used by LazyVim) or {}

These functions can be implemented in a separate module in the user's configuration.

Suggestion: Copy the example module examples/lazyflex_collection.lua to the lua folder inside XDG_CONFIG_HOME. On linux, XDG_CONFIG_HOME defaults to ~/.config/nvim

Note: Do not use a folder lazy.nvim is configured to import from.

Example user opts:

user = {
  get_preset_keywords = require("lazyflex_collection").get_preset_keywords,
  change_settings = require("lazyflex_collection").change_settings,
  presets = {},
  settings = {},

Minimal reproducible configurations

There are two examples for writing reproducible configurations using lazyflex:

Lazyflex starter

When starting Neovim for the first time, lazyflex.nvim is not present yet. As a consequence, plugins will be cloned before lazyflex.nvim is activated.

It is possible to avoid cloning plugins that will be not be enabled by cloning lazyflex.nvim first.

See lazyflex starter, a modified LazyVim starter

About enabling and disabling

For each plugin managed by lazy.nvim that is not unconditionally disabled, lazyflex overrides its cond property.

The cond property needs to be set before lazy.nvim starts taking its value into consideration. Therefore, lazyflex operates in the "spec phase". As part of the "spec phase", lazy.nvim requires lazyflex.hook

See: :Lazy profile.

A similar approach can also be found in the following code:



The idea grew over time:


  • lazy.nvim: The architecture, semantics and enhanced possibilities.
  • LazyVim: The concept of a plugin as a collection of other plugins.