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 machines →
common.nix(system) orcommon-home.nix(user) - App for one machine → that host's
home.nix - New feature for both → new file under
features/, add one line to theslashyosbundle - 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:
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-darkcursor 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 scale1.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
kwincompositor,sddm-astronaut-theme(left-aligned form, per-host greyscale background,Electroharmonixfont).
pallidus 🖥️
- 🟢🔐 Lanzaboote — Secure Boot with a signed kernel/bootloader;
sbctlincluded 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 thegrub-of-tsushimatheme; 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-rebuildwrapper, pointed at the repo, with weekly auto-clean (see Maintenance). - direnv + nix-direnv — per-project dev shells that auto-activate on
cd. - comma —
, anythingruns 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 cleanruns weekly: keeps the last 5 generations and anything newer than 3 days, and runs with--no-gcrootsso direnv's dev-shell roots are never removed.nix.settingssetskeep-outputs+keep-derivations, so build-time dependencies of rooted shells survive GC — nothing gets re-downloaded after a clean.auto-optimise-storehardlinks 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):
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 |