nvim-lightbulb makes Neovim code actions visible without a keymap
VSCode 💡 for neovim's built-in LSP.
At a glance
- What is it?
- nvim-lightbulb is a small Lua plugin for Neovim that shows a marker whenever the language server offers a code action at the cursor, in the sign column, as virtual text or in a floating window. It suits Neovim users who want code actions discoverable, and it only reflects what the server offers.
- Who is it for?
- nvim-lightbulb suits a Neovim user who writes code against a language server and wants available code actions visible without remembering a keymap, particularly for refactorings and quick fixes that produce no visible diagnostic. It is the wrong tool for an editor without a working LSP configuration, since it has no language knowledge of its own, and the wrong tool for a Neovim version below 0.11.0, which is not tested.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Activity is slowing. The repository last received commits 6 months ago.
- What is it written in?
- Mainly Lua, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One signal, driven entirely by the language server
nvim-lightbulb is described in one line as VS Code's lightbulb for Neovim's built-in LSP, and the mechanism is narrow by design. The plugin shows a lightbulb in the sign column whenever a textDocument/codeAction is available at the current cursor position.
That single sentence determines everything about how it behaves. The plugin does not parse your code, does not know what a refactoring is, and does not compute anything. It asks the language server what code actions exist at the cursor, and it draws a marker when the answer is not empty.
The argument for doing it this way is stated in the introduction, with a link to a post on making code actions discoverable. The point is that code actions can be available even when there are no visible diagnostics. A warning squiggle tells you something is wrong; a code action might offer a rename, an extraction, a signature change or a quick fix that has no squiggle at all, and without a visual cue you will never know it is on offer.
So the lightbulb is a prompt, not a command. It marks the spot and leaves the action to your existing code action keymap, which is the usual combination of the plugin with Neovim's own handling.
The plugin also exposes the state as text. The README lists a configured message retrievable with require("nvim-lightbulb").get_status_text(), which is the hook for a status line that shows whether a lightbulb is available right now, rather than a marker you have to look for.
Six places to put the marker
The configuration exposes six handlers, and which ones you enable is the whole design decision. The README lists them as three ways to show the lightbulb and three ways to change the look of something else.
The first group adds the marker. The sign column shows it, virtual text shows it, and a floating window shows it. The sign column is the default: the sign handler is enabled in the default configuration, while the virtual text and float handlers are disabled.
The second group changes the look of existing UI. The number column can be highlighted, and the current line can be highlighted, both driven by the same code action availability. These are quieter than a marker, which suits a user who wants the information without a glyph in the gutter.
The third is the status text, which when enabled allows NvimLightbulb.get_status_text to retrieve the configured text, and which has a separate text for the case where no lightbulb is available.
Each handler that draws a glyph has two variants of that glyph in the configuration, one for a code action and one for a code lens, and the code lens variant is a magnifying glass rather than a bulb. That is the point of the code_lenses option: if the current position has executable code lenses, the icon is changed from the text variant to the lens_text variant for sign, virtual_text, float and status_text, so a position that offers something to run is not visually confused with a position that offers something to fix.
The per-handler configuration is also where you set the highlight group, and each handler has its own: LightBulbSign, LightBulbVirtualText, LightBulbFloatWin, LightBulbNumber and LightBulbLine. The default links are shown in the configuration, mapping the sign, float and virtual text groups onto the diagnostic info groups and the number group onto DiagnosticSignInfo, with the line group linked to CursorLine.
Installing it and turning the autocmd on
The prerequisites are short: Neovim v0.11.0 and above, with older versions possibly working but not tested, and a working LSP server configuration.
Installation is like any other plugin. With lazy.nvim the spec is a single line:
{ 'kosayoda/nvim-lightbulb' }With packer.nvim:
use { 'kosayoda/nvim-lightbulb' }and with vim-plug:
Plug 'kosayoda/nvim-lightbulb'Then the setup call, which the README asks you to place in your Neovim configuration:
require("nvim-lightbulb").setup({
autocmd = { enabled = true }
})That single autocmd line is the part that is easy to miss. In the default configuration the autocmd handler is disabled, and the comment on it explains the consequence: if it is disabled, you have to manually call NvimLightbulb.update_lightbulb. The autocmd block itself configures an updatetime of 200 milliseconds and hooks the CursorHold and CursorHoldI events across all patterns, with the note that a negative updatetime avoids setting it at all. A negative value is the escape hatch for a user who already has an updatetime they care about.
Configuration can be passed to NvimLightbulb.setup or to NvimLightbulb.update_lightbulb, and anything passed to update_lightbulb overrides what setup set. That gives you a way to run a global configuration and then adjust per call site, for example enabling the float only in a particular buffer.
There is also a debug entry point. The README points to NvimLightbulb.debug for debugging the plugin, and the configuration carries a validate_config option set to auto, which performs full validation in setup, or in update_lightbulb as well when set to always, or not at all when set to never.
Filtering which code actions count
The action_kinds option is the one that decides whether the lightbulb is useful or noise, and it defaults to nil, which means all code actions match.
The configuration comment explains the shape: set it to nil to match all code actions, otherwise set a table of kinds, with an example of quickfix and refactor.rewrite. The kinds are the ones from the Language Server Protocol specification for code action kinds, and the reference link in the configuration points at the LSP 3.17 specification.
The reasoning behind the default is worth stating. A language server can return a wide range of actions, and many of them are things a given user never wants to see offered. A Rust user with rust-analyzer gets source actions, a code lens for running tests, and quick fixes for diagnostics. A user who only wants the quick fixes and the rewrites gets a marker that means something. A user who takes the default gets a marker that lights up in places where the only action is something like an inline parameter hint, which is a cheap thing to notice and a cheap thing to regret.
There is a second filter in the configuration, the ignore table, whose first entry is a list of LSP client names to ignore, with null-ls and lua_ls given as an example. That is a different axis: it silences entire servers rather than particular kinds of action. The configuration is truncated in the documentation excerpt before the rest of the ignore table is shown, so the full set of ignore conditions is not visible there.
Two other options complete the picture. The priority value, 10 by default, sets the priority of the lightbulb for all handlers except float, and it is the setting that matters when other plugins also use the sign column. And hide_in_unfocused_buffer, true by default, hides the lightbulb when the buffer is not focused, so a background buffer does not keep a marker in its gutter.
Where it stops, and what it is not
The limits of this plugin are the limits of the protocol it sits on.
First, it is entirely dependent on the language server. If your server does not implement textDocument/codeAction, there is nothing to show, and the plugin will sit there silent while the same feature works in another editor for a different reason. The prerequisite of a working LSP server configuration is therefore not a formality.
Second, the plugin knows nothing about what an action does. It shows that an action exists, and it does not tell you the name of the action or what it would change. The list of available actions still has to come from your own code action keymap, and the plugin deliberately does not replace it.
Third, the version floor is real. Neovim v0.11.0 and above is required, with older versions noted as possibly working but not tested. Since the project has a single published release, v1.0.0 from 2023-07-08, and the last push was on 2026-04-27, a user on an older Neovim has no version of the plugin to fall back on and has to test the current branch against an unsupported editor.
The sign column competition is worth calling out as a practical failure mode. The sign column is a shared resource, and other plugins use it too. A lightbulb that is set but invisible is a configuration problem rather than a bug, and the priority option exists precisely to let this plugin yield or take precedence.
Finally, the plugin is a Lua file tree in a repository whose top-level entries are a stylua configuration, the licence, the README, a doc directory and a lua directory. There is no plugin manager of its own, no test harness in the layout, and no release automation to speak of. It is a small, hand-written plugin, and treating it as a dependency with a service level would be a mistake.
MIT terms and a project that stopped at version 1.0.0
The licence is MIT, with a LICENSE file at the repository root. There is no complication there for either personal or commercial use.
The maintenance picture is where the nuance is. The repository has one published release, v1.0.0 from 2023-07-08, and the last push was on 2026-04-27. The project is not archived, so the branch is still there and still receiving work, but there has been no new tagged release since 2023.
That means anyone installing from a plugin manager gets version 1.0.0 unless they pin to a commit or track the branch, and the fixes and changes that landed on the branch over the following three years are only reachable one of those two ways. For a plugin this small that is not fatal, since the code is a few Lua files, but it does mean the version number on your machine tells you very little about what is running.
The documentation lives in a doc directory alongside the README, and the .stylua.toml at the root shows the project uses StyLua for formatting its own Lua, which is a small signal about how the code is maintained.
The honest summary is that nvim-lightbulb is a finished, well-documented feature that a maintainer has kept working on without cutting a release. If you want the behaviour described in the configuration file rather than the behaviour in the 1.0.0 tag, install from the branch and pin the commit, and read the doc directory for the option reference.
Editorial conclusion
nvim-lightbulb suits a Neovim user who writes code against a language server and wants available code actions visible without remembering a keymap, particularly for refactorings and quick fixes that produce no visible diagnostic. It is the wrong tool for an editor without a working LSP configuration, since it has no language knowledge of its own, and the wrong tool for a Neovim version below 0.11.0, which is not tested. Before you adopt it, confirm your server actually returns code actions for the language you write, enable the handler that suits your sign column setup, and check the priority option against the other sign column plugins you already run, because two plugins competing for the same column is the most common way this one ends up invisible.
Frequently asked questions
What does the nvim-lightbulb plugin do?
It shows a lightbulb in the sign column whenever a textDocument/codeAction is available at the current cursor position. It can also show the marker as virtual text or in a floating window, or highlight the number column and the current line instead.
How do I install nvim-lightbulb in Neovim?
Like any other plugin. With lazy.nvim the spec is { 'kosayoda/nvim-lightbulb' }, with packer.nvim it is use { 'kosayoda/nvim-lightbulb' }, and with vim-plug it is Plug 'kosayoda/nvim-lightbulb'. Neovim v0.11.0 or above is required.
Why is the lightbulb not showing in my Neovim?
The autocmd handler is disabled in the default configuration, so you have to enable it during setup with require("nvim-lightbulb").setup({ autocmd = { enabled = true } }), or call NvimLightbulb.update_lightbulb yourself. A working LSP server configuration is also required, since the plugin only shows what the server reports.
Can I filter which code actions trigger the lightbulb?
Yes. The action_kinds option takes a table of LSP code action kinds, with quickfix and refactor.rewrite given as an example, and the ignore table has a list of LSP client names to silence, with null-ls and lua_ls as an example.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/kosayoda-nvim-lightbulb)Was this useful?