# NixOS Configs Reproducible multi-host NixOS + Hyprland ("Silicon Volt") configuration. ## Install (new machine) ```bash # Setup disks nix run --experimental-features "nix-common flakes" github:nix-community/disko -- --mode disko --flake .#hades # install configs nixos-install --flake .#hades # set password nixos-enter --root /mnt -- passwd anish ``` ## Rebuild (existing machine) ```bash rebuild switch # zsh helper: sudo nixos-rebuild switch --flake ~/NixOS-Configs# ``` ## Adding a new host (e.g. a laptop) 1. Create `hosts//` with `default.nix`, `hardware-configuration.nix`, and (optionally) `disko.nix`. Shared modules (`modules/core`, `modules/graphical`, `modules/apps`) are already pulled in by `commonModules` in `flake.nix` — the host only adds its own hardware/disko config. 2. Register it in `flake.nix` under `nixosConfigurations`. 3. Turn optional features on per machine via the shared `my.*` options: ```nix # hosts//default.nix my = { username = "anish"; # default; change for a different primary user gaming.enable = false; # Steam, Gamemode, MangoHud ai.local.enable = false; # Ollama, ComfyUI, Open WebUI pi.enable = false; # pi coding agent (home-manager) }; ``` 4. Declare host-specific displays in `hosts//default.nix`: ```nix home-manager.users.anish.hypr.monitors = [ { output = "eDP-1"; # or "desc:" mode = "2880x1800@120Hz"; # or "preferred" position = "auto"; scale = 2; vrr = null; # optional per-monitor VRR } { output = ""; mode = "preferred"; position = "auto"; scale = "auto"; } # fallback ]; ``` The `hypr.monitors` default (any output @ preferred) keeps every machine working out of the box; hosts override only what they need. Hosts without an NVIDIA GPU simply don't import `modules/hardware/nvidia.nix` — all vendor env vars live there, while the vendor-neutral `hardware.graphics` stack lives in `modules/graphical`. ## Feature toggles (`my.*`) Optional app modules are always imported (via `modules/apps/default.nix`) but only activate when a host sets the corresponding flag, so hosts never need to edit import lists: | Option | Enables | | --- | --- | | `my.username` | Primary user (users, home-manager, getty autologin) | | `my.flakeDir` | Checkout path used by the `rebuild` helper and `zshconf`/`hyprconf` aliases | | `my.gaming.enable` | Steam, Gamemode, MangoHud | | `my.ai.local.enable` | Ollama (CUDA), ComfyUI, Open WebUI | | `my.pi.enable` | pi coding agent (home-manager) | Hardware modules remain explicit imports per host (e.g. `modules/hardware/nvidia.nix`). ## Theming The Silicon Volt palette lives in one place, `home/theme.nix`, and is passed to every home-manager module through `extraSpecialArgs`. Tools that only accept a raw config file (starship, rofi, the herdr picker) carry `@color@` placeholders that are substituted from the same palette at build time, so changing an accent means editing one file. ## Editing configs: live vs generated Most configs are generated from Nix and symlinked read-only from the store, so they need a `rebuild switch` to change: - `foot.ini`, `hyprlock.conf`, `hypridle.conf`, `mako/config`, `starship.toml`, `rofi/config.rasi`, `.zshenv`/`.zshrc` (Nix attrs, themed) Three configs are instead symlinked **straight from the repo** with `mkOutOfStoreSymlink`, so edits apply without a rebuild: | Live file | Applies on | | --- | --- | | `home/hypr/hyprland.lua` | `hyprctl reload` | | `home/hypr/quickshell/**` | quickshell restart | | `home/nvim/config/**` (incl. `lazy-lock.json`) | next nvim start; `:Lazy update` writes here | Because `hyprland.lua` is live, the palette and per-host monitors are emitted as generated fragments, `~/.config/hypr/theme.lua` and `~/.config/hypr/monitors.lua`, which the live file loads with `dofile`. Edit the Lua directly for anything else. The tradeoff: live files are not part of the Nix closure, so the repo must exist at `my.flakeDir` for the symlinks to resolve, and uncommitted edits can drift from git. Keep them committed like any other tracked file.