The library splits content blocks from window components
UI Component Library for Neovim.
At a glance
- What is it?
- nui.nvim is a Neovim UI component library that separates four content blocks from six window components, mounts them on ordinary buffers, and ships a rockspec whose name ends in dev-1. The stated requirement is Neovim 0.5.0.
- Who is it for?
- nui.nvim suits a plugin author writing floating windows, prompts and menus in Neovim who wants buffers, layout and lifecycle handled rather than hand-rolled, and it keeps a low Neovim floor. It does not suit someone wanting a theme, an icon set or a status line, nor a project with its own buffer abstraction.
- 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 50 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 28, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Four blocks, six components, one distinction
The README organizes its own API into two categories and that split is the fastest way to understand it. Blocks are content renderers that live on a buffer: NuiText adds highlighted text to a buffer, NuiLine adds a line made of highlighted chunks, NuiTable renders table-like structured content, and NuiTree renders tree-like structured content. Components are windows and the machinery around them: Layout, Popup, Input, Menu and Split. That separation matters in practice. You can use NuiTable to render a list inside your own split, or render the same table inside a Popup without changing the rendering code, because the block never knew which window it was in. Each entry links to both a detailed documentation file in the repository and a wiki page, which is the arrangement most projects pick when the in-repo docs are thorough and the wiki holds worked examples.
The requirement line is old news
The requirements section is one line: Neovim 0.5.0, linked to the release page for that version. That is a floor rather than a target, and it is the kind of number worth checking against your own user base. A plugin that only needs 0.5.0 can be installed by someone on an old distribution package of Neovim, which is a real audience in locked-down or air-gapped environments, and a library that keeps its floor low is easier to adopt broadly. It also means the library is not relying on recent buffer or window APIs, which is consistent with the design you see in the examples, where mounting is a method call and content is set through the nvim_buf_set_lines API rather than through a newer abstraction. The version badge in the README points at LuaRocks rather than at GitHub, which is the same theme from another angle: this is packaged as a Lua module, and the newest published tags are 0.4.0 from 2025-05-03, 0.3.0 from 2024-02-16 and 0.2.0 from 2023-07-20.
Layout is a tree of boxes you can rebuild at runtime
The Layout component is the one that shows the library's mental model. You construct popups, wrap them in Layout.Box with size values expressed as percentages or absolute numbers, set a position, and mount the result. A box has a direction, row or col, so a layout is a tree of boxes whose children each claim a share. The interesting part is layout:update, which takes a whole new box tree, so changing the arrangement is a matter of calling update with different proportions rather than repositioning windows by hand. The example does exactly that: two popups side by side at 40 and 60 percent, and a keymap that rebuilds the tree in the opposite direction, which demonstrates that the update path is cheap enough to use on a keystroke. The outer layout also takes position 50% and a size with a fixed width and a percentage height, mixing absolute and relative units in one declaration.
Popup mounts a buffer and unmounts on an autocmd
The Popup example shows the whole lifecycle in a few lines: create it with enter, focusable and a border style, position it at 50 percent, give it a size of 80 percent by 60 percent, then call mount. From there it is an ordinary buffer, and the example sets its content with vim.api.nvim_buf_set_lines on the buffer number the popup exposes. The unmount is event-driven rather than manual: the popup registers a handler on event.BufLeave from nui.utils.autocmd, so leaving the buffer tears the window down. That pattern is why this library is useful for prompts and pickers, since the window exists exactly as long as the interaction does and does not require the caller to remember to close it on every error path. The autocmd helper is a module in its own right, which means the event names come from the library rather than from a table you write.
One Plug line, and a rockspec named dev
Installation is whatever your plugin manager does, with vim-plug shown as the example:
Plug 'MunifTanjim/nui.nvim'The repository is a Lua module laid out the conventional way for Neovim plugins: lua/ at the root holding the library, tests/, scripts/, a .luacheckrc and .luacov for linting and coverage, a .stylua.toml for formatting, a CHANGELOG.md, and a rockspec named nui.nvim-dev-1.rockspec. That last filename is worth a second look, because the version badge at the top of the README links to LuaRocks for this module and the rockspec carries a dev marker rather than a plain version. For a library consumed as a plugin through a plugin manager, the rockspec matters mainly for people installing it as a Lua module outside a plugin manager, which is a smaller audience in the Neovim world than it would be elsewhere. The repository has no homepage field of its own, so the documentation and examples both live on the GitHub wiki rather than on a separate site.
Input and Menu follow the Popup pattern
Input and Menu are listed after Popup in the components section and each carries its own detailed documentation file and wiki page, in the same arrangement as the rest. The pattern to expect from Input is the Popup lifecycle plus text entry, since it is the same mount, event and buffer structure with an input surface added, and Menu is the same again with a list and selection handling. Split is the odd one out in the component list, because it wraps the editor's own split rather than creating a floating window, which is what you would use when you want the library's components inside a normal split instead of floating over the buffer behind. The examples section for each component is a GIF rather than a screenshot, which tells you these are short interactions whose behavior over time is the point. For a new user, the reading order that pays off is Popup first, then Input and Menu, then Layout, because Layout only becomes interesting once you know what it is arranging.
Where nui.nvim is the wrong choice
Four cases. The first is a plugin that only needs a prompt. A single input line can be done with vim.ui.input, and pulling in a component library for one prompt adds a dependency and a mount and unmount lifecycle to handle. The second is a project expecting a styled theme. This library renders components and manages windows; it does not set a colorscheme, provide icons, or restyle the status line, so a team wanting a coherent look still needs a separate theme plugin. The third is a codebase with an existing buffer abstraction. The library mounts on buffers and sets lines through the Neovim API directly, so a project that has already built its own buffer and window management layer ends up with two, and the reconciliation is yours. The fourth is anyone assuming the wiki stays current. Each component links to two places, an in-repository documentation file and a wiki page, and when those two disagree the in-repository file is the one that moves with the code.
Editorial conclusion
nui.nvim suits a plugin author writing floating windows, prompts and menus in Neovim who wants buffers, layout and lifecycle handled rather than hand-rolled, and it keeps a low Neovim floor. It does not suit someone wanting a theme, an icon set or a status line, nor a project with its own buffer abstraction. Before adopting, install it with your plugin manager, read the popup example first since Input and Menu follow the same lifecycle, and check that Neovim 0.5.0 is old enough for the audience you ship to.
Frequently asked questions
What does nui.nvim provide for Neovim?
Four content blocks, NuiText, NuiLine, NuiTable and NuiTree, for rendering highlighted text and structured content on a buffer, plus six components: Layout, Popup, Input, Menu and Split as window machinery.
How do I install nui.nvim?
With your preferred plugin manager. The README shows vim-plug with Plug 'MunifTanjim/nui.nvim'. The version badge points at LuaRocks, and the repository contains nui.nvim-dev-1.rockspec for module installs.
What Neovim version does nui.nvim need?
Neovim 0.5.0, stated as the requirement in the README with a link to that release. The examples use ordinary buffer APIs and a mount and unmount lifecycle.
How does the Layout component handle resizing?
A layout is a tree of Layout.Box values with a direction of row or col and size values in absolute or percentage units. Calling layout:update with a new box tree rearranges it, which the example does from a keymap.
How does a Popup know when to close?
You register a handler on event.BufLeave from nui.utils.autocmd, as the example does, so leaving the buffer unmounts the popup. Content is set on the exposed buffer number with nvim_buf_set_lines.