Open-source project
nix-community/nixvim avatar
nix-community/nixvim

Nixvim: configuring Neovim with Nix modules instead of a hand-written init.lua

Configure Neovim with Nix! [maintainers=@GaetanLepage, @traxys, @mattsturgeon, @khaneliman]

2,961 stars403 forksNixMIT

At a glance

What is it?
Nixvim turns a Neovim setup into a Nix module tree, then generates Lua at build time. It suits people who already manage machines with flakes or Home Manager, and it is a poor fit if you want to edit Lua and see the change immediately.
Who is it for?
Adopt Nixvim if Neovim already lives inside a flake or Home Manager setup and you want plugin options expressed as typed Nix attributes rather than a hand-maintained init.lua; skip it if you tune your editor interactively and dislike rebuild cycles.
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 received new commits within the last day.
What is it written in?
Mainly Nix, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem Nixvim solves: an init.lua that drifts from the rest of your system

A normal Neovim setup is a directory of Lua and a plugin manager that resolves versions at runtime. That works until the editor is one of several things you configure declaratively. Then you have two sources of truth: the Nix expression that builds your machine, and the Lua that builds your editor. Nixvim closes that gap by making Neovim itself a Nix module. The README describes it as "a Neovim distribution built around Nix modules", distributed as a flake and configured through Nix, with room left for your own plugins and your vimrc. The audience is narrow and specific: people already running NixOS, nix-darwin or Home Manager who want editor configuration to be part of the same evaluated system, reviewed in the same repository, and rolled back with the same generation mechanism. If you do not already manage your machine with Nix, the cost of adopting Nixvim is the cost of adopting Nix, and nothing in the project reduces that.

How Nixvim works: modules in, generated Lua out

The mechanism is a build step, not a runtime layer. According to the README, when you build the module (probably through Home Manager) Nixvim installs your plugins and generates a Lua config for Neovim containing the options you specified. Using Lua is a deliberate choice: the README states it ensures the configuration loads as fast as possible, and that because everything is disabled by default the result is as snappy as you want it to be. So the trade is explicit. You give up the ability to edit a file and see the effect on the next restart; in exchange the editor's configuration becomes a derivation, and the plugin set becomes a pinned input rather than whatever the plugin manager fetched today.

The escape hatches matter as much as the module system. Most plugins expose a settings option that accepts any Nix attribute set and translates it into a Lua table, which is then passed to that plugin's setup function. The README is direct about the consequence: if a plugin has a settings option, any plugin option can be configured even when no corresponding Nix option exists. For everything else there is extraConfigLua, plus extraConfigLuaPre and extraConfigLuaPost for ordering. Where a value of the wrong type needs to be Lua, Nixvim has a raw type written as { __raw = "lua code"; }, which the README shows turning into a Lua table entry. That raw type is the seam between the two languages, and it is where type checking stops.

Installing Nixvim with flakes, and a first configuration that actually does something

The README carries a warning worth reading before anything else: Nixvim must be installed with a compatible nixpkgs version, the main branch requires nixpkgs-unstable, and nixpkgs 26.05 users should use the nixos-26.05 branch. Getting this wrong is the most common way a first attempt fails.

If you are not using flakes, the project ships flake-compat so the module can be imported from any system. The README's example fetches the repository with builtins.fetchGit and imports one of three modules depending on your platform.

nix
{ pkgs, lib, ... }:
let
  nixvim = import (builtins.fetchGit {
    url = "https://github.com/nix-community/nixvim";
    # If you are not running an unstable channel of nixpkgs, select the corresponding branch of Nixvim.
    # ref = "nixos-26.05";
  });
in
{
  imports = [
    # For Home Manager
    nixvim.homeModules.nixvim
    # For NixOS
    nixvim.nixosModules.nixvim
    # For nix-darwin
    nixvim.nixDarwinModules.nixvim
  ];

  programs.nixvim.enable = true;
}

With flakes, the README's alternative is to add the input and import the module from it. The README recommends not overriding Nixvim's nixpkgs input with follows, because Nixvim is tested against its own nixpkgs revision.

nix
{
  # ...
  inputs.nixvim = {
    url = "github:nix-community/nixvim";
    # If you are not running an unstable channel of nixpkgs, select the corresponding branch of Nixvim.
    # url = "github:nix-community/nixvim/nixos-26.05";
  };
}

Once the module is imported, the options live under programs.nixvim.

Writing a first configuration: colorscheme and status line in six lines

The README's own example is the shortest path to a working editor. It enables the module, turns on the catppuccin colorscheme, and enables lualine. The README notes that lualine gets a sensible default setup and picks up catppuccin with no extra configuration.

nix
{
  programs.nixvim = {
    enable = true;

    colorschemes.catppuccin.enable = true;
    plugins.lualine.enable = true;
  };
}

For a configuration that is not tied to NixOS or Home Manager, the README's standalone path evaluates a configuration and uses its package output, and the recommended starting point is the project's flake template.

bash
nix flake init --template github:nix-community/nixvim

Standalone use, the flake template, and the test derivation

