# base16-nvim: one highlight template, hundreds of palettes

> base16-nvim is a Neovim plugin that turns a sixteen colour palette into a full colorscheme, with Treesitter and builtin LSP highlight groups, a catalogue of several hundred built-in schemes, and a config switch for turning off the plugin specific highlights it manages.

**RRethy/base16-nvim** — Neovim plugin for building a sync base16 colorscheme. Includes support for Treesitter and LSP highlight groups.

- Repository: https://github.com/RRethy/base16-nvim
- Stars: 661 · Forks: 95
- Language: Lua
- License: MIT
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/rrethy-base16-nvim

## A palette in, a whole colorscheme out

The repository description calls this a Neovim plugin for building a sync base16 colorscheme, with support for Treesitter and LSP highlight groups, and the README describes it as a plugin for building base16 colorschemes with support for Neovim's builtin LSP and Treesitter. The mechanism is the interesting part. A base16 scheme is defined by sixteen colours, conventionally named base00 through base0F, arranged in a way that describes a ramp of backgrounds and a ramp of foregrounds plus eight accent colours. Those sixteen values are enough to derive every highlight group a text editor needs, because the mapping from palette slot to highlight group is fixed by the base16 convention. So the plugin holds one mapping and many palettes, and applying a theme means choosing sixteen hex values rather than shipping a separate file of highlight definitions for every theme. That is why the catalogue of schemes in this repository is so long, and it is the reason a user who wants a different look can often find one already built rather than writing a scheme from scratch.

## Applying a built-in scheme by name

The simplest use is a single command, and the README shows it as a colorscheme command because the plugin registers its schemes with Neovim's own colorscheme mechanism.

```lua
-- All builtin colorschemes can be accessed with |:colorscheme|.
vim.cmd('colorscheme base16-gruvbox-dark-soft')
```

The naming convention is worth reading closely, because it explains the size of the list. The prefix is base16-, then the family name, then usually a variant. The gruvbox family, for instance, appears as base16-gruvbox-dark, base16-gruvbox-light, and then the dark variants in a hard, medium, soft and pale form, plus a medium-forest variant. The atelier family appears with cave, dune, estuary, forest, heath, lakeside, plateau, savanna, seaside and sulphurpool, each in a light and a dark version. Catppuccin appears with frappe, latte, macchiato and mocha. Other families include everforest with hard, medium and soft contrasts in light and dark, harmony and harmony16, horizon and horizon-terminal, ocean and oceanicnext, oxocarbon, primer with dimmed and high contrast variants, and the pencil shades with the familiar names. So the catalogue is a set of families with variants, which is a reasonable way for a scheme to be described when a single colour change can flip a whole family from light to dark.

## Building a palette of your own with setup()

The alternative to picking a name is to hand the plugin the sixteen colours, which the README shows as the second route.

```lua
-- Alternatively, you can provide a table specifying your colors to the setup function.
require('base16-colorscheme').setup({
    base00 = '#16161D', base01 = '#2c313c', base02 = '#3e4451', base03 = '#6c7891',
    base04 = '#565c64', base05 = '#abb2bf', base06 = '#9a9bb3', base07 = '#c5c8e6',
    base08 = '#e06c75', base09 = '#d19a66', base0A = '#e5c07b', base0B = '#98c379',
    base0C = '#56b6c2', base0D = '#0184bc', base0E = '#c678dd', base0F = '#a06949',
})
```

The values in the example are the familiar sixteen of a dark scheme, and the table format means a palette can come from anywhere, including another configuration file or a generator. The consequence is that the plugin is not just a theme list. It is a renderer, and the catalogue is one of its inputs. There is a practical trap right below this snippet in the README, and it costs people an afternoon. If you do not see colours, the note says to try adding vim.opt.termguicolors = true to your init.lua. The plugin emits 24 bit colour, and a terminal that is not in true colour mode will quietly render nothing useful, which looks like a broken plugin rather than a terminal setting.

## with_config, and the plugins it manages for you

Beyond the base colours, the plugin also sets highlight groups for a list of popular plugins, and the advanced usage section is how you turn that off. The function is called with_config, it must be called before you set the colorscheme, and the defaults are shown in the README.

```lua
-- These are the defaults.
require('base16-colorscheme').with_config({
    telescope = true,
    indentblankline = true,
    notify = true,
    ts_rainbow = true,
    cmp = true,
    illuminate = true,
    dapui = true,
})
```

