https://github.com/micdzu/aalto.nvim
A minimal Neovim colorscheme where structure is visible and color stays quiet.
https://github.com/micdzu/aalto.nvim
colorscheme dark-theme editor-theme light-theme lua neovim theme treesitter
Last synced: 2 months ago
JSON representation
A minimal Neovim colorscheme where structure is visible and color stays quiet.
- Host: GitHub
- URL: https://github.com/micdzu/aalto.nvim
- Owner: micdzu
- License: mit
- Created: 2026-03-30T12:52:45.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-04-09T20:57:53.000Z (3 months ago)
- Last Synced: 2026-04-09T21:29:59.087Z (3 months ago)
- Topics: colorscheme, dark-theme, editor-theme, light-theme, lua, neovim, theme, treesitter
- Language: Lua
- Homepage:
- Size: 324 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-neovim-sorted - micdzu/aalto.nvim
- awesome-neovim - micdzu/aalto.nvim - **_`[TS][LSP][L/D][Lua]`_** A semantic colorscheme with a perceptual OKLCH engine, featuring four semantic roles and both dark and light variants. (Colorscheme / Markdown and LaTeX)
README
# Aalto.nvim
> Color that means something. Everything else fades away.

Most colorschemes are hex tables with opinions. Aalto is a perceptual color
engine that happens to produce a colorscheme.
The difference in practice: when you change a color in Aalto, you change a _hue
identity_. Contrast, saturation, and the visual hierarchy between roles are
recomputed automatically in [OKLCH](https://oklch.com) space — a perceptually
uniform color model where equal numeric steps look equal to the eye. You get a
coherent result without manually tweaking six related values.
---
## The idea
Aalto maps all of code down to four semantic roles and colors those. Everything
else — keywords, operators, punctuation, variables — renders in neutral
foreground.
| Role | Meaning | Examples |
| ------------ | --------- | ---------------------------------- |
| `definition` | Structure | functions, types, classes, modules |
| `constant` | Values | numbers, booleans, enum members |
| `string` | Data | string literals |
| `comment` | Context | comments, documentation |
The hierarchy `definition > constant > string > comment` is enforced
perceptually, not just numerically — each role is placed at a deliberate
distance from the background in OKLCH lightness, so the prominence ordering
holds across both dark and light variants regardless of hue.
The result is an editor that quietly shows you the shape of your code. The best
colorscheme is the one you stop noticing.
Read the full reasoning in [docs/philosophy.md](docs/philosophy.md).
---
## Features
- **Semantic-first** — four roles, consistent across every language
- **OKLCH color engine** — perceptually uniform; adjustments look right
- **Automatic contrast hierarchy** — definition > constant > string > comment
- **Dual palettes** — independent dark and light variants, hand-tuned
- **Deep plugin coverage** — Telescope, nvim-cmp, Neo-tree, Gitsigns, Which-key,
Trouble, Notify, and more
- **Extension API** — add highlight mappings for your own plugins without
modifying core files
- **Runtime commands** — switch variants, preview, reload without restarting
- **Built-in statusline** — minimal, semantic, opt-in
- **Health check** — `:checkhealth aalto` reports contrast, gamut, and
light/dark balance
---
## Requirements
- Neovim 0.9+
- 24-bit color terminal or GUI
---
## Installation
**lazy.nvim**
```lua
{
"micdzu/aalto.nvim",
priority = 1000,
config = function()
require("aalto").setup({})
vim.cmd("colorscheme aalto")
end,
}
```
**packer.nvim**
```lua
use {
"micdzu/aalto.nvim",
config = function()
require("aalto").setup({})
vim.cmd("colorscheme aalto")
end,
}
```
**vim-plug**
```vim
Plug 'micdzu/aalto.nvim'
```
```lua
require("aalto").setup({})
vim.cmd("colorscheme aalto")
```
---
## Quick start
```lua
-- Dark variant, all defaults
require("aalto").setup({})
vim.cmd("colorscheme aalto")
```
```lua
-- Light variant
require("aalto").setup({ variant = "light" })
vim.cmd("colorscheme aalto")
```
---
## Configuration
```lua
require("aalto").setup({
-- "dark" or "light"
variant = "dark",
-- Override raw palette hues. Contrast and hierarchy are re-applied on top.
palette = {
definition = "#7C8CFA",
string = "#8FC77C",
constant = "#B87EDC",
comment = "#746FA3",
},
-- Override semantic role colors directly, bypassing palette mapping.
semantic = {
definition = "#82AAFF",
},
-- Bold/italic for comments and keywords only.
styles = {
comments = { italic = true },
keywords = {}, -- e.g. { bold = true }
},
-- Transparent backgrounds.
transparent = false, -- main windows
float_transparent = false, -- floating windows
-- Set terminal_color_0 … terminal_color_15.
terminal_colors = true,
-- Applied last, wins over everything.
overrides = {
-- ["@keyword"] = { italic = true },
},
-- Enable built-in statusline.
statusline = false,
-- Print resolved palette after setup.
debug = false,
})
```
Full customization reference: [docs/customization.md](docs/customization.md)
---
## Commands
| Command | Description |
| ----------------------------- | --------------------------------------------- |
| `:AaltoVariant [dark\|light]` | Switch variant, or toggle if no argument |
| `:AaltoStatus` | Show current configuration |
| `:AaltoReload` | Re-apply highlights with the last used config |
| `:AaltoPreview dark\|light` | Preview a variant temporarily without saving |
---
## Lualine
```lua
require("lualine").setup({
options = {
theme = require("aalto").lualine_theme(),
},
})
```
Pass `{ lualine_style = "full" }` for a filled mode indicator instead of the
default minimal one.
---
## Custom plugin highlights
```lua
require("aalto").register_plugin_specs({
{
definition = { "MyPluginTitle", "MyPluginHeader" },
fg_dark = { "MyPluginBorder", "MyPluginSeparator" },
error = { "MyPluginErrorSign" },
string = { "MyPluginAddedLine" },
},
})
```
Available roles: `definition`, `constant`, `string`, `comment`, `fg`, `fg_dark`,
`error`, `warn`, `info`, `hint`, `bg`, `bg_light`, `selection`,
`inv_definition`, `inv_constant`, `inv_string`.
Full reference: [docs/plugins.md](docs/plugins.md)
---
## Health check
```vim
:checkhealth aalto
```
Reports contrast ratios, gamut warnings, and a light/dark comparison table.
---
## Architecture
```
base → variants → semantic → link() → groups → highlights
```
- **base** — raw hues (dark/light palettes)
- **variants** — UI surfaces derived from background in OKLCH
- **semantic** — lightness positioning, chroma shaping, hierarchy enforcement
- **link()** — role-to-highlight-spec translation
- **groups** — Neovim highlight group definitions
Full internals: [docs/design.md](docs/design.md)
---
## License
MIT