Skip to content

SlashyOS

A personal, multi-host NixOS configuration spanning an AMD desktop and a Framework laptop. It's built with flake-parts and import-tree, so every .nix file under modules/ is auto-imported — no manual wiring, just drop a file in and it's part of the flake.

Both machines run niri (a scrollable-tiling Wayland compositor) with the Noctalia shell, both wrapped declaratively via nix-wrapper-modules instead of imperative dotfiles, and are themed system-wide by Stylix — from the boot splash to the TTY to every app.

Shared configuration is written once: a slashyos base bundle pulls in everything common (system and home-manager level), and each host adds only its hardware, bootloader, and a handful of per-host values. Adding an app to both machines is a one-line change.

Repository

Source lives at Gitlab · NixOS 26.05 · 2 hosts

Flake structure

SlashyOS/
├── flake.nix                     # inputs + flake-parts entrypoint
├── modules/
│   ├── parts.nix                 # systems, `flake.variables` option, nix fmt formatter
│   ├── devshells/
│   │   └── devshells.nix         # `devShells` outputs (python, frontendServer)
│   ├── features/                 # reusable modules, grouped by concern
│   │   ├── appearance/           # stylix, sddm, plymouth, fastfetch
│   │   ├── desktop/              # niri, noctalia (+ noctalia.json)
│   │   ├── system/               # base bundle, common, common-home, shell, nvf, yazi, ntfy, virtualisation
│   │   ├── pallidus/             # host-exclusive: lanzaboote, sunshine
│   │   └── theseus/              # host-exclusive: grub
│   └── hosts/
│       ├── pallidus/             # 🖥️ AMD desktop
│       │   ├── default.nix       # nixosSystem definition
│       │   ├── pallidus.nix      # host config: imports + hostname + bootloader
│       │   ├── hardware.nix      # generated hardware scan
│       │   ├── desktop-hardware.nix
│       │   ├── home.nix          # host-only home-manager extras
│       │   └── variables.nix     # this host's values
│       └── theseus/              # 💻 Framework AMD laptop
│           ├── default.nix
│           ├── theseus.nix
│           ├── hardware.nix
│           ├── laptop-hardware.nix
│           ├── home.nix
│           └── variables.nix
└── config/
    ├── Wallpapers/               # wallpaper collection (+ greyscale/)
    └── fastfetch/image/          # fastfetch logos

Anything under modules/ is auto-imported regardless of subfolder — the folders are purely for humans. A module only becomes active on a host when that host's config imports it by name.

Module layers

Deduplication works in three layers:

Layer Module Contains
Base bundle slashyos (features/system/default.nix) Imports everything every machine gets: common, commonHome, niri, sddm, stylix, shell, fastfetch, plymouth, ntfy, nvf, yazi, virtualisation
Shared system common NixOS-level config both hosts share: nix settings, locale, pipewire, portals, Steam, users, firewall, …
Shared home commonHome Home-manager config both hosts share: user dirs, packages, kitty, VSCodium, git, btop, mangohud

A host file then reads as "the OS, plus this hardware, plus this bootloader":

# modules/hosts/theseus/theseus.nix
imports = [
  self.nixosModules.slashyos
  self.nixosModules.theseusHome
  self.nixosModules.theseusHardware
  self.nixosModules.laptopHardware
  self.nixosModules.grub
];

Where does a change go?

  • App / setting for both machinescommon.nix (system) or common-home.nix (user)
  • App for one machine → that host's home.nix
  • New feature for both → new file under features/, add one line to the slashyos bundle
  • New machine → copy the closest host folder (~5 short files) — see Usage

Tags

Tag Meaning
🟢 Enabled / active
🛠️ Declaratively wrapped via nix-wrapper-modules
🔐 Security-related (Secure Boot, etc.)
🖥️ Desktop-only (pallidus)
💻 Laptop-only (theseus)

Hosts

