How to Use Nixvim: The Beginner's Guide (First Module, the options Lesson, First Plugin, and the LSP Arc)

CodexFuse Team · 2026-11-06T17:52:28.859Z · 21 min read min read

What Is Nixvim and How Do You Use It?

Nixvim is a Neovim distribution built around Nix modules, and learning how to use Nixvim means learning to declare your whole editor in Nix instead of editing init.lua by hand. One module carries everything, your options, keymaps, plugins, language servers, and colorscheme, and Nixvim turns it into the Lua configuration Neovim loads. As of November 2026, this nixvim tutorial pins every command to the current stable branch, nixos-26.05, with main as the rolling unstable alternative.

The mental model is simple: instead of installing plugins at runtime, you describe the editor once and Nixvim generates the configuration for Neovim. Your plugins install from nixpkgs, your settings live as Nix options, and your whole editor rebuilds with the system instead of drifting across dotfiles. That is the whole promise of the nixvim nixos module, one source of truth for how the editor behaves, versioned in your flake.

Nixvim is not a Neovim fork, a replacement, or a separate editor. It is the same Neovim, configured through the Nix module system, and it leaves room for plain Lua through extraConfigLua when you need an escape hatch. Everything is disabled by default, so the editor stays as fast as you want it to be.

Devenv provisions whole development environments while Nixvim configures the editor inside them, and the two are complementary, never rivals. The Devenv beginner guide covers the environment side of the same Nix story, while this guide covers the editor itself. CodexFuse offers no Nixvim tool, so this guide teaches the tool itself, from install to first plugin.

Nixvim is free and open source under the MIT License, with no paid tier to quote. The repository had 2,981 stars and 408 forks when this guide was written, which works out to 7.31 stars per fork and a 13.69 percent fork ratio, and it was created 2020-12-30, making it 2,137 days old as of this writing. It is actively maintained: the newest commit on main landed 2026-10-17, 20 days before this writing, and the repository was last pushed 2026-11-05, one day before this writing.

The project also carries 120 open issues, which works out to 4.03 open issues per 100 stars, and 4,779 commits in total. It gains about 1.39 stars per day since creation, a slow and steady pace for a developer tool. The newest stable branch commit is a flake lock bump, and the project lists four maintainers in its README.

How to Use Nixvim in 7 Steps

Follow these seven steps to go from a bare Nix setup to a working Nixvim editor. Each step builds on the last, and the whole arc takes one configuration file. Keep your flake open beside this guide as you work through them.

  1. Enable flakes in your Nix configuration, so your flake can declare inputs.
  2. Add the nixvim input to your flake, pinned to the nixos-26.05 branch.
  3. Import the matching module, homeModules for Home Manager or nixosModules for NixOS.
  4. Set programs.nixvim.enable to true and rebuild your system or home configuration.
  5. Set your first options, globals, opts, and keymaps, in the same module.
  6. Enable your first plugin with plugins.lualine.enable and rebuild again.
  7. Enable your first language server under plugins.lsp.servers and open a file to check it works.

The rest of this guide walks each step slowly, with the exact code for every move. By the end you will have a versioned editor you can rebuild on any machine with one command.

Nixvim vs Neovim: What Is the Difference?

Neovim is the editor, a fork of Vim with a Lua core and a built-in language server client. Nixvim is a configuration system for that editor, a set of Nix modules that generates the Lua configuration Neovim reads at startup. You still run nvim at the end, and every keystroke behaves like Neovim because it is Neovim.

The difference is where the configuration lives and how it is installed. A plain Neovim setup keeps init.lua in your home directory and installs plugins at runtime with a plugin manager. A Nixvim setup keeps every setting as a Nix option in your flake, and Nix installs the plugins from nixpkgs when you rebuild.

If you have never configured the editor itself, the Neovim beginner guide covers the plain-editor side first, and this guide picks up where it leaves off.

