Skip to content
Velle Sinclair edited this page Aug 7, 2026 · 1 revision

Nix

Two separate things share this page because they share a language, and it is worth being clear about which is which before either is useful:

  1. A declarative user environment — Nix + Home Manager installed beside pacman, managing packages and dotfiles for your account.
  2. Install profiles — a file that answers the installer's questions, so an install is reproducible instead of re-typed. Written in Nix, or in plain key=value.

Both are optional. Neither is on unless you asked for it.

This is not NixOS. SynapseOS is Arch. pacman owns the system — the compositor, the daemons, the drivers, the kernel — before you install Nix and after. Nix owns a user environment on top. If you are looking for "declare the whole machine in one file and rebuild it", that is NixOS the operating system, not Nix the package manager, and this is not that.


Turning it on

At install time: pick Full, or answer yes to "Nix + Home Manager" in Custom. The installer installs nix, enables nix-daemon.socket, and writes the configurator to /etc/synapseos/nix.

Afterwards, on a system that declined it:

sudo pacman -S nix
sudo syn nix init

syn nix init is the same code the installer runs — there is one implementation, not two.

Nothing is built during the install. Setting the config up takes seconds; realising it is a multi-gigabyte download from cache.nixos.org, and the nix daemon is not running inside the installer's chroot anyway. So a fresh install leaves the layer ready and the first build is yours to start:

syn nix apply        # as your user, after a reboot — this is the download

The configurator

/etc/synapseos/nix, owned by your account so you can edit it without sudo:

File
flake.nix The inputs, pinned by flake.lock. nixpkgs-unstable and the matching home-manager branch
home.nix Yours. Packages and dotfiles. syn nix edit opens it
facts.nix Generated. What this machine actually is — do not edit it

facts.nix is the bridge

Nix on a foreign distro cannot see what pacman did. So SynapseOS probes the installed system and hands the result to your expressions as facts:

{
  system      = "x86_64-linux";
  version     = "0.2.7";
  hostname    = "synapse";
  username    = "syn";
  desktop     = "synui";          # synui | kde | gnome | tty
  gpu         = "nvidia";         # nvidia | amd | intel | vm | none
  allowUnfree = true;             # nvidia and Steam are unfree
  want = {
    model = true;  bluetooth = true;  printing = true;  filemgr = true;
    wine  = true;  phone = false;     steam = true;     blackarch = true;
    nix   = true;
  };
}

which lets one home.nix react to the machine instead of being edited per machine:

home.packages = with pkgs; [ ripgrep fd ]
  ++ lib.optionals facts.want.steam     [ protontricks ]
  ++ lib.optionals facts.want.blackarch [ nmap ]
  ++ lib.optionals (facts.gpu != "vm")  [ vulkan-tools ];

The same probe runs at install time and any time afterwards:

syn nix facts        # re-derive it from this machine

so it stays true. Install without Steam, add it with pacman a month later, run that, and the facts follow. It reads what is actually installed rather than what you once told the installer, which is why the two cannot disagree.


Commands

syn nix status      daemon, store size, whether the flake is set up
syn nix apply       build the config and activate it
syn nix build       build it without activating
syn nix update      bump flake.lock to current nixpkgs / home-manager
syn nix facts       re-derive facts.nix from this machine
syn nix edit        open home.nix in $EDITOR
syn nix rollback    list home-manager generations
syn nix profile F   render an install profile (see below) — unrelated to the above
syn nix init        first-time setup (root; the installer does this for you)

Three things that will bite you

Do not manage synuirc from home.nix

It is tempting — declare ~/.config/synui/synuirc and the desktop is declarative too. It does not work, and it fails in a shape that takes a while to recognise.

Home Manager materialises the files it manages as read-only symlinks into /nix/store. But synuirc is written at runtime, by synui itself and by synctl, every time a setting changes. Declaring it does not make your version win — it makes every write from the control panel fail, and that shows up as a panel whose toggles flip back a second later with no error anywhere you can see it.

The same applies to anything else written live: the wallpaper engine's state, kdeglobals while a KDE app is running. Declare the packages; leave live state to whatever owns it.

/etc/synapseos/nix is deliberately not a git repository

Flakes copy their directory into the store, and inside a git repo they copy only what git tracks. A freshly generated facts.nix would be invisible, so the build would either evaluate last week's facts or fail with "path does not exist" — and nothing in that error points anywhere near git.

If you want it under version control, keep the repo elsewhere and symlink, or git add facts.nix after every regeneration.

Packages shadow pacman's

targets.genericLinux.enable puts the Nix profile ahead of the system on PATH. That is what makes .desktop files from Nix packages show up in the launcher, and it also means anything you install here that pacman also provides will be the one you get. Sometimes that is the point (a newer version than Arch ships); usually it is two copies of one thing and a pacman -Qo that no longer explains which is running. Prefer packages pacman does not have.


Install profiles

Different feature, same language. facts.nix describes a machine that exists; an install profile prescribes one that does not yet.

syn-install --config profile.nix       # or a plain key=value file

Whatever the profile leaves out is still asked at the machine. Pinning just the disk layout and the package set is a perfectly good profile — this is not all-or-nothing, and a partial one is the normal case.

{
  disk          = "vda";
  install_mode  = "erase";
  confirm_erase = true;

  filesystem = "btrfs";
  bootloader = "limine";
  snapshots  = true;

  preset = "custom";
  want   = { steam = false; blackarch = true; nix = true; };

  username = "syn";
  desktop  = "synui";
  timezone = "America/Chicago";
}

/usr/share/syn/nix/profile-example.nix documents every key.

Three things worth knowing

Keys are semantic, never menu positions. filesystem = "btrfs", not filesystem = 2. A number means whatever that row happens to be on the day you install, and menus grow entries.

A key that answers nothing is reported by name at the end of the run. bootlaoder = "limine" is not a syntax error — it is silence, and silence is how this kind of file usually fails: you find out when the machine boots the wrong loader. The installer lists unused keys instead.

The destructive confirmations are separate keys on purpose. confirm_erase, confirm_alongside and confirm_format each have to be written out. An unattended install that erases a disk should have said so in writing; leave them out and the installer stops and asks, which is the right outcome for a profile that was not meant to run unattended.

Passwords. password and luks_passphrase are real keys, because an unattended install needs them. chmod 600 the file. The installer warns if it is readable by other users, and it will not stop you.

On a medium without nix

The ISO ships nix, so --config profile.nix evaluates in place. Anywhere it does not, render the profile first on a machine that has it — the installer says so rather than failing obscurely:

syn nix profile profile.nix > install.conf
syn-install --config install.conf

The key=value form is the same vocabulary, one per line, # for comments:

disk = vda
filesystem = btrfs
want_steam = no

See also: Installation, Commands, Updating.

Clone this wiki locally