README.md
April 17, 2026 · View on GitHub
LuxVim is a self-contained Neovim distribution with a focused plugin set, a pipeline-based core, and a complete user-config override layer. It installs in one command, runs in its own data directory, and stays out of the way of any existing Neovim setup.
Quick start
git clone https://github.com/LuxVim/LuxVim.git
cd LuxVim && ./install.sh
lux
The installer creates a lux launcher in ~/.local/bin/, bootstraps lazy.nvim, and syncs every plugin. If ~/.local/bin isn't on your PATH, add:
export PATH="$HOME/.local/bin:$PATH"
Features
- Isolated — runs with
NVIM_APPNAME=LuxVimandLUXVIM_ROOTset to the repo'sdata/directory, so LuxVim never touches your existing Neovim config or data. - Declarative plugin specs — every plugin is a small Lua table under
lua/plugins/<category>/. A 5-stage pipeline discovers, loads, validates, merges, and transforms them intolazy.nvimspecs. - User config layer — drop files under
~/.config/luxvim/(or setLUXVIM_CONFIG) to add plugins, override keymaps and autocmds, or extend the schema. Useextends = "name"to deep-merge,replaces = "name"to swap. - Action-based keymaps — keymaps resolve through a central action registry (
namespace.method), so the same action can be bound from multiple keys or reused from user config. - First-class diagnostics —
:LuxVimErrorsand:LuxVimValidatefor inspecting pipeline output and validating config without applying it. - Factory-based core —
schema,actions, andpipelineare explicit classes (M.new()+ lazyM.default()) so tests can build isolated instances without touching production state. - Test harness + CI — 105 plenary-busted cases across 11 suites, runnable via
./scripts/test.sh. GitHub Actions matrix runs on Neovimv0.10.0,stable, andnightly.
Requirements
- Neovim 0.10+
- Git
- macOS, Linux, or WSL
bashfor the installer and scripts
Usage
lux # open LuxVim (no file)
lux path/to/file # open a file
lux path/to/dir # open a directory
lux --headless "+Lazy! sync" +qa # headless plugin sync
Commands
| Command | What it does |
|---|---|
:LuxVimErrors | Show errors and warnings from the current session's pipeline run. |
:LuxVimValidate | Run the pipeline through the validate stage only (no bootstrap, no keymaps) and report issues. Safe to run anywhere, any time. |
:LuxVimGenerateTypes | Regenerate lua/types/plugin.lua from the schema. |
:Themes | Open the theme picker to browse, preview, install, and apply colorschemes. |
Key bindings
Leader is <Space>.
| Keys | Action |
|---|---|
<leader>fs | Save file (:write) |
<leader>fq | Quit (:quit) |
<leader>FQ | Force quit (:quit!) |
<leader>bye | Quit all, no save (:quitall!) |
<leader><leader> | Fuzzy find files (:Files) |
<leader>st | Search text across project (:Rg) |
<leader>e | Toggle file explorer (nvim-tree) |
<leader>1 … <leader>6 | Jump to window N |
<leader>wv | Vertical split |
<leader>wh | Horizontal split |
<C-/>, <C-_>, <C-`> | Toggle terminal (works in terminal mode too) |
<C-n> (terminal mode) | Exit terminal mode |
jk (insert mode) | Leave insert mode |
Every action is declared in lua/core/registry/keymaps.lua and resolved through the action registry; override any of them from your user config.
Installation detail
install.sh:
- Checks for
nvimandgit. - Writes
~/.local/bin/lux— a launcher that invokes Neovim withLUXVIM_ROOT="$(repo dir)",NVIM_APPNAME=LuxVim,XDG_DATA_HOME="$(repo dir)/data". - Creates
data/lazy/,data/luxlsp/,data/site/. - Clones
lazy.nvimintodata/lazy/lazy.nvim. - Runs
lux --headless "+Lazy! sync" +qato install all plugin specs.
Everything lives inside the repo's data/ directory; deleting it resets LuxVim to a clean state.
Architecture overview
init.lua
└── core/init.lua
├── pipeline (5 stages: discover → load → merge → validate → transform)
├── bootstrap (lazy.nvim)
├── actions (namespace.method registry)
├── keymap + autocmd (from registry/)
└── user commands (:LuxVimErrors, :LuxVimValidate, ...)
lua/core/lib/— factory modules (pipeline,schema,actions,registry) and utilities (paths,data,notify,platform,bootstrap,keymap,autocmd,typegen,validate).lua/core/registry/— central definitions for keymaps, autocmds, conditions, filetypes.lua/plugins/<category>/— plugin specs grouped by purpose:editor/,lib/,lsp/,navigation/,terminal/,ui/. Each category's_defaults.luaapplies to every spec in that directory.data/— plugin installs, LSP servers, lockfiles, dynamic specs written by the theme picker.
Every plugin spec follows the same shape:
return {
source = "author/repo", -- required
opts = { ... }, -- passed to setup()
config = function(_, opts) ... end, -- optional
dependencies = { "plenary.nvim" }, -- by source name
event = { "BufReadPost" }, -- lazy-load trigger
cmd = { "Command" }, -- lazy-load trigger
ft = "lua", -- lazy-load trigger
cond = "has_git", -- from registry/conditions.lua
actions = { toggle = function() ... end, open = ":Command" },
globals = { some_flag = 1 }, -- sets vim.g before load
}
See lua/core/lib/schema.lua for the full contract.
Customization
LuxVim reads user files from $LUXVIM_CONFIG (or $XDG_CONFIG_HOME/luxvim). The user layer can:
Override keymaps
-- ~/.config/luxvim/registry/keymaps.lua
return {
extends = true,
editor = {
{ lhs = "<leader>w", action = "core.save", desc = "Save file" },
},
}
Use extends = true to deep-merge into the framework registry, or replaces = true to swap it entirely.
Add or override plugins
-- ~/.config/luxvim/plugins/editor/my-plugin.lua
return {
source = "author/my-plugin",
event = "VeryLazy",
}
Target a framework plugin:
-- ~/.config/luxvim/plugins/ui/nvim-tree.lua
return {
extends = "nvim-tree",
opts = { view = { width = 40 } },
}
Pipeline hooks and schema extensions
-- ~/.config/luxvim/init.lua (runs before the pipeline executes)
local pipeline = require("core.lib.pipeline")
local schema = require("core.lib.schema")
schema.extend("plugin_spec", {
my_custom_field = { type = "string", desc = "…" },
})
pipeline.on("post_load", function(ctx)
-- inspect or mutate ctx.specs here
return ctx
end)
Included plugins
Editor
- nvim-treesitter — syntax
- fzf + fzf.vim — fuzzy finding
- quill.nvim — text editing helpers
Navigation & UI
- nvim-tree.lua — file explorer
- nvim-web-devicons — icons
- nvim-luxdash — startup dashboard
- nvim-luxline — statusline
- nvim-luxterm — terminal manager
- vim-luxpane — window management
- whisk.nvim — UI utilities
Colorscheme
- Default: fathom.nvim
- Additional themes browsable and installable through
:Themes.
LSP
- nvim-lspconfig — LSP client setup
Development
./scripts/test.sh # run the plenary-busted suite (105 cases)
./scripts/validate.sh # headless config validator; exits 1 on critical errors
lux # interactive sanity check
See CLAUDE.md for the full architectural contract (spec fields, registry lifecycle, test harness layout).
Troubleshooting
| Symptom | Fix |
|---|---|
lux not found | Add ~/.local/bin to PATH. |
| Plugin fails to load | :LuxVimErrors — shows every error and warning from the session's pipeline run. |
| Config change doesn't apply | :LuxVimValidate — runs the pipeline through validate only, shows which file errors. |
| Need a full reset | Delete data/ and run ./install.sh again. |
| Tests fail in CI | Run ./scripts/test.sh locally; CI uses the same command. Nightly Neovim may regress — fail-fast: false is set so stable is the gate. |
License
Apache License 2.0. See LICENSE.
Credits
- Neovim — the editor.
- folke/lazy.nvim — plugin manager.
- nvim-lua/plenary.nvim — test harness + shared utilities.
- junegunn/fzf and junegunn/fzf.vim — fuzzy finding.
- nvim-tree — file explorer + icons.
- nvim-treesitter — syntax.
- Theme catalog authors: catppuccin, folke (tokyonight), rebelot (kanagawa), EdenEast (nightfox), rose-pine, sainnhe (everforest, sonokai, edge), nyoom-engineering (oxocarbon), marko-cerovac (material), navarasu (onedark), and more.