The trade is control for reproducibility. You give up editing init.lua directly and installing plugins on a whim, and in return your editor becomes a versioned artifact that rebuilds identically on every machine. For a Nix user, that trade is usually the whole point.

Before You Start: What You Need

You need Nix with flakes enabled, and either NixOS or Home Manager to host the module. Flakes are the input mechanism this guide uses, so enable the nix-command and flakes experimental features before you start. The standalone route covered later in this guide works without a system module, but the module route is the one most readers want.

You also need a Git repository for your flake, because flake inputs are fetched from Git. The Git beginner guide covers the basics if Git is new to you. Keep your flake in version control from the first commit, since the flake lock file is what pins every input.

A tool-version manager keeps the rest of your toolchain tidy while Nixvim owns the editor. The Mise beginner guide covers installing language runtimes outside Nix, which is useful when a project needs a runtime Nixvim does not manage. Nixvim itself needs no version manager, since the branch pin does that job.

Finally, decide which channel you run before you pick a branch. NixOS 26.05 is the current stable release, supported through 2026-12-31 with 55 days of support left as of this writing. NixOS 25.11 went end of life on 2026-06-30, 129 days ago, so do not pin anything to it.

How Do You Install Nixvim? The Flake Input

Installation is one input in your nixvim flake, plus one import in your configuration. The input points at the nix-community/nixvim repository on GitHub, and the branch you choose must match your nixpkgs channel. This section shows the stable pin, and the branch lesson later in this guide explains why the match matters.

{
  inputs.nixvim = {
    url = "github:nix-community/nixvim/nixos-26.05";
  };
}

That single input is the whole install for the stable track. If you run nixpkgs-unstable instead, point the input at github:nix-community/nixvim with no branch suffix, which follows main. Update the input and your nixpkgs together, since the docs recommend always updating both at the same time.

Without flakes, the same input works through a direct import instead. The install docs show a builtins.fetchGit import with a ref option for the branch, and the same three module attributes work from there. Flakes are the recommended route, and the rest of this guide assumes them.

{ pkgs, lib, ... }:
let
  nixvim = import (builtins.fetchGit {
    url = "https://github.com/nix-community/nixvim";
    ref = "nixos-26.05";
  });
in
{
  imports = [ nixvim.homeModules.nixvim ];
  programs.nixvim.enable = true;
}

The flake input also carries the lock file entry that pins the exact revision. Run nix flake update when you want newer revisions, and commit the lock file so every machine rebuilds the same editor. A lock file you never commit is a pin that only exists on one machine.

How Do You Enable Nixvim? programs.nixvim.enable

Enabling Nixvim is one boolean, once the module is imported. The module import tells your configuration that the programs.nixvim options exist, and the enable flag turns the generated editor on. Everything after this section is configuration, not installation.

{
  programs.nixvim = {
    enable = true;
    colorschemes.catppuccin.enable = true;
    plugins.lualine.enable = true;
  };
}

That three-line block is the canonical first configuration from the project README, and it already produces a working editor. The catppuccin colorscheme and the lualine status line are both real plugins, installed from nixpkgs and configured through their Nix modules. Rebuild after adding it, then open nvim and confirm the colors and status line appear.

ShapeModule importWhere it lives
NixOS modulenixvim.nixosModules.nixvimconfiguration.nix or a flake nixosConfigurations entry, system-wide editor
Home Manager modulenixvim.homeModules.nixvimhome.nix or a flake homeConfigurations entry, user-level editor
nix-darwin modulenixvim.nixDarwinModules.nixvimdarwin-configuration.nix, macOS editor
Standalone derivationno module import, flake input onlyany flake package output, evaluated with nixvim.lib.evalNixvim

Pick the shape that matches where your configuration already lives. The nixvim home manager module is the route this guide uses in its examples, since the editor is a user tool, and the README assumes that route when it says the module is probably built using Home Manager. The options are identical in every shape, and only the import and the enable location change.

