Imngzx/resonance.nvim

website github github
plugin-manager
stars 16
issues 0
subscribers 0
forks 0
CREATED

UPDATED


πŸ”Š Resonance.nvim

An optimized, minimalist, and zero-dependency lazy-loader and vim.pack wrapper for Neovim (0.13+).

Resonance.nvim is born out of a desire for extreme performance and simplicity. It strips away the bloat of traditional package managers while keeping the most powerful features: lazy-loading, automatic build hooks, and an elegant UI.

❀️Special Thanks to: CWorld1.

✨ Features

  • Zero Dependencies: Works out of the box. Native UI fallback is provided if you prefer a minimalist setup.
  • Pretty UI: Gracefully upgrades its UI and search capabilities if snacks.nvim or nui.nvim are detected.
  • Advanced Lazy Loading: Load plugins on Event, Cmd, Keys, or FileType.
  • Automatic Build Hooks: Intercepts PackChanged events to automatically run make, cargo, or custom Lua functions when a plugin is installed or updated.
  • Native Update Discovery: Checks pending updates with vim.pack.get() and displays the commits from the installed revision to the resolved target revision.
  • Fast: Built entirely on Neovim's native vim.pack and modern vim.system APIs.

[!TIP] Please enable UI2 for better experience.

Preview Image

https://github.com/user-attachments/assets/f37b574f-6061-493b-95cb-9e9478616b05

Preview Image

Build notifications DAG UI

πŸ“¦ Installation and Configuration

Add this bootstrap snippet to your init.lua. It ensures resonance.nvim is downloaded and prepended to your runtime path on the first run.

-- =====================================================================
-- 🎡 Bootstrap Resonance.nvim
-- =====================================================================
-- You can also use the link from codeberg
local plugin_url = 'https://github.com/Imngzx/resonance.nvim'
local pack_path = vim.fn.stdpath('data') .. '/site/pack/core/opt/resonance.nvim'

if not vim.uv.fs_stat(pack_path) then
  vim.notify('󱑽 Resonating (Downloading resonance.nvim)...', vim.log.levels.INFO)
  vim.system({ 'git', 'clone', '--filter=blob:none', plugin_url, '--branch=main',
    pack_path }):wait()
end

vim.opt.rtp:prepend(pack_path)

-- =====================================================================
-- πŸš€ Configuration
-- =====================================================================
local resonance = require('resonance')
resonance.load({
  'https://github.com/Imngzx/resonance.nvim',
  version = 'main',
  event = 'VimEnter',
  keys = {
    { 'n', '<leader>pL', '<cmd>Resonance<cr>', { desc = '[Float] Resonance UI' } },
  },
  config = function()
    resonance.setup({
      ui = {
        border = 'rounded',
        width = 0.65,
        height = 0.75,
      }
    })
  end
})

-- NOTE: must put this at the end of your init.lua!
resonance.trigger_verylazy()

⚑ Lazy Loading by Events

Because Resonance.nvim uses Neovim's native C-API (nvim_create_autocmd) under the hood, it supports all native Neovim events out of the box.

You can define events as a string, a table of multiple strings, or a detailed User event table.

1. Native Neovim Events

Here are the most commonly used native events for lazy-loading plugins:

  • Startup and UI: VimEnter, UIEnter
  • File and Buffer: BufReadPre, BufReadPost, BufNewFile, BufEnter
  • Mode Changes: InsertEnter, CmdlineEnter, VisualEnter
  • Others: CursorMoved, FocusGained, TextYankPost

Examples:

-- Single event
event = "VimEnter"

-- Multiple events
event = { "BufReadPost", "BufNewFile" }

-- Trigger when entering Insert or Command mode (Great for completion plugins)
event = { "InsertEnter", "CmdlineEnter" }

2. Custom (User) Events

For ecosystem-specific events (like the famous VeryLazy triggered by resonance.trigger_verylazy()), you must use the strict Neovim native format for User autocmds:

Examples:

-- Trigger on VeryLazy
event = { "User", pattern = "VeryLazy" }

-- Trigger on other custom patterns (e.g. Mason load)
event = { "User", pattern = "MasonLoaded" }

Package Specs

