This repository is a flake-based NixOS configuration for my daily machines. It is also meant to be a readable example of how to grow a personal NixOS setup from one machine into a reusable multi-host configuration.
Clone the repository and make /etc/nixos point to it:
git clone https://github.com/RandomLemon/nixos.git
sudo rm -rf /etc/nixos
sudo ln -s "$PWD/nixos" /etc/nixosRebuild one of the configured hosts:
sudo nixos-rebuild switch --flake /etc/nixos#tx
sudo nixos-rebuild switch --flake /etc/nixos#thinkpad
sudo nixos-rebuild switch --flake /etc/nixos#msr1There is also a shell alias named update, defined in
home-manager/zsh.nix, which runs:
sudo nixos-rebuild switchWhen using flakes directly, prefer the explicit --flake /etc/nixos#<host>
form so it is always clear which machine is being rebuilt.
If you are learning NixOS from this repository, read it in this order:
flake.nixto understand inputs, outputs, and host creation.- One host file, such as
hosts/fa401wv/default.nix, to see how a machine is assembled from modules. modules/software/system/main.nixto learn the base system policy.modules/hardware/default.nixand its imported files to learn reusable hardware defaults.hosts/fa401wv/home.nixandhome-manager/to see user-level configuration.home-manager/desktop/niri/to study a complete Wayland desktop config.
The important lesson is separation of responsibility:
flake.nixdecides which machines exist.hosts/decides what each machine imports.modules/contains reusable operating system building blocks.home-manager/contains user applications and dotfiles.- Hardware-generated files stay close to the machine that needs them.
That structure keeps daily use convenient while making the configuration easier to explain, copy, and modify.
.
|-- flake.nix
|-- flake.lock
|-- hosts/
| |-- fa401wv/
| |-- thinkpad/
| `-- msr1/
|-- modules/
| |-- hardware/
| `-- software/
`-- home-manager/
|-- core.nix
|-- applications.nix
|-- zsh.nix
|-- code.nix
`-- desktop/
The main idea is simple:
flake.nix
-> hosts/<machine>/default.nix
-> shared NixOS modules in modules/
-> optional Home Manager profile in hosts/<machine>/home.nix
-> shared user modules in home-manager/
flake.nix is the top-level entry point. It defines:
- Inputs such as
nixpkgs,home-manager,nix-alien, and a CachyOS kernel overlay. - Binary cache settings, including several mirrors.
- A small
mkHosthelper that creates eachnixosSystem. - The user name shared by the hosts:
int16. Change it as you wish. - Home Manager integration.
This is the first file to read if you want to understand how the whole project is assembled.
Host files decide which reusable modules are active on a specific machine.
The flake currently exposes these NixOS configurations:
| Flake name | Host directory | System | Home Manager | Purpose |
|---|---|---|---|---|
tx |
hosts/fa401wv |
x86_64-linux |
Yes | For ASUS FA401WV 2024, with a Ryzen HX 370 and a RTX 4060 |
thinkpad |
hosts/thinkpad |
x86_64-linux |
Yes | Legacy ThinkPad configuration with legacy GRUB boot, based on T430 |
Each host usually contains:
hosts/<machine>/
default.nix # NixOS system entry point
home.nix # Home Manager entry point, when used
hardware-configuration.nix # generated by nixos-generate-config
hardware/ # optional machine-specific hardware modules
Treat
hardware-configuration.nixas generated hardware state. For a new machine, regenerate it withnixos-generate-configinstead of copying another host's file blindly.
For example, hosts/fa401wv/default.nix imports:
- Generated hardware configuration.
- Hardware-specific ASUS laptop modules.
- Shared hardware defaults from
modules/hardware. - Shared system defaults from
modules/software/system/main.nix. - Development tools such as
direnvanddistrobox. - Gaming modules such as Steam and Prism Launcher.
- The
greetdlogin manager and the Niri desktop session.
The tx flake output uses the hosts/fa401wv directory. This is useful to
remember when reading the tree: the flake name is the rebuild target, while the
directory name describes the hardware model.
hosts/thinkpad/default.nix uses the same shared base, but overrides bootloader
settings to use legacy GRUB on /dev/sda.
hosts/msr1/default.nix is more standalone because it targets ARM64 hardware
and builds a custom kernel.
modules/ contains reusable NixOS modules. These affect the whole operating
system.
modules/hardware/
default.nix # imports the common hardware modules
main.nix # bootloader, kernel, firmware, filesystem helpers
network.nix # NetworkManager, timezone, base hostname
input.nix # locale, fonts, fcitx5, keyboard settings
bluetooth.nix # Bluetooth and Blueman
pipewire.nix # PipeWire audio
modules/software/
system/ # base OS policy and common CLI tools
desktop/ # greetd, niri, hyprland, KDE, LXQt
develop/ # direnv, distrobox, docker, mysql
game/ # Steam, Minecraft / Prism Launcher, Waydroid
3rd/ # third-party packages
The most important shared system module is
modules/software/system/main.nix. It enables unfree packages, creates the
normal user, configures Git, enables flakes, configures garbage collection,
sets the default shell to Zsh, installs common tools, and enables services such
as udisks2, Polkit, and GNOME keyring integration.
home-manager/ contains user-level configuration. These modules are imported
from each host's home.nix.
Important files:
core.nixsets the base Home Manager state, user services, dconf values, and desktop preferences.applications.nixinstalls daily graphical applications and declares XDG default applications.zsh.nixconfigures Zsh, Oh My Zsh, shell plugins, and aliases.code.nixinstalls and configures VS Code / Cursor.desktop/niri/contains the active Niri desktop configuration.desktop/hyprland/contains an alternative Hyprland desktop setup.
Home Manager is not used as a standalone command here. It is wired into the
NixOS rebuild through flake.nix.
The current desktop stack is Wayland-first:
greetd / tuigreet
-> niri-session
-> Niri compositor
-> Waybar
-> fuzzel, mako, swaylock, swayidle, xwayland-satellite, wl-clipboard
System-level desktop pieces live in modules/software/desktop/:
greetd.nixconfigures the login manager.niri.nixenables Niri and supporting desktop services.hyprland.nix,kde.nix, andlxqt.nixare alternative desktop modules.
User-level desktop configuration lives under home-manager/desktop/:
desktop/niri/default.nixinstalls the Niri user tools.desktop/niri/*.kdlsplit the Niri configuration into focused files for input, outputs, keybindings, layout, startup commands, and window rules.desktop/waybar/contains the bar configuration.desktop/hyprland/keeps the older Hyprland setup available as a reference or alternate session.
To switch between Niri and Hyprland, change both layers:
- In the host system file, switch the imported desktop module, for example in
hosts/fa401wv/default.nix. - In the host Home Manager file, switch the imported user desktop module, for
example in
hosts/fa401wv/home.nix.
Keeping the system session and the Home Manager desktop files in sync avoids a login session that starts without the matching user tools.
This is the most complete daily-driver configuration.
Notable pieces:
hosts/fa401wv/hardware/default.nixcontains machine-specific tuning such as power management, battery settings, fstrim, and sensors.hosts/fa401wv/hardware/nvidia.nixconfigures AMD + NVIDIA PRIME offload and GPU-related environment.hosts/fa401wv/hardware/asus.nixenables ASUS laptop services.hosts/fa401wv/hardware/custom-dsdt.nixis a custom DSDT experiment for ACPI fixes.- The flake applies the CachyOS LTO Zen4 kernel overlay for this host.
- The host also enables
nix-ld,nix-alien, andwemeet.
The ThinkPad host uses the shared desktop base but has different boot settings:
systemd-boot is disabled and GRUB is installed to /dev/sda.
The MSR1 host targets aarch64-linux and keeps most configuration inside its
own host file because it uses a custom CIX P1 kernel setup. Currently it doesn't work...
Common commands:
# Rebuild the current machine explicitly
update
# update is the alias of `sudo nixos-rebuild switch`
# Update flake inputs
nix flake update /etc/nixos
# Inspect what changed after an update
git diff flake.lock
# Build without switching, useful before risky changes
sudo nixos-rebuild build --flake /etc/nixos#txGarbage collection and store optimisation are configured in
modules/software/system/main.nix:
- Automatic GC runs weekly.
- Generations older than 14 days are deleted.
- Nix store optimisation is enabled automatically.
To use this repository as a template for a new machine:
-
Create a new host directory:
mkdir -p hosts/my-machine
-
Generate hardware configuration on the target machine:
sudo nixos-generate-config --dir /etc/nixos/hosts/my-machine
-
Create
hosts/my-machine/default.nixand import the shared modules you need:{ config, pkgs, lib, username, ... }: { imports = [ ./hardware-configuration.nix ../../modules/hardware ../../modules/software/system/main.nix ../../modules/software/develop/direnv.nix ../../modules/software/desktop/greetd.nix ../../modules/software/desktop/niri.nix ]; networking.hostName = "my-machine"; }
-
Optionally create
hosts/my-machine/home.nix:{ pkgs, lib, username, ... }: { imports = [ ../../home-manager/core.nix ../../home-manager/applications.nix ../../home-manager/zsh.nix ../../home-manager/code.nix ../../home-manager/desktop/niri ]; }
-
Add the host to
nixosConfigurationsinflake.nix:my-machine = mkHost { system = "x86_64-linux"; hostModule = ./hosts/my-machine; homeModule = ./hosts/my-machine/home.nix; };
-
Build or switch:
sudo nixos-rebuild build --flake /etc/nixos#my-machine sudo nixos-rebuild switch --flake /etc/nixos#my-machine