indent-blankline.nvim: Indent Guides for Neovim Without Conceal
Indent guides for Neovim
At a glance
- What is it?
- indent-blankline.nvim draws indentation guides with Neovim's virtual text rather than conceal, and its scope feature marks where variables and functions are actually accessible. Here is what the README documents, what it leaves open, and who should install it.
- Who is it for?
- Adopt indent-blankline.nvim if you run the latest stable Neovim, already have treesitter configured, and want scope guides that underline the block where your variables are reachable, not merely the current indent column. Skip it if you cannot move off the conceal-based indentLine approach, if you have no treesitter parser for the languages you edit, or if you expect it to fix indentation itself rather than draw it.
- 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?
- Yes. The repository last received commits 27 days 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 September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem indent-blankline.nvim addresses in a Neovim buffer
Deeply nested code is hard to scan when columns of whitespace look identical. indent-blankline.nvim adds indentation guides to Neovim, drawn with the editor's virtual text feature. The README states plainly that it uses no conceal, which is the design decision that separates it from older indent-guide plugins. Conceal replaces characters in the buffer for display, and that replacement interacts with syntax highlighting, cursor movement and anything else reading the line. Virtual text is drawn alongside the buffer content instead, so the underlying text is untouched.
The audience is narrow and specific: Neovim users who already configure their editor in Lua and want a visual aid for reading nested blocks. The README does not pitch the plugin at Vim users, and it does not offer a non-Lua configuration path. If your setup lives in vimrc and you have never written a Lua table, this is not the plugin to learn on.
Virtual text, scope detection and the treesitter dependency
The mechanism is virtual text plus, optionally, treesitter. The README describes two distinct visual layers. The first is the indentation guide itself, one per indent level. The second is scope, which the README is careful to define: the scope is not the current indentation level, it is the indentation level where variables or functions are accessible. That distinction matters in languages where a block opens and closes without changing the visual indent depth, and it is why scope requires treesitter to be set up. Without treesitter, the plugin has no parse information to compute where a scope begins and ends.
Scope boundaries are drawn with underline. The README notes that to get the best result you may need to tweak the underline position, and gives Kitty terminal's modify_font option as an example. That is a rendering detail the plugin cannot control from inside Neovim, and it is a fair signal that scope rendering depends on the terminal's font metrics.
Configuration is exposed through a single setup call and, for the full option surface, the README points to :help ibl.config rather than listing keys inline. That is a deliberate choice: the README shows outcomes through screenshots and snippets, and the help file carries the reference. Anyone evaluating the plugin should read both, because the README alone will not tell you which keys exist.
Installing indent-blankline.nvim with lazy.nvim and calling setup
The README gives install snippets for three plugin managers. For lazy.nvim, the spec sets main to "ibl" and passes an empty opts table, which means lazy.nvim calls the module's setup function for you:
{
"lukas-reineke/indent-blankline.nvim",
main = "ibl",
---@module "ibl"
---@type ibl.config
opts = {},
}For Neovim 0.12 and later, the README shows vim.pack, the built-in plugin manager, using vim.pack.add with the repository URL:
vim.pack.add({
"https://github.com/lukas-reineke/indent-blankline.nvim"
})With pckr.nvim the README gives a single use line, and nothing else changes.
If you are not using a manager that calls setup for you, the README says to initialize and configure the plugin by running the setup function yourself. The minimal form is one call:
require("ibl").setup()After that call, the plugin is active. The README notes you can optionally pass a configuration table to setup, and directs you to :help ibl.config for all available options. The default setup produces the simple guide style shown in the README's first screenshot. The scope screenshot uses the same one-line setup, which means scope rendering depends on treesitter being configured in your Neovim rather than on extra plugin options.
Rainbow indent colors and the highlight hook
The README's most instructive example is the multiple-indent-colors configuration, because it shows how the plugin expects highlight groups to be managed. You define a list of highlight group names, then register a hook on HIGHLIGHT_SETUP that creates those groups with nvim_set_hl. The README explains the reason: creating them in the highlight setup hook means they are reset every time the colorscheme changes. Without that hook, a colorscheme switch would wipe your custom groups and the guides would fall back to default colors.
local highlight = {
"RainbowRed",
"RainbowYellow",
"RainbowBlue",
"RainbowOrange",
"RainbowGreen",
"RainbowViolet",
"RainbowCyan",
}
local hooks = require "ibl.hooks"
hooks.register(hooks.type.HIGHLIGHT_SETUP, function()
vim.api.nvim_set_hl(0, "RainbowRed", { fg = "#E06C75" })
end)
require("ibl").setup { indent = { highlight = highlight } }The README also documents a background-color style, where indent.char is set to an empty string and the whitespace highlight is configured instead, with scope disabled. In that mode the guides are not glyphs at all; the indentation columns are painted. That is a genuinely different visual approach, and it shows the plugin is not locked to one rendering style.
For rainbow-delimiters.nvim integration, the README adds a SCOPE_HIGHLIGHT hook registered against hooks.builtin.scope_highlight_from_extmark, alongside setting vim.g.rainbow_delimiters. The two plugins then share the same highlight list, so delimiters and scope guides use matching colors. This is the part of the README worth reading closely if you already use rainbow-delimiters.nvim, because the integration is a hook registration rather than a config key.
Where indent-blankline.nvim is the wrong tool
The scope feature is the clearest limitation, and the README is honest about it. Scope requires treesitter to be set up, and it depends on the language you are writing. If treesitter has no parser for your filetype, or the parser is not installed, scope has nothing to compute from. The README does not document a fallback that approximates scope without a parser, so the honest expectation is that scope simply does not render for those files.
Underline rendering is a second constraint that sits outside the plugin. The README says the start and end of scope use underline, and that you might need to tweak the underline position for the best result, citing Kitty's modify_font as an example. In a terminal where underline position is not adjustable, or where underlines render inconsistently, scope boundaries will look wrong and there is no in-plugin setting described in the README that compensates.
The plugin also draws guides; it does not fix indentation. Nothing in the README suggests it reindents code, converts tabs to spaces, or normalizes mixed indentation. It has a screenshot for mixed indentation, which shows it renders guides sensibly when tabs and spaces are mixed, not that it repairs the file. If your actual problem is inconsistent indentation in a codebase, you want a formatter, not this.
Finally, the README states the plugin requires the latest stable version of Neovim. That is a real constraint for anyone on a distribution-packaged Neovim that lags behind stable, and the README offers no older-version support path.
How indent-blankline.nvim differs from conceal-based indent guides
The obvious alternative is the conceal-based indent guide approach, where the plugin substitutes visible characters for leading whitespace. The README's own framing is the difference: indent-blankline.nvim uses virtual text and no conceal. With conceal, the displayed line no longer matches the buffer, and everything that reads the line for display purposes has to account for the substitution. Virtual text avoids that class of interaction entirely, because the buffer content and the guide are separate layers in the renderer.
A second alternative is doing nothing and relying on your colorscheme or your own listchars and whitespace settings. That costs no plugin, no treesitter dependency and no underline tuning, but it gives you no scope information. The scope layer is the part of indent-blankline.nvim that has no cheap substitute, since it needs a parser to know where variables and functions become accessible.
A third comparison point is rainbow-delimiters.nvim, which the README treats as a companion rather than a competitor. It colors delimiters; indent-blankline.nvim draws indent and scope guides. The README's integration snippet exists precisely because people run both, and the SCOPE_HIGHLIGHT hook is how they are kept visually consistent. If you want delimiter coloring, install rainbow-delimiters.nvim; it will not give you indentation guides, and this plugin will not give you delimiter coloring.
Maintenance, licence and what a Neovim plugin upgrade actually costs
The repository is not archived, and the last push was on 2026-09-04. Three releases landed within two days of each other in early September 2026: v3.9.2 and v3.10.0 on 2026-09-03, then v3.10.1 on 2026-09-04. That cadence suggests active release work around that date, though a single cluster of releases says nothing about the months around it.
The licence is MIT, per the repository metadata. MIT is permissive: it allows use, modification and redistribution with the licence and copyright notice retained. That is a statement about the licence text, not legal advice; if you vendor the plugin into a product, read LICENSE.md and your own obligations.
Upgrade cost for a Neovim plugin of this shape is mostly configuration drift. The README points at :help ibl.config for the option surface, which means the help file, not the README, is the reference you would diff when a release changes a key. The hooks API is the other surface to watch, since the rainbow and highlight examples both depend on hook types and on hooks.builtin.scope_highlight_from_extmark. The repository ships a Makefile with test, luacheck, stylua and lua-language-server targets, and the test target clones plenary.nvim and neodev.nvim into .ci/vendor before running PlenaryBustedDirectory over specs/features. That is a usable signal for anyone who wants to run the suite locally before bumping, though the README does not document it.
Editorial conclusion
Adopt indent-blankline.nvim if you run the latest stable Neovim, already have treesitter configured, and want scope guides that underline the block where your variables are reachable, not merely the current indent column. Skip it if you cannot move off the conceal-based indentLine approach, if you have no treesitter parser for the languages you edit, or if you expect it to fix indentation itself rather than draw it. Before committing, check that your Neovim version satisfies the README's requirement of the latest stable release, confirm a treesitter parser exists for your main language, and open :help ibl.config to see the option surface the README does not reproduce.
Frequently asked questions
How do I configure indent-blankline.nvim?
Call require("ibl").setup() and optionally pass a configuration table. The README points to :help ibl.config for the full list of available options, so the help file is where the key reference lives.
Does indent-blankline.nvim need treesitter?
Only for scope. The README states that scope requires treesitter to be set up, and that scope depends on the language you are writing. The basic indentation guides render from a plain require("ibl").setup() call.
How do I install indent-blankline.nvim with lazy.nvim?
The README gives a lazy.nvim spec with the repository URL, main set to "ibl", and opts set to an empty table. Setting main to "ibl" is what makes lazy.nvim call the module's setup function.
What is the difference between scope and the current indentation level in indent-blankline.nvim?
The README states the scope is not the current indentation level. It is the indentation level where variables or functions are accessible, which is why it needs treesitter to compute.
Does indent-blankline.nvim work with rainbow-delimiters.nvim?
Yes. The README shows setting vim.g.rainbow_delimiters with a shared highlight list, then registering hooks.type.SCOPE_HIGHLIGHT against hooks.builtin.scope_highlight_from_extmark so both plugins use matching colors.
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/lukas-reineke-indent-blankline-nvim)