Nixfiles – Custom NixOS & Desktop Environment
Eine maßgeschneiderte NixOS-Konfiguration mit einem selbst entwickelten Desktop-Interface basierend auf Niri und Quickshell.

Case Study
1. Einleitung und Motivation
Dieses Projekt ist weit mehr als eine Sammlung von Konfigurationsdateien ("Dotfiles"). Es repräsentiert die Entwicklung einer vollständig maßgeschneiderten Desktop-Umgebung auf Basis von NixOS. Nachdem ich jahrelang GNOME genutzt hatte, wollte ich ein System, das sich exakt meinen Arbeitsabläufen anpasst, statt mich einzuschränken. Die Lösung war der Wechsel auf Niri (einem Scrollable Tiling Window Manager) kombiniert mit einer selbst geschriebenen Shell-Oberfläche in Quickshell. Das Herzstück ist die Automatisierungsebene, die es erlaubt, komplexe Software-Stacks deklarativ und konfliktfrei zu verwalten.
2. Problemstellung und Ziele
Problem: Herkömmliche Desktop-Umgebungen (DEs) sind oft unflexibel. Tiling Window Manager (WMs) bieten zwar Effizienz, es fehlt ihnen aber oft an Ästhetik und modernen UI-Funktionen. Zudem neigen große Konfigurationen dazu, unübersichtlich zu werden ("Spaghetti-Code").
Ziele:
- Totale Kontrolle: Jeder Pixel des Desktops und jede Systemkomponente soll kontrollierbar sein.
- Moderne Ästhetik: Flüssige Animationen und ein einheitliches Design-System (Material You inspiriert).
- Abstrakte Automatisierung: Neue Features sollen durch bloßes Hinzufügen von Dateien erkannt und integriert werden.
- Reproduzierbarkeit: Das gesamte System muss auf jedem Rechner (Laptop "jello" oder Workstation "yorke") identisch funktionieren.
3. Systemarchitektur und Design
Architekturüberblick: Das System folgt einem modularen "Feature-First"-Ansatz. Die Logik der Fensterverwaltung (Niri) ist strikt von der optischen Repräsentation (Quickshell) getrennt.
Das Herzstück: lib/helper.nix
Die gesamte Systemerstellung wird durch eine leistungsstarke Funktionsbibliothek gesteuert. Statt Module manuell zu importieren, nutzt der Helper dynamisches Verzeichnis-Scanning:
- Automatisches Discovery: Alle Unterordner in
features/werden gescannt. Findet der Helper einedefault.nix, wird sie automatisch als NixOS-Modul eingebunden. - Zweistufiges Metadaten-Loading: In einer ersten Phase werden nur
metadata.nix-Dateien gelesen, um Abhängigkeiten zu prüfen, bevor der eigentliche Build startet. - Auto-Enablement: Features können andere Features anfordern (z.B. benötigt
desktop.niriautomatischsystem.wayland).
Technologie-Stack:
- Niri: Ein Wayland-Compositor, der Fenster in einer unendlichen horizontalen Rolle anordnet.
- Quickshell (QML/JS): Ermöglicht hardwarebeschleunigte UIs mit Qt Quick.
- Home Manager: Tief in den System-Build integriert für nahtlose User-Config (Nixcord, Nixvim).
4. Implementierungshighlights
Intelligentes Dependency-Management:
Innerhalb der lib/helper.nix wurde ein rekursiver Resolver implementiert. Dieser stellt sicher, dass:
- Alle benötigten Abhängigkeiten eines Features automatisch aktiviert werden.
- Konflikte (z.B. zwei verschiedene Bootloader) bereits zur Evaluierungszeit erkannt und mit einer klaren Fehlermeldung abgebrochen werden.
- Die Hardware-spezifischen Unterschiede (AMD vs. Intel) über ein sauberes Metadaten-Mapping in den
hosts/-Ordnern abstrahiert werden.
Custom Desktop Shell: Die Shell wurde von Grund auf in QML entwickelt. Sie kommuniziert via IPC mit System-Services:
- Audio & Brightness: Eigene OSDs (On-Screen-Displays), die auf Hardware-Events reagieren.
- App-Launcher: Ein performanter, Tastatur-gesteuerter Launcher mit integrierter Suche.
- State Manager: Ein zentrales QML-Objekt, das den Status aller Systemkomponenten verwaltet und an die UI-Komponenten verteilt.
5. Ergebnisse und Ausblick
Erreichte Ziele:
Mein System ist nun vollständig deklarativ. Ich kann eine neue Hardware mit einem einzigen Befehl (nixos-rebuild switch --flake .#hostname) in meinen exakten Desktop-Zustand versetzen. Die Trennung von Logik und UI in Niri/Quickshell sorgt für eine unerreichte Stabilität und Flexibilität.
Nächste Schritte:
- Dynamic Theming: Automatische Farbanpassung des gesamten Systems (inkl. QML-Shell und Terminal) basierend auf dem gewählten Wallpaper.
- Global Search: Erweiterung des Launchers um Datei-Inhaltssuche und Taschenrechner-Funktionen direkt im QML-Interface.
6. Persönliches Wachstum und Lessons Learned
Funktionale Programmierung in Nix:
Die Entwicklung der helper.nix war eine tiefgreifende Übung in funktionaler Programmierung. Patterns wie Lazy Evaluation, Recursion über Attribut-Sets und das Handling von String-Contexts waren essenziell, um die Performance bei wachsender Modulanzahl hochzuhalten.
Linux Desktop Engineering: Der Verzicht auf fertige Lösungen (GNOME/KDE) zwang mich dazu, die zugrunde liegenden Protokolle (Wayland, D-Bus, Pipewire) im Detail zu verstehen. Die Erkenntnis, wie man System-Events in eine reaktive UI übersetzt, hat meine Herangehensweise an Software-Architektur nachhaltig verändert.