Components
Table of Contents
What emanix actually installs, by tier. Most of it is Home Manager; the substrate and the compositor are NixOS.
1. Home Manager tier (home/)
1.1. Emacs
The centre of the system, and the reason for the rest of it. A pgtk build with
a curated package set and modal editing.
There is exactly one Emacs build. Which one you get depends on
emanix.ewm.enable:
- true — the system-owned build, carrying the compositor's own package, put on
the system PATH so
emacsclientis available everywhere. Home Manager delivers configuration only, never a second Emacs. - false — the same package set minus the compositor, installed at the home level and run as a systemd user service.
Two builds of Emacs on one machine is the failure mode this design exists to prevent.
1.2. EWM — the compositor
A Wayland compositor written in Rust on Smithay, loaded as a dynamic module inside the Emacs process. Windows, workspaces, status bar: all of it is Emacs, so keybindings and configuration are one language. Upstream is codeberg.org/ezemtsov/ewm; what follows is how Emanix launches it.
It launches from the TTY login shell, inside the logind session scope. This is not the obvious approach — there is a shipped systemd user unit — but that unit runs outside any session and cannot acquire display-master without a display manager. Launching from the login shell was the working path.
Three details in that launch are load-bearing and were each found the hard way:
- One compositor per boot session. A stale daemon holds display-master and starves every new launch, so the launcher kills a prior instance first — and matches on the full command line, because the Nix wrapper truncates the process name.
- A flap guard. If the compositor crashes in a loop, a marker file drops you to a normal shell instead of an unusable login cycle. Remove it to re-arm.
- Keyboard options are set in the environment, not in the compositor's own config, because the keymap is built at compositor start — configuration applied afterwards is simply too late.
1.3. Terminal, shell, multiplexer
A GPU-accelerated terminal, gated on emanix.ghostty.enable; zsh with
completion and a themed prompt; and an optional multiplexer that SSH logins land
in, so remote sessions survive disconnection.
1.4. arc, and the line around it
This is the clearest place the distribution's boundary shows, because three adjacent things land on three different sides of it.
arc is shipped. It is the distribution's bundled companion: a local, offline
retrieval engine over this machine's own configuration — Emacs, Elisp, NixOS
and Home Manager options, and the org-roam vault — returning ranked, jumpable
citations rather than model-generated prose. Bound to s-i from any slot, and
to C-c i for its command map. When nothing in the searched scope matches, it
says so and names the scope, which is the whole point: a config index that
invents a NixOS option is worse than none. See
Keybindings.
The model runner is not shipped. arc's hybrid retrieval needs a local Ollama for embeddings, and Emanix does not install one — it is a substantial dependency to impose on a machine that may not want it, and a headless box very reasonably does not. Your flake supplies it. arc constructs its providers without contacting anything, so nothing here fails at load time on a host with no runner; at query time it falls back to keyword-only results rather than answering plausibly.
A coding agent is not shipped either. An AI harness is not a decision a
distribution should make for you. Emanix ships the wiring — the
emanix-agent-shell.el ACP glue (C-c C-' for Claude, C-c p for pi), the
adapter wrappers in agent-acp/, and a secret store your flake can point at a
credential. Supply the claude or pi CLI and the keys work; supply none and
the binding reports the missing adapter rather than failing silently. See
Secrets for why credential use and credential access
are separate questions.
1.5. Everything else
Search and file tooling, git and its helpers, a formatter and linters for Nix itself, Python tooling, media tooling, screenshot and screen-recording utilities for Wayland, a password manager, and fonts.
The list is one place. Feature flags decide which of it materializes: a host
with emanix.gui = false does not receive the GUI applications, because the
modules that provide them are gated on that flag. Nothing consults the role.
Two seams let a consumer extend the tier: emanix.emacs.extraPackages adds
Emacs packages to the distribution's build, and
emanix/modeline-extra-segments registers extra tab-bar segments as no-argument
functions. The distribution ships none of either.
2. NixOS tier (modules/)
Six modules. Three are the substrate.
2.1. Base — every host
Shell, primary user, timezone, locale, console keymap, and the Nix settings that make the rest sane:
- Flakes and the modern CLI enabled
- Store auto-optimisation
- Daily garbage collection, keeping the current generation and the two before
it (
--delete-generations +3) - A mid-build emergency valve: when free space drops below a floor, Nix collects garbage during the build until a ceiling is available again
That last pair matters more than it looks. A weekly timer is not enough on a host that builds often — a churning machine can accumulate many gigabytes of dead paths within a day or two of a successful collection. And on a virtualised host whose disk image never shrinks below its high-water mark, garbage that lives a week costs real disk on the host side even after it is finally collected.
2.2. init
The first system generation, and emanix-init on the PATH: the tool that adopts
a generated configuration into a git repository, and fails the build rather than
failing on a stranger's console.
2.3. Firstboot
Packages the one-time post-install command. It is built with a wrapper that shellchecks the script at build time, so a broken helper fails the build rather than the install.
2.4. The rest of the tier
gpu.nix and firmware.nix supply hardware capability, and ewm.nix is the
compositor service, exposed as nixosModules.ewm.
Every host gets the secret store: mkHost imports the agenix module, so a
consumer supplies recipients and secrets rather than wiring the mechanism.
3. Hardware and network
Capability, not facts. The distribution ships emanix.hardware.gpu, the
redistributable-firmware default, and lib.mkDisk for describing a disk's shape
— how to bring up a GPU or lay out a disk, not which GPU a box has or which
disk it is.
Which drivers must be in the initrd, how the disks are partitioned, what mesh or network the host joins — those are facts about a particular machine on a particular network, and only your flake knows them. See Architecture for the argument, which is the same one that removed the roles.