Options Reference
Table of Contents
Every Emanix-specific setting lives under the emanix.* namespace.
Most are Home Manager options, set inside home-manager.users.<user> — or,
better, passed through mkHost's homeModules. Three groups are NixOS-level
instead, and are marked as such below: emanix.username, emanix.firstboot.*
and emanix.hardware.gpu.
Nothing here is set by a role, because there are no roles. A host gets the defaults unless the flake consuming Emanix says otherwise.
1. Core
1.1. emanix.username — NixOS level
| Type | string |
| Default | — (required) |
Which user the distribution configures. Read by modules/base.nix and
modules/ewm.nix to address home-manager.users.<name>.
Do not set it by hand. Pass username to mkHost; it sets this from the
same argument, so the option and the composed system cannot disagree.
1.2. emanix.role
| Type | enum: workstation / server / wsl |
| Default | workstation |
What shape of box this is. It selects nothing. No module is imported because
of it and no behaviour in the distribution branches on it. It is metadata: set
by mkHost from its role argument, exported to the shell as EMANIX_ROLE,
and interpreted by the consuming flake, which may well gate real things on it.
Like username, this is an argument rather than an opinion — so it is set
plainly, not with mkDefault. Overriding it to disagree with the value
mkHost was called with produces an incoherent host.
1.3. emanix.gui
| Type | bool |
| Default | true |
This machine has a graphical session. Gates the cursor theme, the Wayland tools, GUI applications, the screen locker, and terminal config.
1.4. emanix.hardware.gpu — NixOS level
| Type | enum: amd / intel, or null |
| Default | null |
The graphics driver to force-load in the initrd, so a compositor started
from tty1 does not lose the DRM-master race. null contributes nothing, which
is correct for a headless or virtualised host.
Setting it asserts that hardware.enableRedistributableFirmware is true —
forcing a driver into the initrd without its firmware blobs is a black screen,
and boot.initrd.allowMissingModules hides that at build time. See
Architecture for why a distribution ships the
capability and not the fact.
1.5. emanix.ewm.enable
| Type | bool |
| Default | false |
This machine's Emacs is the system-owned EWM build. When false, the home layer installs the non-EWM pgtk Emacs instead and runs the daemon as a systemd user service.
This is the single switch between "Emacs is my desktop" and "Emacs is an editor
with a daemon". Enabling it also means importing nixosModules.ewm from the
flake — the option gates the home side; the module supplies the compositor
service. See Components.
1.6. emanix.theme
| Type | enum of palette names |
| Default | catppuccin-mocha |
Active theme. An enum, not a string: the value is a lookup key for the theme plan, and the consumers of that plan degrade silently on a name that matches nothing, so a typo used to build cleanly and surface later as a theme that quietly did not apply. Now it is an eval error naming the valid set. See Theming.
1.7. emanix.emacs.extraPackages
| Type | function of the package set |
| Default | epkgs: [ ] |
Emacs packages the consuming flake adds to the distribution's Emacs build:
home-manager.users.<user>.emanix.emacs.extraPackages = epkgs: [ epkgs.s ];.
It takes the package set rather than a plain list, so the consumer never names
the Emacs variant — pkgs.emacs-pgtk is the distribution's choice and stays its
choice.
2. Source paths — emanix.src.*
Where things live on disk. Two different checkouts matter, and conflating them
is the classic mistake: path is this distribution's checkout,
dotfilesPath is your flake's.
| Option | Type | Default | Meaning |
|---|---|---|---|
emanix.src.path |
string | ~/projects/emanix |
The Emanix source checkout, used for live-editable config |
emanix.src.dotfilesPath |
string | ~/dotfiles |
The consumer's checkout — the flake that imports Emanix |
emanix.src.themesDir |
string | generated store path | The rendered theme tree. Read-only by default; override to supply your own |
emanix.src.binDir |
string | ${src.dotfilesPath}/bin |
Where the consumer's scripts live; put on PATH by the shell |
emanix.src.liveElisp |
bool | true |
Symlink the Emacs Lisp out of the Nix store |
2.1. On liveElisp
Symlinks the Lisp out of the Nix store, straight from the Emanix checkout, so edits take effect on restart with no rebuild.
Set false on a host with no checkout; the Lisp is then copied into the store and editing it requires a rebuild.
This is a deliberate seam, one of two in the distribution — the other is
emanix.emacs.extraPackages: it trades
generation-pinning for edit latency on the files that get edited most. The
content is still version-controlled — it is simply not content-hashed into the
system generation, so a rollback does not roll the Lisp back with it.
It also means moving or renaming the checkout breaks Emacs until the next rebuild, because the symlink target vanishes. Move and rebuild as one step.
3. Opt-in components
3.1. emanix.ghostty.enable
| Type | bool |
| Default | emanix.gui |
Install and configure the GPU-accelerated terminal. Defaults to the GUI flag, which is why it appears automatically on a graphical host — but it is a separate option so a headless-but-terminal host can opt in surgically. A WSL host under WSLg is the usual case: no compositor, but a real terminal is still wanted.
3.2. emanix.zellij.enable
| Type | bool |
| Default | false |
Terminal multiplexer, with SSH logins landing in a persistent session, so connections from other hosts resume where they left off.
4. Identity
| Option | Type | Default |
|---|---|---|
emanix.git.userName |
string | emanix user |
emanix.git.userEmail |
string | user@example.invalid |
The defaults are deliberately useless. A distribution must not ship somebody's name, and an invalid address is better than a plausible wrong one — it fails loudly the first time you push.
5. First boot — NixOS level
| Option | Type | Default |
|---|---|---|
emanix.firstboot.text |
lines | a stub that prints a message |
emanix.firstboot.runtimeInputs |
list of packages | [ ] |
Emanix owns the convention — a command called emanix-firstboot, shellchecked
at build time so a broken script fails the build rather than the install. It
does not own the content. Joining a mesh, pairing file sync and cloning your
flake are all your decisions, so you supply the script and the packages it
needs.
The default is a stub. If you never set text, first boot prints a message and
does nothing.
6. A note on the namespace
The namespace was named after an individual until 2026-08-14. That was both awkward to adopt and wrong in principle: the namespace is the distribution's public API, and nobody setting up their own machine wants to configure it under someone else's name.
The rename was verified as a no-op by comparing derivation paths across every
host rather than by rebuilding: two were byte-identical, and the third differed
only in three user-facing error strings that now name the correct option. The
2026-08-30 rename from eminix.* to emanix.* was proven the same way, by
closure diff — the only entries that moved were the ones carrying the name.