Open-source project
olimorris/onedarkpro.nvim avatar
olimorris/onedarkpro.nvim

onedarkpro.nvim: One Dark for Neovim, with a styles table instead of a colour list

🎨 Atom's iconic One Dark theme. Cacheable, fully customisable, Tree-sitter and LSP semantic token support. Comes with variants

1,100 stars55 forksLuaMIT

At a glance

What is it?
onedarkpro.nvim is a Neovim port of the One Dark theme, and its distinguishing feature is the style layer: a table where you set bold and italic per language category instead of a wall of hex values. It also caches its generated files, which is the part that makes it fast.
Who is it for?
onedarkpro.nvim fits a Neovim user who wants One Dark because it is what the rest of their toolchain already looks like, and who wants to adjust weight and emphasis per language category rather than hand edit highlight groups.
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 44 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 October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One Dark, ported from the VS Code theme

The lineage is stated in the README. This is Atom's iconic One Dark theme for Neovim, based on the One Dark Pro theme for Visual Studio Code, originally developed by Binaryify. The original Atom theme is the ancestor that most people picture, and the VS Code theme is the direct donor of the port.

The project describes itself as fully customisable, with Tree-sitter, LSP semantic tokens and support for many common plugins. The topic tags name the scope precisely: colorscheme, dark theme, light theme, neovim, neovim colorscheme, neovim theme, onedark, onedarkpro, onelight.

The theme list is longer than the name suggests. There are five variants shown in the README, Vaporwave as a new addition, Onedark, Onelight, Onedark Vivid and Onedark Dark. Onelight is the light counterpart, which matters more than it sounds, because a theme that only ships a dark palette is unusable in a bright room or in a daylight theme, and having the light variant come from the same palette means the highlight group structure matches and switching is a single command.

Vaporwave is the one that is not a member of the original family at all. It is a separate aesthetic that the project has added, and the fact that it sits in the same variant mechanism as the others is a small design statement about how the theme is structured.

A detail worth knowing: the README notes that all bolds and italics in the screenshots are completely customisable, which is a polite way of saying the default rendering is not what you see in the images unless you configure the styles table.

The styles table, which is the part that makes this more than a palette

Most colourschemes give you a set of highlight groups and let you override them. This one gives you a layer above that, and the default configuration shows the shape of it.

