Summary
nixsh declares everything that lives in a terminal: shared environment and per-shell configuration (including fish universal variables and a guarded greeting) plus a terminal-native tool catalogue of shells, TUIs, CLI tools, and shell-integration hooks. Every binary is left to the system; the modules resolve each selection to the right package name per platform.
The core design rule is explicit: environment variables and PATH are shared
and rendered per shell, while aliases, functions, and completions stay per shell
because fish is not POSIX and a generic alias layer would render badly three
times.
What it is
- Shell modules:
homeModules.nixsh,nixosModules.nixsh, andsystemManagerModules.nixsh(seemodules/home.nix,modules/nixos.nix,modules/arch.nix). - Policy and catalogue split:
lib.policywithmodules/nixsh.nixfor shells,lib.toolsPolicywithmodules/tools.nixfor tools, backed bylib/shells.nixandlib/tools.nixdata. - An underlay adoption pattern (absorbed from the earlier fish work) for typed per-shell extension of vendor-owned files, including fish universal-variable primitives.
- Two source-backed packages:
crow-cli(absent from normal sources) andtermpdf(NixOS half of an AUR-only tool). - Declared checks: tool and underlay evaluation, systemd-user
PATHprojection, desktop-entry build, and Crow CLI legs, plusexperiments/andstudies/notes.
It has deliberately no per-host story: every host has a shell, unlike the display-substrate family.
How it works
One nixsh.environment declaration renders into fish’s set -gx form and into
POSIX export form for bash and zsh. Greetings, login-shell assignment, rc
files, and terminal selection compose on top. The tool catalogue resolves each
nixsh.tools.selected entry into per-platform package names (NixOS,
official-repository, AUR) with lean, integrate, and shell-hook dimensions,
recording sources that exist on only one platform as explicit exceptions.
The underlay merges typed fragments into files the system or vendor already
owns, with per-directory ordering documented in studies/. The systemd-user
PATH projection carries a literal placeholder for the session manager to
expand later; expanding it at Nix evaluation time would silently produce a wrong
session PATH.
How to configure it
Compose the module for the target platform, then use the observed nixsh.*
surface:
nixsh.environment.variablesandnixsh.environment.path— the single shared declaration.nixsh.fish, shell-specific aliases, functions, andinteractiveInit— deliberately per shell.nixsh.tools.<group>(core,integrate,nav,edit,git,system,network,data,media,archive,integrity,comms,record,misc) pluslean— catalogue selection by group;tools.selectedand the per-platform package lists are internal read-only resolution results, not inputs.nixsh.underlay*and greeting options — adoption of owned files and first-run presentation.
Review checks/tools-eval.nix, checks/underlay-eval.nix, and the studies/
naming notes (delta, micro, nvtop, p7zip, yq) before assuming a name resolves
identically on both platforms.
Tutorial
This example uses invented values against the real option interface from the
referenced revision. The interface shape below was evaluated with the actual
homeModules.nixsh module at the pinned revision using synthetic values only;
the resolved catalogue confirms the selection.
# Synthetic example: invented environment and tool choices.
{
imports = [ inputs.nixsh.homeModules.nixsh ];
nixsh = {
environment.variables.EDITOR = "hx";
environment.path = [ "/opt/tools/bin" ];
tools.integrate = [ "starship" ];
};
}Selection happens through catalogue groups such as tools.integrate;
tools.selected is an internal read-only view of the resolved entries, not an
input. Per-shell content stays per shell by design:
# Synthetic example: public placeholder only.
nix run github:example-org/nixsh-demo#crow-cli -- --helpTreat catalogue names as platform-resolved selections to verify per host, not as literal package names.
Evidence and limits
This page is bound to public revision
7e71aa2c714a51a0603e25652625336ae414436c. That tree contains the flake
outputs, modules/ host modules, lib/shells.nix, lib/tools.nix,
packages/crow-cli.nix, packages/termpdf.nix, the checks/ suite, and the
experiments/ plus studies/ material discussed above.
CNIX has not independently established a successful evaluation, shell render, tool resolution, or session result for that revision. The tutorial interface above was evaluated against the real module at that revision with synthetic values: environment settings pass type checking, the catalogue group accepts the selection, and the resolved entries confirm it. Catalogue coverage, underlay merge behavior, and greeting flows are described from source structure, not from reproduced runs.
Related
nixsh owns terminal environment and tool selection only. Compositor setup, remote session forwarding, memory policy, file sharing, and tiny-VM server profiles are sibling concerns with their own revision-addressed concepts. Its relationship to other Corbet Nix projects is currently a shared design direction, not evidence of runtime integration.