Components

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 emacsclient is 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.