Host Platform Machine Bootloader Keyboard Notes
pallidus x86_64-linux 🖥️ AMD desktop systemd-boot + 🔐 Lanzaboote gb,fr Dual-boots Windows 11
theseus x86_64-linux 💻 Framework AMD (AI 300) GRUB us,fr Tuned via nixos-hardware, zram, power-profiles-daemon

Each host is a separate entry in flake.nixosConfigurations. You build the one matching the machine — see Usage.

Per-host variables

Values that differ between machines (hostname, wallpaper, login background, fastfetch logo, username, keyboard layout) live in each host's variables.nix under flake.variables.<host>:

# modules/hosts/theseus/variables.nix
flake.variables.theseus = {
  username = "dias";
  hostname = "theseus";
  kbLayout = "us,fr";
  wallpaper = "${self}/config/Wallpapers/japan.png";
  # ...
};

The flake.variables output is declared as an option in parts.nix, which is what lets each host contribute its own set without collisions. Shared modules that need a host-specific value look it up by the machine's hostname:

image = self.variables.${config.networking.hostName}.wallpaper;

So a single stylix.nix themes both hosts, each with its own wallpaper. To add a value, add the key to every host's variables.nix.

Desktop environment

niri

  • 🟢🛠️ Scrollable-tiling Wayland compositor, wrapped declaratively (programs.niri + wrapper-modules).
  • phinger-cursors-dark cursor theme, size 32, throughout the stack.
  • Rounded window corners (12px), blur, 8px gaps, focus ring in Stylix accent colors.
  • Keyboard layout is per-host, Alt+Shift to toggle.
  • 💻 The Framework's built-in panel (eDP-1) runs at fractional scale 1.2; Electron apps go native Wayland (NIXOS_OZONE_WL) so they stay crisp, and Steam's UI is scaled to match.

Keybinds (shared across hosts; Mod = Super)

Bind Action
Super+Shift+Enter Toggle Noctalia launcher
Super+Enter Open kitty
Super+D Open vesktop (Discord)
Super+T Open thunar
Super+W Open brave
Super+Shift+B Open emote (emoji picker)
Super+Ctrl+S / Super+Shift+S Screenshot full / region → clipboard
Super+Q Close window
Super+Shift+E Quit niri
Super+Shift+Esc Show hotkey overlay
Super+Tab Toggle overview

Noctalia

  • 🟢🛠️ Shell / bar / launcher for niri, wrapped as a package and toggled via niri keybinds (launcher, settings, wallpaper, session menu). Themed via noctalia.json.

Theming (Stylix)

  • 🟢 Stylix drives system-wide theming — colors, fonts, and icons — from each host's wallpaper (polarity = "dark").
  • Covers everything: apps, btop, the Plymouth boot splash, and the TTY console, so the whole boot-to-desktop journey shares one palette per host.
  • Papirus icon theme (dark), 80% terminal/application opacity.

Boot & security

Shared

  • 🟢 Plymouth — Stylix-generated boot splash (wallpaper-derived background, logo, spinner) with silent boot: quiet kernel params, hidden initrd logs.
  • 🟢 SDDM — Wayland session via the kwin compositor, sddm-astronaut-theme (left-aligned form, per-host greyscale background, Electroharmonix font).

pallidus 🖥️

  • 🟢🔐 Lanzaboote — Secure Boot with a signed kernel/bootloader; sbctl included for key management (keys live on the machine, not in the repo).
  • systemd-boot, 5 generations kept, EFI variables writable, dedicated Windows 11 boot entry.

theseus 💻

  • 🟢 GRUB (EFI, device = nodev) with the grub-of-tsushima theme; Stylix's GRUB target disabled so the theme applies.

Shell & CLI

  • fish — default shell, fastfetch greeting.
  • starship — prompt, with username/hostname disabled.
  • nh — pretty nixos-rebuild wrapper, pointed at the repo, with weekly auto-clean (see Maintenance).
  • direnv + nix-direnv — per-project dev shells that auto-activate on cd.
  • comma, anything runs a nixpkgs program without installing it.
  • fastfetch — custom system-info fetch with a per-host logo (kitty-direct).
  • nvf — declaratively configured Neovim. yazi — terminal file manager.
  • ntfy — a user service subscribes to ntfy and relays to desktop notifications (reads ~/.config/ntfy/client.yml, deliberately unmanaged so credentials stay out of the repo).

