NH is a modern helper utility that aims to consolidate and reimplement some of the commands from various tools within the NixOS ecosystem. Our goal is to provide a cohesive, easily-understandable interface with more features, better ergonomics and at many times better speed. In addition to bringing together relevant 3rd party projects, NH also acts a super-convenient all-in-one utility that reimplements well known Nix commands.
- Unified CLI: Consistent, intuitive interface for NixOS, Home Manager, and Darwin workflows.
- Rich Interface: Each major function (
os
,home
,darwin
,search
,clean
) exposes granular subcommands and flags for fine-tuned control. - Enhanced Garbage Collection:
nh clean
extendsnix-collect-garbage
with gcroot cleanup, profile targeting, and time-based retention. - Build-tree Visualization:
nh os
and similar commands display build trees for clear dependency tracking. - Diff & Change Review: Integrated, super-fast diffing of derivation changes before activation or switch.
- Specialisation Support: Easily select or ignore NixOS & Home-Manager specialisations via flags.
- Generation Management: Inspect, rollback, and manage system generations with explicit targeting.
- Extensible & Futureproof: Designed for seamless, rapid addition of new subcommands and flags.
NH is packaged in nixpkgs, and is available under both nixpkgs stable and nixpkgs unstable. Outside of extreme circumstances, all updates will be backported to the stable branch. Refer to the installation section for more details. Make sure you submit an update request in Nixpkgs if the package is outdated.
One of the features and the core principles of NH is to provide a clean, uniform
and intuitive CLI for its users. The nh
command offers several subcommands,
all with their extensive CLI flags for extensive configuration.
nh search
- a super-fast package searching tool (powered by a ElasticSearch client).nh clean
- a re-implementation ofnix-collect-garbage
that also collects gcroots.
nh os
- reimplementsnixos-rebuild
1 with the addition of- build-tree displays.
- diff of changes.
- confirmation.
nh home
- reimplementshome-manager
.nh darwin
- which reimplementsdarwin-rebuild
.
See the help page for individual subcommands, or man 1 nh
for more information
on each subcommand.
The latest, tagged version is available in Nixpkgs as NH stable. This is recommended for most users, as tagged releases will usually undergo more testing.This repository also provides the latest development version of NH, which you can get from the flake outputs.
nix shell nixpkgs#nh # stable
nix shell github:nix-community/nh # dev
You can try NH today in a Nix shell today, no setup required!
We provide a NixOS module that integrates nh clean
as a service. To enable it,
set the following configuration:
{
programs.nh = {
enable = true;
clean.enable = true;
clean.extraArgs = "--keep-since 4d --keep 3";
flake = "/home/user/my-nixos-config"; # sets NH_OS_FLAKE variable for you
};
}
Tip
As of 4.0, NH fully supports both Nix flakes and classical NixOS configurations via channels or manual dependency pinning and the such. Please consider installables support mature, but somewhat experimental as it is a new addition. Remember to report any bugs!
- For flakes, the command is
nh os switch /path/to/flake
- For a classical configuration:
nh os switch -f '<nixpkgs/nixos>'
, ornh os switch -f '<nixpkgs/nixos>' -- -I nixos-config=/path/to/configuration.nix
if using a different location than the default.
You might want to check nh os --help
for other values and the defaults from
environment variables.
NH is capable of detecting which specialisation you are running, so it runs the
proper activation script. To do so, you need to give NH some information of the
spec that is currently running by writing its name to /etc/specialisation
. The
config would look like this:
{config, pkgs, ...}: {
specialisation."foo".configuration = {
environment.etc."specialisation".text = "foo";
# ..rest of config
};
specialisation."bar".configuration = {
environment.etc."specialisation".text = "bar";
# ..rest of config
};
}
Home specialisations are read from ~/.local/share/home-manager/specialisation
.
The config would look like this:
{config, pkgs, ...}: {
specialisation."foo".configuration = {
xdg.dataFile."home-manager/specialisation".text = "foo";
# ..rest of config
};
specialisation."bar".configuration = {
xdg.dataFile."home-manager/specialisation".text = "bar";
# ..rest of config
};
}
Contributions are always welcome. To get started, just clone the repository and
run nix develop
. We also provide a .envrc
for Direnv users, who may use
direnv allow
to enter a shell with the necessary dependencies.
NH consists of two modules. The core of NH is found in the src
directory, and
is separated into different modules. Some of the critical modules that you may
want to be aware of are nh::commands
for command interfaces, nh::checks
for
pre-startup checks and nh::util
to store shared logic.
The xtask
directory contains the cargo-xtask tasks used by NH, used to
generate manpages and possibly more in the future. Some of the
Once your changes are complete, remember to run fix.sh to applyg general formatter and linter rules that will be expected by the CI.
Lastly, update the changelog and open your pull request.
NH would not be possible without all thee tools we run under the hood
- Tree of builds with nix-output-monitor.
- Visualization of the upgrade diff with dix.
- And of course, all the crates we depend on.
Last but not least, thank you to those who contributed to NH or simply talked about it on various channels. NH would not be where it is without you.