A small tip from the install docs saves typing later. Use programs.nixvim.imports to include a separate file that configures Nixvim, and inside that file you can drop the programs.nixvim prefix entirely. Your options then read as plugins.lualine.enable instead of programs.nixvim.plugins.lualine.enable.

The standalone shape skips the module entirely and evaluates a configuration into a package. The docs show nixvim.lib.evalNixvim taking a system and a list of modules, with the built editor at configuration.config.build.package. A test derivation at configuration.config.build.test fails the build when the configuration is broken, so it doubles as a smoke test.

makeNixvim is legacy now, so use evalNixvim in new configurations.

{
  description = "A very basic flake";
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05";
    nixvim.url = "github:nix-community/nixvim/nixos-26.05";
  };
  outputs =
    { nixpkgs, nixvim, ... }:
    let
      system = "x86_64-linux";
      configuration = nixvim.lib.evalNixvim {
        inherit system;
        modules = [ { colorschemes.gruvbox.enable = true; } ];
      };
    in
    {
      packages.${system}.default = configuration.config.build.package;
    };
}

How Do You Match the Nixvim Branch to Your Channel?

Nixvim has no release tags, branches are the versioning. The main branch tracks a very recent nixpkgs-unstable, and each stable NixOS release gets its own nixos branch. Pick the branch that matches the channel your system already runs, and never mix them.

Your channelNixvim branchNotes
nixpkgs-unstablemainrolling track, docs at nix-community.github.io/nixvim
NixOS 26.05nixos-26.05current stable, docs at nix-community.github.io/nixvim/26.05
NixOS 25.11nixos-25.11stale, do not use, the release is end of life
NixOS 25.05nixos-25.05older stable, upgrade to 26.05

A mismatch fails loudly at build time, which is the good outcome. The install docs say a wrong branch produces errors saying a vimPlugins attribute was not found, because the plugin set in your nixpkgs does not match the module set Nixvim expects. When you see that error, check the branch first, before you touch anything else.

Do not add inputs.nixpkgs.follows to the nixvim input. Nixvim is tested against its own nixpkgs revision, and overriding that input is a prime cause of the cannot be found in pkgs errors the FAQ documents. Update both inputs together instead, and let the lock file record the pair that works.

The main branch HEAD landed 2026-10-17, 20 days before this writing, while the nixos-26.05 HEAD landed 2026-09-21, 46 days before this writing, as a flake lock bump. NixOS 26.05 itself released 2026-05-30, 160 days before this writing, with 55 days of support left. That gap is normal: the stable branch moves only when its lock file needs a bump.

Your First Options: globals, opts, and Keymaps

Options are where the editor starts to feel like yours. Nixvim exposes every Neovim option through the opts attribute, and you set them as plain Nix values instead of Vimscript or Lua. Two lines give you line numbers and relative line numbers, and the same pattern covers every option in the Neovim manual.

{
  programs.nixvim = {
    enable = true;
    globals.mapleader = " ";
    opts = {
      number = true;
      relativenumber = true;
      shiftwidth = 2;
    };
    keymaps = [
      { key = ";"; action = ":"; }
      {
        mode = "n";
        key = "<leader>m";
        options.silent = true;
        action = "<cmd>!make<CR>";
      }
    ];
  };
}

To disable an option, set it to false rather than inventing a negative name. The README is explicit: to turn numbers off you set opts.number to false, not opts.nonumber. The same rule holds for every boolean option in the set.

OptionWhat it doesExample value
globalsVim global variables, including the leader keyglobals.mapleader = " "
optsEvery Neovim option from the option listopts.number = true
keymapsKey bindings as a list of attribute setskeymaps = [ { key = ";"; action = ":"; } ]
extraConfigLuaRaw Lua appended to the generated init.luaextraConfigLua = "vim.opt.wrap = false;"
extraConfigLuaPreRaw Lua placed before the generated configextraConfigLuaPre = "-- early setup"

