SandVim is a portable, declarative, NVF-based Neovim IDE distributed as a Home Manager module and as ready-to-build preset packages. It is extracted from a production dotfiles configuration but has no host, user, secret, Stylix, or personal dotfiles dependencies.
C++ and Nix editing with split buffers, Treesitter highlighting, inlay hints, Git status, and language-server integration.
Fast workspace navigation through fzf-lua with file icons and a rendered preview.
Markdown and Obsidian-style authoring with rendered callouts, task lists, tables, fenced code, and language services.
The screenshots use the full preset and the default gruvbox-dark-hard palette. The core theme, editor UI, statusline, bufferline, and finder are shared across all presets; language, debugging, notes, workflow, AI, and Java capabilities vary by preset.
SandVim uses Space as <leader>. These core navigation keys are available in every preset:
| Key | Action |
|---|---|
<leader>e |
Open Mini.files at the current file |
Mini.files l / h |
Enter a file or directory / move to the parent directory |
Mini.files L / q |
Open a file and close Mini.files / close the explorer |
<leader><leader> |
Find files with fzf-lua |
<leader>/ |
Search workspace text with fzf-lua live grep |
<leader>fb / <leader>fr |
Find open buffers / recent files |
<leader>gf |
Find Git-tracked files |
H / L |
Move to the previous / next buffer |
<C-h/j/k/l> |
Focus the split or tmux pane left/down/up/right |
Press <leader> and pause to open WhichKey. See the comprehensive hotkeys reference for all SandVim-defined mappings, preset gates, plugin-local keys, Mini.files operations, and a guide to key enabled integration defaults.
SandVim exports packages for:
x86_64-linuxaarch64-linuxx86_64-darwin(Intel macOS)aarch64-darwin(Apple Silicon macOS)
Native build and runtime checks run in CI on x86_64-linux, x86_64-darwin, and aarch64-darwin. The aarch64-linux outputs receive evaluation coverage because GitHub does not provide a matching hosted runner. Because Nixpkgs unstable 26.11 removed Intel macOS, x86_64-darwin package/check outputs use dedicated Nixpkgs, Home Manager, and NVF compatibility inputs.
- Nix with the
nix-commandandflakesfeatures enabled. - A flake-based Home Manager configuration, or the willingness to create one with the included template.
- Network access to GitHub. SandVim itself has no private inputs and does not require credentials for anonymous consumption.
If Nix is not installed, use the official Nix installation instructions or the installer approved by your organization. On managed work devices, confirm proxy, certificate, and software-approval requirements before installation.
Recent Determinate Nix and NixOS installations normally enable flakes already. Otherwise add the following to the applicable user or system nix.conf and restart the Nix daemon when using multi-user Nix:
experimental-features = nix-command flakesA separate global Home Manager installation is not required to build the template. Activation can use the Home Manager CLI or the generated activation package.
Launch the workplace-oriented minimal preset directly from the published release:
nix run github:sandmhan/sandvim/v0.2.0#sandvimMinimalThe package selector is the literal fragment after #. Change that fragment to choose the configuration intensity; the braces below describe the choice and are not part of the command:
| Configuration intensity | Package selector | Complete launch command |
|---|---|---|
| Minimal | #sandvimMinimal |
nix run github:sandmhan/sandvim/v0.2.0#sandvimMinimal |
| Standard | #sandvimStandard |
nix run github:sandmhan/sandvim/v0.2.0#sandvimStandard |
| Full | #sandvimFull |
nix run github:sandmhan/sandvim/v0.2.0#sandvimFull |
In other words, replace #sandvimMinimal with #sandvimStandard or #sandvimFull; do not write #sandvim{Minimal,Standard,Full} literally.
To open the current directory, pass it to Neovim after --:
nix run github:sandmhan/sandvim/v0.2.0#sandvimMinimal -- .nix run executes the packaged Neovim wrapper but does not supply the general command-line tools intentionally owned by module consumers. For a more representative trial with Git and search workflows available, use a temporary Nix shell:
nix shell \
github:sandmhan/sandvim/v0.2.0#sandvimMinimal \
nixpkgs#git \
nixpkgs#ripgrep \
-c nvim .Alternatively, enter the shell first and launch Neovim later:
nix shell github:sandmhan/sandvim/v0.2.0#sandvimMinimal nixpkgs#git nixpkgs#ripgrep
nvim .Use the same #sandvimMinimal, #sandvimStandard, or #sandvimFull selector with nix shell to inspect another preset. Those presets have substantially larger closures and enable AI integration; include nixpkgs#codex-acp in the shell if you intend to test that integration. The minimal preset is the recommended workplace trial.
These commands do not activate Home Manager, modify an existing Home Manager configuration, or update its flake.lock. Nix downloads the selected closure into the Nix store, and Neovim may create its normal cache, data, and state files under the user's XDG directories.
Exit Neovim normally with :qa or :qa!, then proceed with the module integration only if the trial is satisfactory.
Create an empty directory and initialize it from the released template:
mkdir work-home && cd work-home
nix flake init -t github:sandmhan/sandvim/v0.2.0#home-managerEdit flake.nix and replace username, system, and homeDirectory. Keep an existing user's current home.stateVersion; do not increase it merely because the example uses 24.11.
| Machine | system |
Typical homeDirectory |
Module |
|---|---|---|---|
| Intel Linux | x86_64-linux |
/home/<username> |
homeManagerModules.default |
| ARM Linux | aarch64-linux |
/home/<username> |
homeManagerModules.default |
| Intel macOS | x86_64-darwin |
/Users/<username> |
homeManagerModules.intelDarwin |
| Apple Silicon macOS | aarch64-darwin |
/Users/<username> |
homeManagerModules.default |
For Intel macOS, also replace the template's unstable inputs and default module:
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-26.05-darwin";
inputs.home-manager.url = "github:nix-community/home-manager/release-26.05";
# In homeManagerConfiguration.modules:
sandvim.homeManagerModules.intelDarwinThe existing follows declarations remain unchanged. This compatibility path is required because newer unstable Nixpkgs and Home Manager releases no longer support x86_64-darwin.
Lock and build before activation:
nix flake lock
nix build --dry-run .#homeConfigurations.<username>.activationPackage --show-trace
nix build .#homeConfigurations.<username>.activationPackageAfter reviewing the build, activate it using one of these methods:
# Works directly from the generated activation package.
./result/activate
# Alternatively, when the Home Manager CLI is installed.
home-manager switch --flake .#<username>Activation changes the user's managed home configuration. It is intentionally separate from the validation commands above.
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
sandvim = {
url = "github:sandmhan/sandvim/v0.2.0";
inputs.nixpkgs.follows = "nixpkgs";
inputs.home-manager.follows = "home-manager";
};
};
outputs = { nixpkgs, home-manager, sandvim, ... }:
let
system = "x86_64-linux";
username = "alice";
in {
homeConfigurations.${username} = home-manager.lib.homeManagerConfiguration {
pkgs = nixpkgs.legacyPackages.${system};
modules = [
sandvim.homeManagerModules.default
{
home = {
inherit username;
homeDirectory = "/home/${username}";
# Existing users must retain their current state version.
stateVersion = "24.11";
};
programs.sandvim = {
enable = true;
preset = "minimal";
colorScheme = "gruvbox-dark-hard";
packs = {
ai = false;
workflow = true;
languages = {
nix = true;
python = true;
web = true;
};
};
};
}
];
};
};
}For Home Manager embedded in NixOS or nix-darwin, import SandVim in the applicable user module rather than creating a second standalone Home Manager configuration:
home-manager.users.alice = {
imports = [ sandvim.homeManagerModules.default ];
programs.sandvim = {
enable = true;
preset = "minimal";
colorScheme = "gruvbox-dark-hard";
packs = {
ai = false;
workflow = true;
languages = {
nix = true;
python = true;
web = true;
};
};
};
};The surrounding system flake must already import home-manager.nixosModules.home-manager on NixOS or home-manager.darwinModules.home-manager on nix-darwin. Intel macOS consumers must use sandvim.homeManagerModules.intelDarwin and the compatible inputs shown in the consumer guide.
After activation, run a first-start health check:
nvim --headless "+checkhealth" "+qa"| Preset | Purpose | Feature packs |
|---|---|---|
minimal |
Small hardened editor foundation | Core editor, UI, completion, Treesitter, Git, finder, editing, and workspace hardening |
standard |
Broad polyglot IDE; external default | Minimal plus AI, debugging, notes, Tidal, workflow, documentation, Nix, Python, web, infrastructure, systems, and data/mobile |
full |
Complete curated configuration | Standard plus Java |
Explicit programs.sandvim.packs.* values override preset defaults. For workplace use, start with minimal and enable only approved language/workflow packs. In particular, keep packs.ai = false unless CodeCompanion/Codex ACP is approved for the source code being edited.
Standalone SandVim uses the exact Base16 Gruvbox dark hard palette by default. This matches the palette previously supplied to the source dotfiles' Neovim configuration by Stylix:
- Background:
#1d2021 - Foreground:
#d5c4a1 - Red:
#fb4934 - Yellow:
#fabd2f - Green:
#b8bb26 - Blue:
#83a598 - Purple:
#d3869b - Aqua:
#8ec07c
SandVim v0.1.x did not configure a theme itself. Without an external theme module it therefore used Neovim's built-in default dark palette, whose effective Normal colors were #14161b and #e0e2ea in the validated package. The source dotfiles looked different because Stylix injected Gruvbox highlights outside SandVim.
Select a bundled Gruvbox palette with one option:
programs.sandvim.colorScheme = "gruvbox-dark-hard";Available values are:
| Value | Background | Intended appearance |
|---|---|---|
gruvbox-dark-hard |
#1d2021 |
Dark, highest contrast; default and preferred palette |
gruvbox-dark-medium |
#282828 |
Dark, medium contrast |
gruvbox-light-hard |
#f9f5d7 |
Light, highest contrast |
gruvbox-light-medium |
#fbf1c7 |
Light, medium contrast |
none |
Unmanaged | Let Stylix or a direct NVF theme configuration own colors |
For example:
programs.sandvim = {
enable = true;
preset = "minimal";
colorScheme = "gruvbox-light-medium";
};When another module should control Neovim's theme, disable SandVim's ownership without disabling the editor:
programs.sandvim.colorScheme = "none";After selecting none, an advanced consumer may configure programs.nvf.settings.vim.theme directly. Do not enable both SandVim theme ownership and another Neovim theme provider, because whichever configuration loads last can overwrite highlights.
The ready-to-run sandvimMinimal, sandvimStandard, and sandvimFull packages use the default gruvbox-dark-hard palette. Package selectors change feature intensity, not the color scheme; use the Home Manager option to select a different palette.
Consumers that do not need option-level customization can install a preset Neovim wrapper directly. The wrapper contains NVF-managed editor and language tooling, while general command-line dependencies remain consumer-owned:
home.packages = [
sandvim.packages.${pkgs.system}.sandvimMinimal
pkgs.git
pkgs.ripgrep
];The standard/full wrappers also require codex-acp on PATH to use their enabled AI integration. Importing the Home Manager module is preferred because it installs required general tools and pack-specific Home Manager packages.
Available package attributes are:
sandvimMinimalsandvimStandardsandvimFulldefault(the standard preset)
programs.sandvim.enableprograms.sandvim.preset:minimal,standard, orfullprograms.sandvim.colorScheme: a bundled Gruvbox palette ornoneprograms.sandvim.packs.{ai,debugging,notes,tidal,workflow}programs.sandvim.packs.languages.{general,documentation,nix,python,web,infrastructure,systems,dataMobile,java}programs.sandvim.notes.{attachmentsFolder,templatesFolder}
The general language option is retained as a deprecated compatibility umbrella. Notes require the documentation pack. homeManagerModules.intelDarwin exposes the same SandVim option API as default while selecting the compatibility NVF module. Intel consumers must also choose compatible Nixpkgs and Home Manager releases as documented in the consumer guide.
nix flake show --all-systems
nix build .#checks.x86_64-linux.sandvimMinimalConsumer
nix build .#checks.x86_64-linux.sandvimMinimalRuntime
nix build .#checks.x86_64-linux.sandvimThemeOptions
nix build .#checks.x86_64-linux.sandvimThemeRuntime
nix build .#checks.x86_64-linux.sandvimMarkdownRuntime
nix build .#checks.x86_64-linux.sandvimJavaRuntime
nix build .#checks.x86_64-linux.sandvimStartupProfileExternal-consumer activation checks are exported for all supported systems and all presets. Runtime checks should only be run on a matching native system.
Profile closure size and startup time without activation:
scripts/profile-nvf.sh minimal --runs 3
scripts/profile-nvf.sh allSee the consumer guide for integration details, the hotkeys reference for the complete SandVim-defined mapping inventory, and the operations and IDE guide for language ownership, security boundaries, and troubleshooting.
SandVim embeds no API credentials. The optional AI pack uses CodeCompanion with Codex ACP and ChatGPT authentication performed outside Neovim. It does not provide pre-send secret redaction or sensitive-path blocking. Review all context before sending it to an external model.
Workspace-local Neovim configuration and modelines are disabled. Secret scanning is explicit through :NvfScanSecrets / <leader>tS and uses a Nix-provided gitleaks wrapper.
MIT


