Get Started

From a fresh clone to a running system. Every command and option on this page is checked against the repository — if it is written here, it exists.

Just want to look? Jump to Try it in a VM first — it boots a full desktop without touching your machine.

Prerequisites

This template tracks NixOS 26.05 (stable), so nearly everything comes from the binary cache rather than being compiled locally.


  1. Clone and enter the dev shell

    git clone https://github.com/olafkfreund/nixos-template.git
    cd nixos-template
    nix develop
    

    The shell provides just, nixfmt, nixd (Nix LSP), statix, deadnix, treefmt, shellcheck, shfmt, pre-commit, nh, plus pciutils/lshw for hardware detection.

    Running just with no arguments opens an interactive menu over every recipe.

  2. Pick a starting point

    Template Use case
    hosts/desktop-template Workstation, full Home Manager profiles
    hosts/laptop-template Desktop plus power management and TLP
    hosts/server-template Headless, SSH-hardened, server profile
    hosts/wsl2-template NixOS inside Windows Subsystem for Linux 2
    hosts/darwin-desktop macOS workstation via nix-darwin
    hosts/darwin-laptop macOS laptop via nix-darwin
    hosts/darwin-server macOS server via nix-darwin
    cp -r hosts/desktop-template hosts/my-machine
    
  3. Generate your hardware configuration

    Run this on the machine you are configuring — it describes that machine’s disks, filesystems and kernel modules, so it is never copied between hosts.

    sudo nixos-generate-config --show-hardware-config \
      > hosts/my-machine/hardware-configuration.nix
    
  4. Customise the host

    Edit hosts/my-machine/configuration.nix:

    networking.hostName = "my-machine";
    
    # GPU support. autoDetect is on by default and enables the right
    # vendor module for you; set the profile to match your workload.
    modules.hardware.gpu = {
      autoDetect = true;
      profile = "desktop";        # desktop | gaming | ai-compute | server-compute
    };
    
    environment.systemPackages = with pkgs; [ vim ];
    

    To pin a vendor explicitly instead of relying on detection:

    modules.hardware.gpu.nvidia = {
      enable = true;
      driver = "production";      # stable | beta | production
    };                            # legacy_470 | legacy_390 | open
    

    Then edit hosts/my-machine/home.nix to choose Home Manager profiles:

    imports = [
      ../../home/profiles/base.nix        # git, shell, core CLI tools
      ../../home/profiles/desktop.nix     # GUI applications
      ../../home/profiles/development.nix # languages and dev tooling
    ];
    

    See GPU-CONFIGURATION for the full set of GPU options.

  5. Register the host in flake.nix

    Open flake.nix and find the ADD YOUR OWN HOSTS HERE block inside nixosConfigurations. Uncomment an entry and edit it:

    my-machine = flakeUtils.mkSystem {
      hostname = "my-machine";     # must match the hosts/ directory name
      profile = "workstation";     # workstation | server | laptop
    };                             # gaming | development | minimal
    
    Why mkSystem? It imports your configuration.nix and wires in Home Manager, agenix and the flake metadata module — so you never repeat that boilerplate. There is one builder; the machine type is a parameter. See HOST-TEMPLATES.
  6. Check before you switch

    nix flake check     # evaluates every host and runs the lint gates
    

    Then dry-run your specific host to see exactly what would be built:

    nix build .#nixosConfigurations.my-machine.config.system.build.toplevel --dry-run
    
  7. Build and activate

    just test my-machine     # activate now, no bootloader entry — safest first try
    just switch my-machine   # activate and make it the default boot entry
    

    just test is the one to reach for first: if something is wrong, reboot and you are back where you started.


Try it in a VM first

No install, no risk — this boots a complete desktop host in QEMU:

nix build .#nixosConfigurations.desktop-test.config.system.build.vm
./result/bin/run-desktop-test-vm
# login: vm-user / nixos

Any host can be built this way; swap desktop-test for test-server, test-gaming, or your own host name.


Everyday commands

Run just on its own for the interactive menu, or call recipes directly:

Command What it does
just switch [host] Build and activate, and set as default boot entry
just test [host] Activate without adding a boot entry
just build [host] Build only, do not activate
just boot [host] Stage for next boot without switching now
just update Update all flake inputs
just update-switch [host] Update inputs, then switch
just check nix flake check
just fmt Format Nix, shell, Markdown, YAML and JSON via treefmt
just lint statix check
just validate check → lint → format-check → dead-code
just test-vm [host] Build and boot a host as a QEMU VM
just list-vms Show the VM configurations available
just build-wsl2-archive Build a WSL2 import tarball
just setup-secrets Initialise agenix secret management
just edit-secret SECRET Create or edit an encrypted secret
just list-secrets List age-encrypted secrets
just rekey-secrets Re-encrypt after adding a new age key

just list prints all ~100 recipes without the menu UI.


Keeping it green

just validate

This runs nix flake check, statix, the formatting check and deadnix. All of them pass on a clean clone, and CI enforces the same set — so if validate is green locally, your pull request will be too.


Where to go next