Options Reference

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.*, emanix.hardware.gpu and emanix.installer.*.

Nothing here is set by a role, because there are no roles. A host gets the defaults unless the flake consuming Emanix says otherwise.

Settings for Emacs itself — the status bar, the prose renderer, buffer groups — are not options. They are Emacs variables, set from your own Emacs Lisp; see Emacs Settings. The EMANIX_* environment variables are listed at the end of this page.

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 (31.1) 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 — which base a host runs (pwayl/Skia 31.1 under EWM, pgtk 31.1 otherwise) is the distribution's choice.

A package the distribution does not ship is added the same way: epkgs: [ epkgs.weblorg ], for example.

1.8. emanix.emacs.base

   
Type package
Default — (none; evaluation fails if nothing sets it)

The Emacs derivation this host's Emacs packages are built from. Do not set it in a host config. It is set by whichever module owns the host's Emacs: nixosModules.ewm (the pwayl/Skia build) on EWM hosts, and the home layer's daemon module (pgtk) everywhere else. A consumer reads it when it has to build an Emacs package itself, so that package is byte-compiled by the same Emacs that loads it. There is deliberately no default: a default would be a variant decision nobody made, and a host that sets neither fails to evaluate rather than quietly building the wrong Emacs.

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.

4. Installer — NixOS level

Option Type Default
emanix.installer.flake path the distribution's own flake
emanix.installer.keysDir string or null null

These configure the installer ISO that nixosModules.installer builds (see Installation). flake is the flake repository the ISO stages at /etc/emanix/flake; a consumer points it at its own flake. keysDir is the absolute path of a keys/ directory of host key pairs to stage at /etc/emanix/keys, and null stages none. It must be a string naming the working tree, not a path inside the flake source: the private halves are gitignored, so a store-derived path stages only the .pub files and yields an ISO that cannot install. Reading it requires nix build --impure.

5. 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.

6. First boot — NixOS level

Both options configure one command, emanix-firstboot, which is put on the system PATH of the installed machine. The distribution owns the convention and the build-time check. It does not own the content: joining a mesh, pairing file sync and cloning your flake are your decisions, so you supply the script and the packages it needs.

6.1. emanix.firstboot.text

   
Type lines (a string; several definitions are joined with newlines)
Default a stub that prints three lines and does nothing else

The body of the emanix-firstboot script, as shell. It is built with writeShellApplication, so it is shellchecked at build time and runs with errexit, nounset and pipefail: a broken script fails your build, not the first boot — the one moment nobody is watching a screen they can debug from.

The default stub prints a heading, then No first-boot steps are configured., then Set emanix.firstboot.text in your consuming flake. A distribution cannot know what your first boot needs — a network to join, a configuration repository to clone, secrets to place — and a guessed script is wrong for everyone but its author.

emanix.firstboot = {
  runtimeInputs = [ pkgs.git ];
  text = ''
    git --version
    printf 'first boot done\n'
  '';
};

6.2. emanix.firstboot.runtimeInputs

   
Type list of packages
Default [ ]

The packages whose bin/ directories are put at the front of the script's PATH, ahead of the PATH it inherits. The default is empty on purpose: an earlier version listed three tools while the script used one, which is the kind of drift an unused input never announces. List what text calls, and nothing else.

6.3. Where it applies

  • You run emanix-firstboot yourself, once, after the first boot. Nothing runs it for you.
  • A host the installer generated in interactive mode sets neither option, so the command exists and prints the stub message. See Installation: it is for a fleet, not for a machine the installer just invented.
  • The installer ISO does not carry it. It runs on the installed system, where your text acts on the machine you built.

7. Environment variables

The distribution exports a small set of EMANIX_* variables. They exist so that code which cannot read the Nix configuration — Emacs, a shell script, the installer — can still find the facts the configuration decides.

Variable Set by Read by Meaning
EMANIX home/zsh.nix: shell and systemd user manager nothing in the distribution The Emanix checkout, from emanix.src.path
EMANIX_THEMES_DIR home/zsh.nix (shell, user manager); modules/ewm.nix (EWM login) emanix-theme.el, for every theme file it reads and links The rendered theme tree, from emanix.src.themesDir. Unset, Emacs falls back to ~/dotfiles/themes, a last resort that is usually absent
EMANIX_THEME home/zsh.nix (shell, user manager); modules/ewm.nix (EWM login) emanix-theme.el The host's build-time theme, from emanix.theme. Consulted once, to give a machine with no runtime state the theme its flake configures. It never overrides a theme you switched to
EMANIX_BIN_DIR home/zsh.nix (shell, user manager); modules/ewm.nix (EWM login) The shell, which puts it first on PATH; config.el (the calendar-sync binding); emanix-ewm-slots.el (Firefox fallback); a consuming flake's own Emacs Lisp The consumer's script directory, from emanix.src.binDir. Unset, the Emacs readers fall back to a bare relative path that resolves nowhere
EMANIX_DOTFILES home/zsh.nix (shell, user manager); modules/ewm.nix (EWM login) emanix-welcome.el, as the first candidate for the configuration repository The consumer's checkout, from emanix.src.dotfilesPath. Unset, the welcome buffer falls through to ~/flake and /etc/nixos and may report "no config repo yet"
EMANIX_ROLE home/zsh.nix, shell only nothing in the distribution The emanix.role label, for interactive use and for a consuming flake that chooses to branch on it
EMANIX_REPO You fresh-emanix-install A path to the flake the installer should use. Tried first; it is used only if it holds a flake.nix. Otherwise the installer tries its own parent directory, /etc/emanix/flake and common mount points
EMANIX_TARGET_ROOT The installer's own tests fresh-emanix-install Where the target system is mounted. Defaults to /mnt; nothing outside the tests sets it

Three delivery paths exist because three kinds of process start Emacs:

  • Login shell — programs.zsh.sessionVariables in home/zsh.nix.
  • systemd user manager — systemd.user.sessionVariables in the same file. The non-EWM Emacs daemon is a user service that never passes through a login shell. Home Manager writes these to ~/.config/environment.d/, which the manager reads at start: changing one needs systemctl --user daemon-reload and a restart of the service, not just a rebuild.
  • EWM login — environment.sessionVariables in modules/ewm.nix. EWM starts from the tty1 login shell, outside both paths above. Without this path, EMANIX_THEMES_DIR read as unset in the compositor's Emacs and every theme file silently missed.

EMANIX travels the first two paths and EMANIX_ROLE only the first, because nothing in Emacs reads either.

A consuming flake may define variables of its own under the same prefix. The reference consumer uses EMANIX_ISO_KEYS to hand its keys directory to the impure ISO build; that is the consumer's convention, and the distribution never reads it. Variables used only by the distribution's own checks are not listed.

8. 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.