Raw Lua is the escape hatch, not the default. Use extraConfigLua for lines that have no Nix option yet, and keep everything else declarative so the configuration stays searchable. If you find yourself writing long Lua blocks, check whether a plugin module already exposes the setting.

The man pages carry the full option reference on your own machine. When enableMan is true, which is the default, the same documentation installs as man pages you can read with man nixvim. The hosted docs mirror the same reference for the branch you run.

Your First Plugin: Enable One With a Single Line

The nixvim plugins catalogue is one module per plugin, and enabling any of them is a single boolean. The pattern is always the same: plugins, the plugin name, and enable, as in plugins.lualine.enable. That one line is the whole install story for every supported plugin.

{
  programs.nixvim = {
    enable = true;
    plugins = {
      lualine.enable = true;
      telescope.enable = true;
      treesitter.enable = true;
      nix.enable = true;
    };
  };
}

Most plugin modules also expose a settings option that accepts any Nix attribute set. Nixvim translates that set into a Lua table and passes it to the plugin setup function, so any setting the plugin documents is reachable even when no dedicated Nix option exists. That design is why a one-line enable can still grow into a fully tuned plugin.

PluginWhat it addsEnable line
lualineStatus line at the bottom of the editorplugins.lualine.enable = true
telescopeFuzzy finder for files, buffers, and textplugins.telescope.enable = true
treesitterSyntax highlighting and parsing from grammarsplugins.treesitter.enable = true
nixNix language support for editing nix filesplugins.nix.enable = true
harpoonQuick navigation between marked filesplugins.harpoon.enable = true

A plugin without a module still works, through extraPlugins. List the package from pkgs.vimPlugins, then call its setup function from extraConfigLua, and the plugin loads like any other. If you do that often for the same plugin, consider requesting a module upstream.

Some plugins install extra packages into the editor PATH, and Nixvim lets you switch those off. The treesitter module, for example, can add gcc to the PATH, and its gccPackage option can be set to null to skip it. Check the per-plugin option pages when a plugin pulls in a tool you do not want.

The LSP Arc: Language Servers the Nix Way

Language servers turn the editor into an IDE, with jump to definition, hover documentation, and diagnostics as you type. The nixvim lsp path is plugins.lsp.servers, with one enable line per server, as in plugins.lsp.servers.nixd.enable. There is no separate installer step, and no server downloads itself at runtime.

{
  programs.nixvim.plugins.lsp.servers = {
    nixd.enable = true;
    lua_ls.enable = true;
    pyright.enable = true;
  };
}

Each server page documents the same shape: an enable flag, a package option pointing at the nixpkgs derivation, and settings passed through to the server. When nixpkgs has no package for a server, the docs say so plainly, and you must provide an external derivation or set the package to null. The nixd example in the standalone docs shows the same shape with settings attached.

ServerLanguagePackage source
nixdNixnixpkgs, nixd.enable = true
lua_lsLuanixpkgs, lua_ls.enable = true
pyrightPythonnixpkgs, pyright.enable = true
astroAstronixpkgs, astro.enable = true
jdtlsJavanixpkgs, jdtls.enable = true

Under the hood, Nixvim now rides Neovim native LSP, not the old lspconfig setup calls. The server pages describe the generated Lua as vim.lsp.enable calls, which is the Neovim 0.11 and newer mechanism. Do not teach or copy the old require lspconfig setup style into a Nixvim configuration, since that is the pre-0.11 world.

The newest Neovim release in the wiki infobox is 0.12.2, released 2026-04-22, 198 days before this writing. That version ships the native LSP client Nixvim targets, so the pairing is current, not aspirational. When Neovim moves again, the nixvim branch you pinned moves with it.

Why Mason Cannot Run on NixOS

