gruvbox.nvim: the Lua port of gruvbox for Neovim 0.8 and newer
Lua port of the most famous vim colorscheme
At a glance
- What is it?
- gruvbox.nvim rewrites the classic gruvbox palette as a Lua colorscheme with treesitter and LSP semantic highlight support. It is a configuration surface more than a new palette, and the setup order is the part people get wrong.
- Who is it for?
- Adopt gruvbox.nvim if you run Neovim 0.8 or newer, want the gruvbox palette, and need to change individual highlight groups, treesitter captures or LSP semantic tokens without forking the theme. Skip it if you are on Neovim 0.7 or older, since the README states 0.8.0+ as a prerequisite, or if you want a theme whose palette is generated rather than fixed.
- 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 168 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 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What gruvbox.nvim actually solves for Neovim users
The original gruvbox is a Vim colorscheme, and the repository describes this project as a port of the gruvbox community theme to Lua. That framing matters, because the value is not the palette. The palette already existed. What the port adds is a configuration path that runs inside Neovim rather than through Vim script variables, plus support for treesitter and LSP semantic highlights, which the README lists as the two headline features.
The audience is narrow and specific. You need Neovim 0.8.0 or newer, which the README states as the sole prerequisite. If you are on Vim, or on an older Neovim, this is not the plugin for you. If you are on a modern Neovim and you want gruvbox colors that also cover the highlight groups treesitter and LSP produce, this is the direct route.
The second audience is people who like gruvbox but dislike one or two of its decisions. The setup table exposes both a palette override and a per-highlight-group override, so you can repaint a single group without maintaining a fork. That is the practical difference between this and copying a colors file into your config directory.
How the setup table and override layers work
There is no daemon, no build step and no generated cache described in the README. The mechanism is a Lua module that reads a configuration table when setup() is called, then applies colors when the colorscheme command runs. The repository layout matches that: a colors/ directory holds the colorscheme entry point, lua/ holds the module, and doc/ holds the documentation.
The configuration table has three layers that matter. The first is the toggle layer: terminal_colors, undercurl, underline, bold, strikethrough, and the italic sub-table with separate switches for strings, emphasis, comments, operators and folds. The second is the contrast layer: contrast accepts "hard", "soft" or an empty string, and the invert_* flags (invert_selection, invert_signs, invert_tabline) plus inverse control how backgrounds are handled for search, diffs, statuslines and errors. The third is the override layer: palette_overrides replaces named palette colors, and overrides replaces individual highlight groups.
The override layer is the interesting one. According to the README, overrides accepts treesitter groups and LSP semantic tokens, so a key like ["@lsp.type.method"] or ["@comment.lua"] can carry its own bg value. Override values follow the highlight group attribute map: fg, bg, bold and italic are named explicitly, and the README points to synIDattr for the rest. That means the override surface is as wide as Neovim's own highlight attributes, not a fixed list of four keys.
The ordering constraint is stated in the README in capital letters: call setup() before the colorscheme command. This is not a stylistic preference. If you call colorscheme first, the module applies defaults, and your table arrives too late to change anything.
Installing gruvbox.nvim and running a first override
The README documents four plugin managers. With vim.pack, which the README marks as Neovim 0.12+, the whole install is three statements: add the repository, call setup, then run the colorscheme command.
vim.pack.add({
"https://github.com/ellisonleao/gruvbox.nvim"
})
require("gruvbox").setup()
vim.cmd.colorscheme("gruvbox")After that runs, the editor should switch to the gruvbox palette. If nothing changes, the usual cause is that setup() ran after the colorscheme command rather than before it.
With lazy.nvim the README gives a single spec line with priority set to 1000 and config set to true, which means the plugin's own setup runs for you and you pass your options through opts. With packer it is a bare use block, and with vim-plug it is a single Plug line.
For a first real change, override one highlight group. The README's example repaints SignColumn with an orange background:
require("gruvbox").setup({
overrides = {
SignColumn = {bg = "#ff9900"}
}
})
vim.cmd("colorscheme gruvbox")The sign column should pick up the new background while everything else stays on the default gruvbox colors. If it does not, check that the setup call is the one being executed and that no earlier setup call is overwriting it.
The same pattern works for treesitter and LSP tokens, which is where a plain colorscheme usually falls short:
require("gruvbox").setup({
overrides = {
["@lsp.type.method"] = { bg = "#ff9900" },
["@comment.lua"] = { bg = "#000000" },
}
})
vim.cmd("colorscheme gruvbox")Palette-level changes use a different key. The README's example sets bright_green to "#990000" through palette_overrides, which shifts every group drawing on that palette entry rather than one group at a time.
Where gruvbox.nvim gets awkward
The setup-before-colorscheme rule is the main failure mode, and it is a silent one. Nothing errors when you get the order wrong. The colorscheme loads with defaults and your overrides are simply ignored, which sends people looking for bugs in their override keys instead of their call order.
Background handling is the second sharp edge. The README's basic usage sets background through vim.o.background or the Vim set background line, and the light and dark variants are separate modes of the same theme. If your background value changes at runtime, the theme's assumptions about which colors apply change with it, and the README does not document a supported path for switching backgrounds after the colorscheme has loaded.
The plugin is also the wrong tool if you want a generated or adaptive palette. gruvbox is a fixed palette with named entries; palette_overrides lets you replace entries, not derive them. If you want colors computed from an image, a wallpaper or a time of day, this project does not do that and the README does not suggest it does.
Finally, the README does not document rollback, version pinning or a migration path between the 1.x and 2.x lines. The release list shows 1.1.0 labeled as the last release before breaking changes, followed by 2.0.0, but the README itself carries no upgrade notes. If you pin versions, you are working from the release list rather than from written guidance.
gruvbox.nvim against gruvbox-material and the original Vim theme
The most common comparison is with gruvbox-material, and the difference is not cosmetic. gruvbox-material is a separate palette project with its own color decisions and its own maintainers. gruvbox.nvim is a Lua port of the gruvbox community theme, so it tracks that palette rather than inventing a new one. If you want the specific softened, lower-contrast look of gruvbox-material, this plugin will not produce it, and no amount of contrast or palette_overrides keys will get you there exactly. You would be approximating a different design.
The other alternative is the original Vim gruvbox colorscheme. That one works in Vim and older Neovim, which this port explicitly does not, since the README requires Neovim 0.8.0+. The trade is the reverse of what you might expect: the original runs in more places, this port covers more highlight groups. Treesitter captures and LSP semantic tokens are the reason. A Vim script colorscheme written before those systems existed has no natural place to define them, while this port's overrides table accepts @lsp.type.method and @comment.lua keys directly.
There is also a middle option worth naming: keeping gruvbox and layering your own overrides on top of it through a separate autocmd or plugin. That works, but you end up maintaining a list of highlight groups by hand, and every upstream change to the theme can drift from your list. The setup table exists to avoid exactly that.
Maintenance, licence and the cost of staying current
The repository is not archived, and the last push was on 2026-04-15. That is roughly five months before today, which puts it inside the six-month window, but it is not a project pushing daily. The release history is sparser than the commit history: 1.0.0 in June 2022, 1.1.0 and 2.0.0 within days of each other in late September and early October 2023, and nothing tagged since. If you track tags, the 2.0.0 line is what you are on.
The upgrade cost is low in one sense and unquantified in another. A colorscheme has no runtime dependencies to reconcile and no service to restart, so upgrading is a plugin-manager operation. But the jump from 1.x to 2.x is labeled as containing breaking changes, and the README does not describe what those changes are or how to migrate. That gap is the real maintenance risk: you may need to read the commit history to understand a 1.x to 2.x upgrade, because the README will not tell you.
The licence is MIT, which the repository states at the top level with a LICENSE file. MIT is permissive, so redistributing the theme, including inside a dotfiles repository or a bundled configuration, is straightforward. This is not legal advice, and if you are shipping the theme inside a product you should read the LICENSE file itself rather than a summary. One practical consequence worth noting: MIT carries no copyleft requirement, so a fork or an embedded copy does not obligate you to publish your own configuration.
Testing is documented in the Makefile, which runs PlenaryBustedDirectory headless against tests/minimal_init.lua. That tells you the project has a test harness for the Lua module, which is more than many colorschemes have. It does not tell you the palette is correct on your terminal.
Editorial conclusion
Adopt gruvbox.nvim if you run Neovim 0.8 or newer, want the gruvbox palette, and need to change individual highlight groups, treesitter captures or LSP semantic tokens without forking the theme. Skip it if you are on Neovim 0.7 or older, since the README states 0.8.0+ as a prerequisite, or if you want a theme whose palette is generated rather than fixed. Before you commit, verify two things in your own config: that require("gruvbox").setup() runs before the colorscheme command, and that your background value is set before setup() as well, since both determine which colors the theme applies.
Frequently asked questions
How do I install gruvbox.nvim?
Add the repository with your plugin manager, then call require("gruvbox").setup() and run vim.cmd("colorscheme gruvbox"). The README gives install snippets for vim.pack, packer, lazy.nvim and vim-plug.
How do I install gruvbox.nvim with lazy.nvim?
The README's lazy.nvim spec is a single line with priority set to 1000, config set to true, and your options passed through opts. Setting config to true means the plugin's own setup runs, so you supply the table rather than calling setup yourself.
What is the difference between gruvbox and gruvbox-material?
gruvbox.nvim is described in the repository as a port of the gruvbox community theme, so it follows that palette. gruvbox-material is a separate theme with its own color decisions, and this plugin's contrast and palette_overrides keys will not reproduce it exactly.
What is gruvbox?
Gruvbox is the colorscheme this project ports to Lua, originally from the gruvbox community theme. The README describes gruvbox.nvim as that port, with treesitter and LSP semantic highlight support added.
What colors are in the Gruvbox theme?
The README does not list the palette entries themselves, but it does show that they are named, since palette_overrides targets keys such as bright_green. The default options also expose contrast values of "hard", "soft" or an empty string.
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/ellisonleao-gruvbox-nvim)