lua
require("onedarkpro").setup({
  styles = { -- For example, to apply bold and italic, use "bold,italic"
    types = "NONE", -- Style that is applied to types
    methods = "NONE", -- Style that is applied to methods
    numbers = "NONE", -- Style that is applied to numbers
    strings = "NONE", -- Style that is applied to strings
    comments = "NONE", -- Style that is applied to comments
    keywords = "NONE", -- Style that is applied to keywords
    constants = "NONE", -- Style that is applied to constants
    functions = "NONE", -- Style that is applied to functions
    operators = "NONE", -- Style that is applied to operators
    variables = "NONE", -- Style that is applied to variables
    parameters = "NONE", -- Style that is applied to parameters
    conditionals = "NONE", -- Style that is applied to conditionals
  },

The idea is that weight and emphasis are semantic properties of a language category rather than properties of a specific highlight group. Comments can be italic across every filetype, keywords can be bold, virtual text can be dimmed, and you set that once instead of hunting through forty highlight group names. The comment on the key explains the value format, for example "bold,italic" to apply both.

The configuration sits above two other layers. There is a colors table, to override default colors or create your own, and a highlights table, to override highlight groups or create your own. The styles table then applies a consistent weight treatment across all of them, and the filetypes table decides which filetype highlight groups are loaded at all.

The order matters conceptually, and it is a sensible design. The colors are the palette, the highlights are the mapping, the styles are the weight system, and the filetypes are the scope. The feature list summarises it as overriding everything, with styles, colors, tokens, highlight groups and filetype groups.

Caching, and the four commands that manage it

The first item on the features list is automatic caching for faster load times, and there is a set of commands around it.

-:OneDarkProCache force generate new cache files for the themes, and the README notes you won't often need this -:OneDarkProClean removes existing cache files for the themes -:OneDarkProColors output all of the current themes colors to a scratch buffer -:OneDarkProExtras generates the extras files from the /extras folder using your config

The caching is the reason this theme loads quickly. A colourscheme that has to build its highlight groups and plugin extras at startup pays for that on every launch, and precomputing the result into files moves the work to install time. For a theme this is an unusual amount of machinery, which is why OneDarkProCache exists as a separate command: when you change something that affects the generated output, you have to tell it to regenerate.

The extras system deserves a note because the name is vague. The OneDarkProExtras command generates the extras files from the /extras folder using your config, and the repository layout has an extras/ directory alongside lua/, colors/, after/, plugin/ and doc/. The extras are the plugin specific highlight groups, and the plugins table in the default configuration lists dozens of them by name, from aerial and barbar through nvim_tree, telescope, which_key and treesitter.

The practical workflow is therefore two stage. The theme itself is a normal colorscheme you set with a command. The plugin integration is generated separately, from the extras folder, using your configuration, so that a plugin you have not configured does not get highlight groups it should not have.

Tree-sitter, semantic tokens, and the filetype table that gates them

Syntax highlighting in this theme is not the old vim filetype plugin mechanism. The features list promises full Tree-sitter support with bespoke queries, and the requirements section asks for tree-sitter for full syntax highlighting, plus an LSP server that supports semantic tokens for the semantic token path.

The mechanism is filetype based, but in the Tree-sitter sense. The default configuration includes a filetypes table, and the comment on it says it overrides which filetype highlight groups are loaded, with entries for c, comment, go, html, java, javascript, json, latex, lua, markdown, php, python, ruby, rust, scss, toml, typescript, typescriptreact, vue, xml and yaml.

That list has a purpose beyond skipping work. A filetype can be a language, a comment, or something else, and the comment entry is there because comment highlighting is configured as its own filetype group rather than being baked into every language. That is what makes the global comments style possible, and it is why changing the style of comments in one place changes it everywhere.

The plugin table works the same way but for plugins, and the two tables together are why the theme can support dozens of plugins. The examples/ directory in the repository mirrors the language list with a file per language, from c.c and go.go to python.py, python2.py, rust.rs, typescriptreact.tsx, vue.vue, xml.xml and yaml.yml, which is the set the maintainer uses to check that a language renders as intended.

LSP semantic tokens are the third layer. Semantic tokens come from the language server rather than from the parser, so a server that reports them can colour identifiers by their role, and a server that does not leaves that to Tree-sitter. The requirement list is explicit that for semantic tokens you need an LSP server that supports them, which is a server side property rather than something the theme can provide.

Installing it, and the one thing that trips people up

The installation is a normal plugin install with a colourscheme command afterwards, and the README gives the form for three package managers.

For Lazy, the snippet includes a priority.

lua
-- Lazy
{
  "olimorris/onedarkpro.nvim",
  priority = 1000, -- Ensure it loads first
}

-- somewhere in your config:
vim.cmd("colorscheme onedark")

The comment explains the priority, and it is the detail people miss. A colourscheme has to be applied after the plugins whose highlight groups it is meant to define, and a lazy loading plugin manager will happily load your file browser after your colourscheme has already run. The priority field makes the theme load first.

Packer and Vim-Plug are the same idea with different syntax.

lua
-- Packer
use "olimorris/onedarkpro.nvim"

-- somewhere in your config:
vim.cmd("colorscheme onedark")
vim
" Vim-Plug
Plug "olimorris/onedarkpro.nvim"

" somewhere in your config:
colorscheme onedark

Note the colourscheme name in all three is onedark, not onedarkpro. The plugin is named onedarkpro.nvim and the colourscheme it registers is onedark, and that is the name that selects the Onedark variant rather than Onelight, Vaporwave or the other two. The README also notes that you only need to call the setup function if you wish to change any of the defaults, which is worth reading before you start editing the configuration.

The requirements are Neovim 0.9.2 or newer, termguicolors enabled for true color support, tree-sitter for full syntax highlighting, and an LSP server that supports semantic tokens for that layer.

What the theme cannot do for you

Three limits, and they are all consequences of the design rather than bugs.

The first is that the screenshots will not match your configuration. The README states that all bolds and italics in the screenshots are completely customisable, and the default styles table has every category set to NONE. So the images show a configured theme, and an unconfigured install is the same palette with different weights. If you are choosing this theme by looking at the images, you are looking at someone else's configuration.

The second is that the plugin highlight support is opt in per plugin. The plugins table in the default configuration lists dozens of entries, all set to true, and the OneDarkProExtras command generates the extras files from the /extras folder using your config. A plugin that is not in that list, or a plugin whose highlight groups were changed upstream, will not be styled by the extras, and the theme's own groups will be whatever they fall back to.

The third is the hard requirement on Tree-sitter for the full experience. Without it you get the filetype based highlighting and the palette, and the language specific parts of the theme are inert. That is a real dependency for a user on an older Neovim or on a setup that has deliberately avoided Tree-sitter, and the README is clear that tree-sitter is required for full syntax highlighting.

The comparison worth making is with a plain palette. A theme that gives you a set of colours and nothing else is less work to install and less work to fight with, and if what you want is the One Dark palette specifically, that is a smaller thing than this project. What you are buying here is the styles layer, the plugin integration and the caching, and the question is whether those three are worth the configuration surface.

Editorial conclusion

onedarkpro.nvim fits a Neovim user who wants One Dark because it is what the rest of their toolchain already looks like, and who wants to adjust weight and emphasis per language category rather than hand edit highlight groups. It does not fit a user who wants the theme to be a single drop in with no colour work, because the styles table and the extras system both invite configuration, and it does not fit a setup that cannot enable termguicolors or run Tree-sitter, since the full experience depends on both. Check three things before you install. Check your Neovim version, because the requirement is 0.9.2 or newer, and check that termguicolors is enabled, since without true color the palette is meaningless. Check which of the five variants you want, because the theme list is Vaporwave, Onedark, Onelight, Onedark Vivid and Onedark Dark, and the name you set with the colorscheme command determines which one loads. And check whether you want the extras, because the generated files for plugin highlighting are produced from an /extras folder using your config through the OneDarkProExtras command. The last push was on 2026-09-09, the newest release listed is v2.29.0 from the same day, and the license is MIT.

Frequently asked questions

What are the requirements for onedarkpro.nvim?

Neovim 0.9.2 or newer, termguicolors enabled for true color support, tree-sitter for full syntax highlighting, and, for semantic tokens, an LSP server that supports them.

How do I install onedarkpro.nvim with lazy.nvim?

Add the plugin with "olimorris/onedarkpro.nvim" and priority = 1000 so it loads first, then set the colourscheme somewhere in your config with vim.cmd("colorscheme onedark"). The colourscheme name is onedark, not onedarkpro.

What does the styles option in onedarkpro.nvim do?

It sets weight and emphasis per language category, with entries for types, methods, numbers, strings, comments, keywords, constants, functions, operators, variables, parameters, conditionals and virtual_text. The value format is for example "bold,italic", and the default is NONE for every category.

Which theme variants does onedarkpro.nvim ship?

Five, shown in the README: Vaporwave, Onedark, Onelight, Onedark Vivid and Onedark Dark. The colorscheme command selects which one loads.

What are the onedarkpro.nvim commands?

:OneDarkProCache force generates new cache files for the themes, :OneDarkProClean removes existing cache files, :OneDarkProColors outputs all of the current theme colors to a scratch buffer, and :OneDarkProExtras generates the extras files from the /extras folder using your config.

What license is onedarkpro.nvim released under?

MIT, with a LICENSE file at the root of the repository. The newest listed release is v2.29.0 from 2026-09-09, and the last push was on 2026-09-09.

Official sources

  1. Issues
  2. License: MIT
  3. olimorris/onedarkpro.nvim on GitHub
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/olimorris-onedarkpro-nvim.svg)](https://hysenlabs.com/projects/olimorris-onedarkpro-nvim)

Was this useful?