Mason does not work on Nix. The plugin downloads language servers as dynamically linked binaries built for generic Linux, and NixOS cannot run those binaries out of the box. The failure is architectural, not a bug you can configure around, so this guide teaches the Nix-native route instead.

Three independent sources confirm the same failure. The haripm guide states plainly that Nix is the only package manager you need, with no lazy.nvim and no mason.nvim.

The NixOS wiki troubleshooting section shows a Mason-downloaded lua-language-server failing with a dynamically linked executable error. The wiki packaging page shows the same failure for a Mason-downloaded rust-analyzer, missing the dynamic loader entirely.

The workaround some guides suggest is nix-ld, which lets unpatched dynamic binaries run on NixOS. It works, and the gist that teaches running Lua Neovim distributions on NixOS uses it, but it is a workaround for distributions, not the Nixvim route. The Nixvim route is simpler: enable the server under plugins.lsp.servers and let nixpkgs supply the binary.

The same rule covers tree-sitter grammars and every other tool Mason would fetch. Install grammars pre-compiled through the treesitter module, and install formatters and linters as nixpkgs packages in extraPackages. Your editor then rebuilds from the lock file, with nothing downloaded at runtime.

Your First Colorscheme, and Nixvim vs the Lua Distributions

The nixvim colorscheme scope is colorschemes, with one enable line per scheme, as in colorschemes.catppuccin.enable. The canonical first configuration pairs catppuccin with lualine, and every supported plugin adopts the main colorscheme by default. Change one line and the whole editor re-themes on the next rebuild.

{
  programs.nixvim = {
    enable = true;
    extraPlugins = [ pkgs.vimPlugins.gruvbox ];
    colorscheme = "gruvbox";
  };
}

When a colorscheme has no module, install it with extraPlugins and set it with the colorscheme option. The README shows exactly that fallback for gruvbox, and it works for any colorscheme packaged in nixpkgs. Prefer the module form when one exists, since the module also wires the plugin-specific colorscheme settings.

The editor is one layer of the look, and the system around it is another. The Stylix beginner guide themes the whole system from one declaration, while Nixvim configures the editor itself, so the two are complementary, never rivals. Theme the editor here, and let Stylix carry the same palette to the terminal and the rest of the desktop.

DistributionHow it configures NeovimWhere the config lives
NixvimNix options in a flake moduleyour flake, rebuilt with the system
kickstart.nvimA single documented Lua filecloned into ~/.config/nvim
LazyVimLua starter config on lazy.nvimcloned from the LazyVim starter
NVChadPre-configured Lua frameworkcloned into ~/.config/nvim

Kickstart, LazyVim, and NVChad are Lua distributions you clone into your config directory, and a plugin manager installs their plugins at runtime. Nixvim is the Nix-declarative route: the same editor, but every setting is a Nix option in your flake. The wiki lists all four side by side as pre-made distributions, and the choice is about which package manager you trust with your editor.

The other Nix route worth naming is the one the haripm guide teaches. That 427-day-old guide configures programs.neovim with a raw init.lua symlinked through Home Manager, and it names Nixvim as an alternative it did not take. The wiki does mention nixvim too, in its frameworks and distributions sections, though its own teaching stays programs.neovim-first.

Start with the module route in this guide, and keep the Lua route in mind for the day a plugin needs raw config. Both rebuild with the system, and both keep the editor out of imperative dotfiles. The difference is only whether you write Lua or declare options, and this guide has shown you the declarative side.

The numbers in this guide were computed from the repository page fetched on 2026-11-06, and the code below reproduces every one of them.