Resonance accepts native vim.pack fields: src, name, version, and data. A source can also be supplied as the first positional value or through the url compatibility alias; Resonance normalizes both to src before calling vim.pack.add().

Each entry needs at least one lazy trigger: event, cmd, keys, or ft.

πŸ“ Complete Example

local resonance = require('resonance')

resonance.load({
  {
    src = "https://github.com/<author>/<plugin1_name>",

    dependencies = "https://github.com/<author>/<plugin2_name>",

    build = 'make', -- npm i or others based on plugin's docs

    cmd = {'cmd1', 'cmd2'},

    keys = {
      { 'n', '<leader>Tg', '<cmd>cmd1<CR>', { desc = 'Open something' } },
      { 'n', '<leader>TL', '<cmd>cmd2<CR>', { desc = 'Do something' } },
    },

    event = { "BufReadPre", "BufNewFile" },
    -- For VeryLazy, use: event = { "User", pattern = "VeryLazy" }
    config = function()

      local name = require('plugin1_name')

      name.setup({
      -- Config here...
      })

    end
  },

  { -- another plugin...},

  { -- another plugin...},
})

Complex example.

Simple example.

πŸ“Š Dashboard Resonance.stats integration

Preview Image

Resonance provides a clean, zero-hack API to retrieve plugin statistics and exact startup times, heavily inspired by lazy.nvim.

Because Resonance locks the "Time to UI" exactly at the first moment require('resonance').stats() is called, placing this in your dashboard's render function guarantees the most accurate startup time measurement.

The stats() API

local stats = require("resonance").stats()
-- returns:
-- {
--   count = 37,        -- Total number of plugins managed
--   loaded = 20,       -- Plugins loaded at startup
--   startuptime = 24.5,-- Startup time in milliseconds (Time to UI)
--   times = { ... }    -- Table containing load times for individual plugins
-- }

For snacks.nvim

require("snacks").setup({
  dashboard = {
    sections = {
      { section = 'header' },
      { section = 'keys', gap = 1, padding = 1 },
      function()
        local stats = require("resonance").stats()
        local ms = string.format("%.2f ms", stats.startuptime)
        return {
          align = 'center',
          text = {
            { "󱐋 ", hl = "Special" },
            { stats.loaded .. " / " .. stats.count, hl = "Special" },
            { " plugins loaded in ", hl = "Comment" },
            { ms, hl = "Special" },
          },
          padding = 1,
        }
      end,
    }
  }
})

For alpha.nvim

local alpha = require("alpha")
local dashboard = require("alpha.themes.dashboard")

-- ... (your header and buttons configuration) ...

-- Dynamically generate the footer
dashboard.section.footer.val = function()
  local stats = require("resonance").stats()
  local ms = string.format("%.2f ms", stats.startuptime)
  return "󱐋 " .. stats.loaded .. " / " .. stats.count .. " plugins loaded in " .. ms
end
-- Optional: apply highlight group to footer
dashboard.section.footer.opts.hl = "Comment"

alpha.setup(dashboard.opts)

For mini.starter

local starter = require("mini.starter")

starter.setup({
  -- ... (your items and hooks) ...

  footer = function()
    local stats = require("resonance").stats()
    local ms = string.format("%.2f ms", stats.startuptime)
    return "󱐋 " .. stats.loaded .. " / " .. stats.count .. " plugins loaded in " .. ms
  end
})

[!TIP] If you want a very "honest" startuptime, please add this on top of your init.lua.

-- enable this for a "very" honest startuptime :)
_G.start_time = vim.uv.hrtime()

⌨️ UI Keymaps

  • U : Update all plugins (vim.pack.update()).
  • u : Update the plugin at the cursor (vim.pack.update()).
  • dd: Delete the plugin at the cursor.
  • c : Check out an available branch, commit, or tag.
  • r : Check for pending updates (vim.pack.get() fetches and resolves package revisions).
  • S : Search inside plugins source code (Powered by Snacks.picker / Telescope / Native vimgrep).
  • g : Check Dependency Graph (DAG) and Event Replay.
  • s : Skip plugin update.
  • D : Open plugin directory.
  • q / Esc : Quit.

License

This project is licensed under the MIT License.