โ Why kickstart-nix.nvim
If Nix and Neovim have one thing in common,
it's that many new users don't know where to get started.
Most Nix-based Neovim setups assume deep expertise in both realms,
abstracting away Neovim's core functionalities
as well as the Nix internals used to build a Neovim config.
Frameworks and module-based DSLs are opinionated and difficult to diverge from
with one's own modifications.
kickstart-nix.nvim is different:
It's geared for users of all levels,
making the migration of Neovim configurations to Nix straightforward.
This project aims to be as simple as possible, while allowing
for maximum flexibility.
Note
Similar to kickstart.nvim,
this repository is meant to be used by you to begin your
Nix/Neovim journey; remove the things you don't use and add what you miss.
๐ Philosophy
- KISS principle with sane defaults.
- Manage plugins + external dependencies using Nix
(managing plugins shouldn't be the responsibility of a plugin). - Configuration entirely in Lua1 (Vimscript is also possible).
This makes it easy to migrate from non-nix dotfiles. - Use Neovim's built-in loading mechanisms. See:
- Use Neovim's built-in LSP client, with Nix managing language servers.
๐ Features
- Use either nixpkgs or flake inputs as plugin sources.
- Usable on any device with Neovim and Nix installed.
- Create multiple derivations with different sets of plugins,
and simple regex filters to exclude config files. - Uses Nix to generate a
.luarc.jsonin the devShell'sshellHook.
This sets up lua-language-server to recognize all plugins
and the Neovim API.
๐ด Test drive
If you have Nix installed (with flakes enabled),
you can test drive this by running:
nix run "github:nix-community/kickstart-nix.nvim"๐ Usage
- Click on Use this template
to start a repo based on this template. Do not fork it. - Add/remove plugins to/from the Neovim overlay.
- Add/remove plugin configs to/from the
nvim/plugindirectory. - Modify as you wish (you will probably want to add a color theme, ...).
See: Design. - You can create more than one package using the
mkNeovimfunction by- Passing different plugin lists.
- Adding
ignoreConfigRegexes(e.g.= [ "^ftplugin/.*.lua" ]).
Tip
The nix and lua files contain comments explaining
what everything does in detail.
โก Installation
โ๏ธ NixOS (with flakes)
- Add your flake to your NixOS flake inputs.
- Add the overlay provided by this flake.
nixpkgs.overlays = [
# replace <kickstart-nix-nvim> with the name you chose
<kickstart-nix-nvim>.overlays.default
];You can then add the overlay's output(s) to the systemPackages:
environment.systemPackages = with pkgs; [
nvim-pkg # The default package added by the overlay
];Important
This flake uses nixpkgs.wrapNeovimUnstable, which has an
unstable signature. If you set nixpkgs.follows = "nixpkgs";
when importing this into your flake.nix, it may break.
Especially if your nixpkgs input pins a different branch.
๐ง Non-NixOS
With Nix installed (flakes enabled), from the repo root:
nix profile install .#nvim๐ค Design
Directory structure:
โโ flake.nix
โโ nvim # Neovim configs (lua), equivalent to ~/.config/nvim
โโ nix # Nix configs๐ Neovim configs
- Set options in
init.lua. - Source autocommands, user commands, keymaps,
and configure plugins in individual files within theplugindirectory. - Filetype-specific scripts (e.g. start LSP clients) in the
ftplugindirectory. - Library modules in the
lua/userdirectory.
Directory structure:
โโ nvim
โโโ ftplugin # Sourced when opening a file type
โ โโโ <filetype>.lua
โโโ init.lua # Always sourced
โโโ lua # Shared library modules
โ โโโ user
โ โโโ <lib>.lua
โโโ plugin # Automatically sourced at startup
โ โโโ autocommands.lua
โ โโโ commands.lua
โ โโโ keymaps.lua
โ โโโ plugins.lua # Plugins that require a `setup` call
โ โโโ <plugin-config>.lua # Plugin configurations
โโโ after # Empty in this template
โโโ plugin # Sourced at the very end of startup (rarely needed)
โโโ ftplugin # Sourced when opening a filetype, after sourcing ftplugin scriptsImportant
- Configuration variables (e.g.
vim.g.<plugin_config>) should go innvim/init.lua
or a module that isrequired ininit.lua. - Configurations for plugins that require explicit initialization
(e.g. via a call to asetup()function) should go innvim/plugin/<plugin>.lua
ornvim/plugin/plugins.lua. - See Initialization order for details.
๐ Nix
You can declare Neovim derivations in nix/neovim-overlay.nix.
There are two ways to add plugins:
- The traditional way, using
nixpkgsas the source. - By adding plugins as flake inputs (if you like living on the bleeding-edge).
Plugins added as flake inputs must be built manually.
Directory structure:
โโ flake.nix
โโ nix
โโโ mkNeovim.nix # Function for creating the Neovim derivation
โโโ neovim-overlay.nix # Overlay that adds Neovim derivation๐ Initialization order
This derivation creates an init.lua as follows:
- Add
nvim/luato theruntimepath. - Add the content of
nvim/init.lua. - Add
nvim/*to theruntimepath. - Add
nvim/afterto theruntimepath.
This means that modules in nvim/lua can be required in init.lua and nvim/*/*.lua.
Modules in nvim/plugin/ are sourced automatically, as if they were plugins.
Because they are added to the runtime path at the end of the resulting init.lua,
Neovim sources them after loading plugins.
๐ Pre-configured plugins
This configuration comes with a few plugins pre-configured.
You can add or remove plugins by
- Adding/Removing them in the Nix list.
- Adding/Removing the config in
nvim/plugin/<plugin>.lua.
โ Syncing updates
If you have used this template and would like to fetch updates
that were added later...
Add this template as a remote:
git remote add upstream git@github.com:nix-community/kickstart-nix.nvim.gitFetch and merge changes:
git fetch upstream
git merge upstream/main --allow-unrelated-histories๐ Editing your config
When your neovim setup is a nix derivation, editing your config
demands a different workflow than you are used to without nix.
A quick and easy way to test your changes:
- Perform modifications and stage any new files2.
- Run
nix run /path/to/neovim/#nvim
ornix run /path/to/neovim/#nvim -- <nvim-args>
This requires a rebuild of the nvim derivation, but has the advantage
that if anything breaks, it's only broken during your test run.
When developing locally you might want to have a faster feedback loop.
Normally the whole Neovim configuration is copied into the store and
the wrapper which nix generates for the derivation calls nvim
with -u /nix/store/path/to/generated-init.lua.
We can deactivate this behavior with wrapRc = false, so that the
config is loaded from $XDG_CONFIG_HOME/$NVIM_APPNAME3, where
$NVIM_APPNAME defaults to nvim if the appName attribute is not set
in the mkNeovim function.
The Flake exposes a dev shell with a nvim-dev package. The lua configuration in ./nvim
is automatically symlinked to ~/.config/nvim-dev.
After activating the shell with nix develop or nix-direnv
you can run Neovim with nvim-dev to automatically reload your lua configuration. All Nix changes still require a rebuild.
๐ Alternative / similar projects
kickstart.nvim:
Single-file Neovim configuration template with a similar philosophy to this project.
Does not use Nix to manage plugins.neovim-flake:
Configured using a Nix module DSL.NixVim:
A module system for Neovim, with a focus on plugin configs.nixCats-nvim:
A project that organises plugins into categories.
It also separates lua and nix configuration.lz.n:
A plugin-manager agnostic Lua library for lazy-loading plugins.
Can be used with Nix.
Note
When comparing with projects in the "non-Nix world", this
repository would be more comparable to kickstart.nvim (hence the name),
while the philosophies of neovim-flake and NixVim are more in line with
a Neovim distribution like LunarVim
or LazyVim
(though they are far more minimal by default).
Footnotes
-
The absence of a Nix module DSL for Neovim configuration is deliberate.
If you were to copy thenvimdirectory to$XDG_CONFIG_HOME,
and install the plugins, it would work out of the box. โฉ -
When adding new files, nix flakes won't pick them up unless they
have been committed or staged. โฉ -
Assuming Linux. Refer to
:h initializationfor Darwin. โฉ