The list is informative in itself. Telescope, the fuzzy finder, is there, and so is indentblankline, which is the kind of plugin that can be given very opinionated colours. notify is the notification library, cmp is the completion engine, illuminate is the incremental selection helper, dapui is the debugger interface, and ts_rainbow refers to the rainbow colours that Treesitter can use to visualise scopes. The last one is worth a note, because the plugin's headline feature is Treesitter support, and the option to disable the rainbow scope colouring is the one place where that support is something you might want to turn off. The design is opt out rather than opt in, which is the right default for most people and the thing to reconsider if you have a plugin whose colours you would rather keep.

## Reading the palette back out of the plugin

There is one more piece of the API, and it is small but it is the kind of thing that turns a theme into a building block. After the colorscheme has been set by name, the base16 colours can be read from the plugin's colors table.

```lua
local color = require('base16-colorscheme').colors.base01
```

That matters because a scheme is often only half of what a user wants. If you are building a status line, a file tree, a border, a floating window or a custom highlight group of your own, the palette is the input, and reaching into the plugin's own table means the custom highlight always matches the theme, including after you switch themes, because it reads the same sixteen values the highlight groups were derived from. The alternative is to hardcode colours in your own configuration, which is exactly the duplication that a palette based approach exists to remove. The ordering constraint is worth noticing too, since the read works after the colorscheme has been set by name, which suggests the table is populated as a side effect of applying the scheme.

## The repository layout, and where the scheme list comes from

The top level of the repository explains how the catalogue is built. There is a colors directory, which is the natural place for the palette definitions, a templates directory for the highlight group templates that the palettes are rendered against, a lua directory for the plugin code itself, a tools directory for the scripts that generate and check the built-in schemes, a doc directory for the documentation, and a video_script.lua at the root, which appears to drive the demo video that the README links at the top. That arrangement says something about the project. The palettes and the template are separated, so adding a scheme means adding data rather than editing a file of highlight commands, and the tooling in tools is what keeps a list of several hundred entries honest. It also explains why the README is short: the interesting part of this project is a data set and a rendering step, not a large API. On maintenance, the repository is not archived and the last push was on 2026-10-04, and the project publishes no GitHub releases, so versions are not something you pin here. The licence is MIT, which is the permissive choice you would expect for a colourscheme project, since the schemes themselves are derived from many upstream palettes and the copyright on the mapping is the part that matters.

## Conclusion

Adopt base16-nvim if you want one colorscheme definition to cover every highlight group, including Treesitter and the builtin LSP, and you want to switch between many palettes without maintaining a separate plugin per theme. It does not fit a setup that needs every plugin to have bespoke highlighting, because the managed highlights are opt out rather than opt in, so anything with its own strong colour opinions will need that plugin added to the config. Before you install, check that your terminal reports true colour, since the README notes that the colours may not appear otherwise, and call the config function before you set the colorscheme, because the README is explicit that the order matters.

## FAQ

### What does base16-nvim do?

It is a Neovim plugin that builds base16 colorschemes, so a palette of sixteen colours is expanded into a full set of highlight groups, with support for Neovim's builtin LSP and for Treesitter. It ships a large catalogue of built-in schemes that can be set with the colorscheme command.

### How do I set a base16 colorscheme in Neovim?

With a colorscheme command, for example vim.cmd('colorscheme base16-gruvbox-dark-soft'). The scheme names carry a base16- prefix followed by the family and variant, and the catalogue covers families such as gruvbox, atelier, catppuccin and everforest with light and dark variants.

### Why are the colours not showing after I set the scheme?

The README notes that if you do not see colours you should try adding vim.opt.termguicolors = true to your init.lua, because the plugin emits 24 bit colour and a terminal that is not in true colour mode will not render it.

### How do I turn off the highlights that base16-nvim sets for other plugins?

Call the with_config function before you set the colorscheme, and set the plugins you want to exclude to false. The defaults listed in the README are telescope, indentblankline, notify, ts_rainbow, cmp, illuminate and dapui.

### Can I use my own colours instead of a built-in scheme in base16-nvim?

Yes. You can pass a table of colours to the setup function, with base00 through base0F set to hex values, instead of choosing a scheme by name. The plugin then renders the same highlight groups from your palette.

## Sources

- [Issues](https://github.com/RRethy/base16-nvim/issues)
- [License: MIT](https://github.com/RRethy/base16-nvim/blob/master/LICENSE)
- [README](https://github.com/RRethy/base16-nvim/blob/master/README.md)
- [RRethy/base16-nvim on GitHub](https://github.com/RRethy/base16-nvim)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/rrethy-base16-nvim
