Yet another Nix CLI helper. [Maintainers=@NotAShelf, @faukah]
## What Does it Do?
NH is a modern helper utility that aims to consolidate and reimplement some of
the commands and interfaces from various tools within the Nix/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 acting as a super-convenient, all-in-one utility that reimplements well-known
and commonly used Nix commands, NH is a _pretty_ tool that brings together
relevant 3rd party projects that you might be familiar with.
To get started with NH, skip to the [Usage](#usage) section.
## Features
- **Unified CLI**: Consistent, intuitive interface for many **Nix**, **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` extends `nix-collect-garbage`
with gcroot cleanup, profile targeting, and time-based retention.
- **Faster Nix Search**: search Nixpkgs via Elasticsearch for faster results
- **Eye Candy**: It looks great, without any compromise. I mean who does not
love some cool looking UIs?
- **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 a reimplementation of the CLIs you all know and love**, but with a
focus on safety and correctness. The language and design choices allow new
feature additions to be trivial and (almost) zero-cost.
- **Excellent Documentation**: Everything you can do with NH is documented.
Everything NH _does_ is documented. The user-facing and developer-facing
documentation is, and will always remain, up to date.
### Design
[Discussions]: https://github.com/nix-community/nh/discussions
[Issues]: https://github.com/nix-community/nh/issues
NH is an _unified_ CLI, meaning it aims to bring together core platform support
into a single, convenient utility. For the time being, this appears in NH's
interface as support for **NixOS** (first-class), **Home Manager** and
**Nix-Darwin**. We hope to provide a familiar, convenient and _good looking_
interface for users of any and all of those projects.
The familiar interface of NH should not be seen as a weakness, however, as NH is
NOT a nixos-rebuild wrapper, and is not constrained by the limits of such tools.
Simply put, our goal is to implement _not only_ what is available but instead go
above and beyond to implement additional commands and flags to **improve the
experience provided by the default tools**. Which is to say _plumbing_ and _sane
defaults_ matter. You get to enjoy the very tools that you are accustomed to,
with the benefits of a faster and safer language.
> [!IMPORTANT]
> Future goals of NH include providing support for lower-levels tools, such as
> `nixos-install`, and `nixos-generate-config` to become a drop-in replacement
> for most critical tools with the benefits of Rust. If you would like to
> provide feedback and create feature requests, those are welcome over at the
> [Discussions] and [Issues] tabs respectively.
## Status
[update request]: https://github.com/NixOS/nixpkgs/issues
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](#installation)
section for more details. Make sure you submit an [update request] in Nixpkgs if
the package is outdated.
### Installation
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.
```sh
nix shell nixpkgs#nh # stable
nix shell github:nix-community/nh # dev
```
You can try NH in a Nix shell today, no setup required!
### NixOS
We provide a NixOS module that integrates `nh clean` as a service. To enable it,
set the following configuration:
```nix
{
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 the new API 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 ''`, or
> - `nh os switch -f '' -- -I nixos-config=/path/to/configuration.nix`
> if using a different location than the default.
You might want to check `nh os --help` or `man 1 nh` for other values and the
defaults from environment variables.
#### Specialisations support
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:
```nix
{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-Manager
Home specialisations are read from `~/.local/share/home-manager/specialisation`.
The config would look like this:
```nix
{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
};
}
```
## Usage
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.
> [!TIP]
> NH supports various flags, [environment variables](#environment-variables) and
> setup options to provide the best possible user experience. See the `--help`
> page for individual subcommands, or `man 1 nh` for more information on each
> subcommand with examples. You may also use the relevant platform module, such
> as the NixOS module available in Nixpkgs, to customize it for your system as
> described in the installation section.
Under the `nh` command, there are two types of commands that you'll be
interested in:
### Global Subcommands
Global subcommands implement functionality around core Nix commands. As it
stands, we provide a **better search** and **better garbage collection**
experience, done so with two subcommands provided out of the box.
#### `nh search`
[SPAM]: https://github.com/feel-co/SPAM
We provide a super-fast search tool for Nix packages and NixOS/Home Manager
options (powered by an Elasticsearch client against search.nixos.org), offline
search against local [SPAM] databases, and Nixpkgs pull request and issue
search. All available as `nh search`!
The command exposes several explicit subcommands and a convenient shorthand:
[found here]: https://github.com/feel-co/spam/actions/workflows/auto-index.yml
| Invocation | What it does |
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `nh search ` | Shorthand; searches packages by default (see `NH_DEFAULT_SEARCH`.) |
| `nh search packages ` | Search Nixpkgs packages via elasticsearch API. |
| `nh search options [--scope=] ` | Search NixOS/Home Manager/nix-darwin options (`--scope`: `nixpkgs`, `home-manager`, `nix-darwin`, `all`.) |
| `nh search offline --db ` | Search a local [SPAM] database without network access. Generated DBs can be [found here]. |
| `nh search prs [--days ] ` | Search Nixpkgs pull requests and show branch reachability for merged PRs. Defaults to updates in the last 15 days. |
| `nh search issues [--days ] ` | Search Nixpkgs issues, excluding pull requests. Defaults to updates in the last 15 days. |
`--json` is shared by all search modes. `--limit`, `--channel`, and
`--platforms` are available on the modes that use them and on the shorthand
form. `nh search prs` and `nh search issues` use `GH_TOKEN` for GitHub
authentication. If `GH_TOKEN` is unset, NH reads the token from
`NH_GITHUB_TOKEN_FILE`, or from `$XDG_STATE_HOME/nh/github-token` falling back
to `~/.local/state/nh/github-token`. If no token is found in an interactive
terminal, NH prompts for one and saves it to that token file.
#### `nh clean`
Reimplementation of `nix-collect-garbage` that also collects gcroots with
various options for fine-graining what is kept, and additional context before
the cleanup process to let you know what is to be cleaned.
> [!NOTE]
> By default `nh clean` will automatically clean up your
> [gcroots](https://nixos.org/guides/nix-pills/11-garbage-collector.html#indirect-roots)
> directory, which will remove all your built result and direnv directories.
>
> Use `--no-gcroots` to skip all gcroot cleanup, or `--no-direnv` to preserve
> direnv gcroots while still cleaning everything else.
### Platform Specific Subcommands
Platform specific subcommands are those that implement CLI utilities for
**NixOS**, **Home Manager** and **Nix-Darwin**.
#### `nh os`
The `nh os` subcommand reimplements the Python script, `nixos-rebuild-ng`, [^1]
from ground up _with the addition of_:
- Build-tree displays via **nix-output-monitor** (nom).
- Pretty diffs of changes via **dix**
- Confirmation
and other additional changes to make the UI more intuitive, from supporting
environment variables to additional safeguards. Is this all? No, more is to
come.
#### `nh home`
The `nh home` subcommand reimplements the `home-manager` script, with the same
additions as `nh os`.
#### `nh darwin`
Last but not least, the `nh darwin` subcommand is a pure-rust reimplementation
of the `darwin-rebuild` script featuring the same additions as `nh os` and
`nh home`.
[^1]: `nh os` does not yet provide full feature parity with `nixos-rebuild`.
While a large collection of subcommands have been implemented, you might be
missing some features. Please visit
[#358](https://github.com/nix-community/nh/issues/358) for a roadmap.
### Command Examples
| Platform | Old Command (Without NH) | New Command (With NH) |
| ------------ | ---------------------------------------- | ------------------------------ |
| NixOS | `nixos-rebuild switch --flake .#myHost` | `nh os switch . -H myHost` |
| Darwin | `darwi