# computed from the nixvim repo page, fetched 2026-11-06
from datetime import date
today = date(2026, 11, 6)
repo_created = date(2020, 12, 30)
print('repo created 2020-12-30')
print('repo age days:', (today - repo_created).days)
print('stars per fork:', round(2981 / 408, 2))
print('fork ratio percent:', round(408 / 2981 * 100, 2))
print('open issues per 100 stars:', round(120 / 2981 * 100, 2))
print('days since main HEAD 2026-10-17:', (today - date(2026, 10, 17)).days)
print('days since nixos-26.05 HEAD 2026-09-21:', (today - date(2026, 9, 21)).days)
print('days since last push 2026-11-05:', (today - date(2026, 11, 5)).days)
print('days since haripm 2025-09-05:', (today - date(2025, 9, 5)).days)
print('days since NixOS 26.05 release 2026-05-30:', (today - date(2026, 5, 30)).days)
print('days of 26.05 support left:', (date(2026, 12, 31) - today).days)
print('days since 25.11 EOL 2026-06-30:', (today - date(2026, 6, 30)).days)
print('days since Discourse thread 2024-05-16:', (today - date(2024, 5, 16)).days)
print('days since Neovim 0.12.2 2026-04-22:', (today - date(2026, 4, 22)).days)
print('stars per day:', round(2981 / (today - repo_created).days, 2))

Sources

The primary sources for this guide are the Nixvim install docs, the standalone usage page, and the FAQ page, all hosted at nix-community.github.io/nixvim, plus the project README and repository page at github.com/nix-community/nixvim, all fetched on 2026-11-06. The branch rule, the four module shapes, the enable flag, and the no-follows warning all come from the install docs. The LSP server option pages supplied the per-server enable paths and the native vim.lsp mechanism.

The independent field comes from the haripm guide Setting up Neovim on NixOS, published 2025-09-05 and 427 days old at writing, which teaches programs.neovim with a raw init.lua, and from the NixOS wiki Neovim page, which names nixvim in its frameworks and distributions sections. The oldest independent thread in the field is a NixOS Discourse help thread from 2024-05-16, 904 days old, which holds a minimal config fragment rather than a walkthrough. The NixOS 26.05 release announcement supplied the release and support dates, and the LazyVim site and the kickstart.nvim README supplied the Lua-distribution positioning.

The repository numbers in this guide are a 2026-11-06 snapshot: 2,981 stars, 408 forks, 120 open issues on the issues page, 165 open issues and pull requests combined in the API count, and 4,779 commits. The GitHub API returned a rate-limit error when re-checked from this network, so the star and fork counts were confirmed from the repository page itself. Search volume for the primary keyword is unknown, and no nixvim version number exists to quote, since branches are the versioning.

Frequently Asked Questions

Is Nixvim the same as Neovim?

No. Neovim is the editor, and Nixvim is a Nix module system that configures it. You run nvim either way, but with Nixvim the configuration is a set of Nix options in your flake instead of an init.lua file.

Which Nixvim branch should I use?

Use nixos-26.05 if you run NixOS 26.05, and use main if you run nixpkgs-unstable. A mismatch produces vimPlugins attribute errors at build time, so match the branch to your channel before you rebuild.

Can I use Mason with Nixvim?

No, not on NixOS. Mason downloads dynamically linked binaries that NixOS cannot run out of the box, so enable language servers through plugins.lsp.servers instead. The nix-ld workaround exists for other distributions, but it is not the Nixvim route.

Do I need flakes to use Nixvim?

Flakes are the recommended route, but not the only one. Without flakes you can import Nixvim with builtins.fetchGit and a branch ref, and the same three module attributes work from there. The standalone evalNixvim route also works without a system module at all.

Can I use Nixvim with Home Manager instead of NixOS?

Yes. Import nixvim.homeModules.nixvim in your home configuration and set programs.nixvim.enable to true, exactly as this guide shows. The options are identical in every module shape, so a configuration written for Home Manager moves to NixOS unchanged.

Featured on Twelve Tools Hunt for Tools Featured on LaunchBuff Launch Llama Tools Launch your MCP Top Web Development Companies in the US - OnToplist.com Designer Listings Listed on SeeWhatNewAI Featured on SubmitMySaas Featured on AI Agents Directory Product Wing SaaS Wheel