Aliases

Alias Expands to
fr nh os switch
fu nix flake update (on this flake)

Formatting — the flake exposes nixfmt-tree as its formatter; nix fmt from the repo root formats the whole tree.

Dev shells

Defined in modules/devshells/devshells.nix as flake outputs, pinned to the same nixpkgs as the system:

Shell Provides
python Python 3 with numpy, pandas, matplotlib, pillow, jupyter, pytest, pip/setuptools/wheel
frontendServer Node.js 24
# one-off
nix develop ~/SlashyOS#python

# per project — auto-activates on cd, and creates a GC root
echo "use flake ~/SlashyOS#python" > .envrc && direnv allow

Maintenance

Garbage collection is automated without ever nuking dev shells:

  • nh clean runs weekly: keeps the last 5 generations and anything newer than 3 days, and runs with --no-gcroots so direnv's dev-shell roots are never removed.
  • nix.settings sets keep-outputs + keep-derivations, so build-time dependencies of rooted shells survive GC — nothing gets re-downloaded after a clean.
  • auto-optimise-store hardlinks duplicate store files to claw disk back.
  • The nix-community cache is added as an extra substituter (covers lanzaboote and friends).

Applications

Shared apps live in commonHome; host-only extras in that host's home.nix (pallidus adds r2modman and pandora-launcher).

App Purpose
Brave Browser
Thunar File manager
VSCodium Code editor (curated extension set)
Vesktop Discord client
Element Matrix client
Proton Pass Password manager
Proton Mail Email client
Wootility Wooting keyboard configurator
kitty Terminal (custom config, fade tab bar)
Emote Emoji picker (Super+Shift+B)
VLC · imv Media / image viewing
LocalSend LAN file sharing (firewall ports opened)

Plus: btop (Stylix-themed via home-manager), micro, git, Steam (Gamescope session, Proton-GE, GameMode), MangoHud.

Wallpapers

The wallpaper collection lives in config/Wallpapers/, including a greyscale/ subset — one of which (ship-greyscale.jpg) is used as the SDDM login background. Each host picks its own desktop wallpaper in its variables.nix, and Stylix derives the whole color scheme from it — desktop, apps, boot splash, and console alike.

Usage

Each machine builds its own host. From the repo root:

# On the machine itself — hostname is inferred:
fr                    # == nh os switch  (builds the host matching this machine)

# Or be explicit about which host:
sudo nixos-rebuild switch --flake .#pallidus
sudo nixos-rebuild switch --flake .#theseus

# Update flake inputs:
fu                    # == nix flake update (on this flake)

# Format the tree:
nix fmt

Build without switching (safe eval/compile check, e.g. testing the laptop's config from the desktop):

nixos-rebuild build --flake .#theseus     # drops ./result, changes nothing

Adding a new host

To add a machine (e.g. orion): copy the closest existing host folder (pallidus for a desktop, theseus for a laptop), rename its per-host module attributes (<old>Configuration/Home/Hardware<new>…), set flake.variables.<new>, drop in the machine's real hardware.nix, git add the new files, then sudo nixos-rebuild switch --flake .#<new> on that machine. Thanks to the slashyos bundle, the new host file is ~20 lines.

Inputs & credits

Input Used for
nixpkgs (nixos-26.05) Package set
flake-parts Modular flake composition
import-tree Auto-import of modules/
nix-wrapper-modules Declarative niri & Noctalia wrapping
nixos-hardware Framework laptop tuning (theseus)
lanzaboote Secure Boot (pallidus)
stylix (release-26.05) System-wide theming
home-manager (release-26.05) User-level config
nvf Declarative Neovim