Nixvim does not require NixOS or Home Manager. The README lists four ways to use it: the Home Manager, nix-darwin and NixOS modules, plus standalone through makeNixvim. Standalone means evaluating a configuration and using its package output, and the README shows a minimal flake where nixpkgs follows nixvim's own nixpkgs input and the outputs are generated per system. One detail in that standalone example is easy to miss: the configuration also exposes a test derivation through configuration.config.build.test, which the README says can be used from checks. That gives you a way to fail a build when the editor configuration breaks, rather than discovering it the next time you open the editor.

Where Nixvim gets in the way

The nixpkgs coupling is the sharpest limitation and it is self-inflicted by design. Nixvim is tested against its own nixpkgs revision, and the README recommends not overriding its nixpkgs input with follows, pointing to the installation guide for the reason. That means the editor's dependency set is not automatically the same as the rest of your system's. You either accept Nixvim's pinned nixpkgs, or you take on a configuration the project explicitly advises against. Neither option is free.

The second cost is the edit loop. Nothing in the README suggests a live-reload path; the description of the build step is that plugins are installed and Lua is generated. If your normal workflow is opening a plugin's source, changing a value, and restarting Neovim, Nixvim inserts a rebuild between you and that change. The raw type is the pressure valve, but it is also a hole: once a value is written as { __raw = "..."; }, it is a string as far as Nix is concerned, and no option checking applies to what is inside it. A configuration that leans heavily on __raw has most of the drawbacks of plain Lua with extra steps.

Finally, the plugin surface is uneven. The settings option covers plugins that have a setup function and a settings attribute. Plugins that do not are configured through extraConfigLua, which is ordinary Lua with none of the module system's structure. The README does not claim coverage is complete, and it does not document rollback beyond what Nix generations give you.

Nixvim against NVF, and against a plain Lua config

The comparison people search for is Nixvim versus NVF, another Nix-based Neovim configuration. The README does not discuss NVF, so the honest difference to state is the one visible here: Nixvim's stated approach is to leave room for your plugins and your vimrc, and to expose per-plugin settings attributes that pass any attribute set through to the plugin's setup function. That is an open-ended mapping rather than a fixed curated set of options. A plain Lua configuration with a plugin manager differs in the opposite direction: it resolves plugins at runtime, so a plugin update can change behaviour without any commit in your repository, and it needs no Nix evaluation to edit. Nixvim's advantage is that the whole editor is a pinned, reproducible artifact; its disadvantage is that every change is a build.

Licence, maintenance and what an upgrade actually costs

Nixvim is MIT licensed, which is permissive and imposes no copyleft obligation on your configuration; that is a statement about the licence text, not legal advice, and the LICENSE file in the repository root is the authority. The repository is not archived and the last push was on 2026-09-23, so the branch you import is moving. Upgrades are not a version bump you can defer indefinitely: the branch you track determines which nixpkgs you must pair it with, and the README's warning makes the pairing mandatory rather than advisory. In practice an upgrade means moving the Nixvim input and the nixpkgs channel together, then rebuilding and seeing whether any option you used was renamed or removed. The generated option set is the surface that changes, and the standalone test derivation is the mechanism the project itself exposes for catching that at build time.

Editorial conclusion

Adopt Nixvim if Neovim already lives inside a flake or Home Manager setup and you want plugin options expressed as typed Nix attributes rather than a hand-maintained init.lua; skip it if you tune your editor interactively and dislike rebuild cycles. Before committing, check that your nixpkgs channel matches the Nixvim branch you import, and confirm the specific plugin options you rely on exist in the generated option set, because anything without a dedicated option has to go through a plugin's settings attribute or extraConfigLua.

Frequently asked questions

What is Nixvim?

Nixvim is a Neovim distribution built around Nix modules, distributed as a Nix flake and configured through Nix. It installs your plugins and generates a Lua config for Neovim from the options you specify, while leaving room for your own plugins and your vimrc.

How do I install Nixvim?

Import one of the modules (nixvim.homeModules.nixvim for Home Manager, nixvim.nixosModules.nixvim for NixOS, or nixvim.nixDarwinModules.nixvim for nix-darwin) and set programs.nixvim.enable = true. The README warns that the main branch requires nixpkgs-unstable, and that nixpkgs 26.05 users should use the nixos-26.05 branch instead.

Can I use Nixvim without NixOS or Home Manager?

Yes. The README lists standalone use through the makeNixvim function as one of four supported ways, where you evaluate a configuration and use its package output. The recommended starting point is running nix flake init --template github:nix-community/nixvim in an empty directory.

How do I configure a plugin option that Nixvim has no Nix option for?

Most plugins have a settings option that accepts any Nix attribute set and translates it into a Lua table passed to the plugin's setup function, so any plugin option can be configured that way. For anything outside that, extraConfigLua, extraConfigLuaPre and extraConfigLuaPost add Lua lines directly.

What is the __raw type in Nixvim for?

It assigns Lua code to an option that would normally accept another type such as a string or an integer, written as { __raw = "lua code"; }. The README's example shows a function value being emitted into the generated Lua table.

Official sources

  1. Issues
  2. License: MIT
  3. nix-community/nixvim on GitHub
  4. Project website
  5. README
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/nix-community-nixvim.svg)](https://hysenlabs.com/projects/nix-community-nixvim)