How to Install NixOS
Install NixOS from scratch: partition disks, write configuration.nix, pick a channel, run nixos-install, and master the nixos-rebuild workflow for atomic system changes.
Before you start
- ▸A USB drive of at least 2 GB and a way to write the ISO (dd, balenaEtcher, etc.)
- ▸Target machine with at least 40 GB of disk space and 2 GB of RAM
- ▸Wired Ethernet or knowledge of your WiFi credentials for the live environment
- ▸Basic familiarity with partitioning concepts (GPT vs MBR, EFI vs BIOS boot)
NixOS flips the traditional Linux install model on its head. Instead of imperatively running commands to configure your system, you declare the entire machine state in /etc/nixos/configuration.nix and let nixos-rebuild make it real. Every change is atomic and rollbackable. That power comes with a steeper learning curve — this guide gets you through a clean installation to a working, reproducible system.
What You Need Before You Start
Download the NixOS minimal ISO (or the graphical ISO if you want a live desktop to reference) from nixos.org/download. The minimal ISO is smaller and forces you to learn the config early, which pays off. Burn it to a USB drive with dd or a tool like balenaEtcher, then boot your target machine from it.
Partition and Format the Disk
NixOS has no guided partitioner in the minimal ISO. You do this by hand. The example below targets /dev/sda on a UEFI system using a simple two-partition layout (EFI + root). Adjust the device path to match your hardware — check with lsblk first.
lsblk
Create the partition table:
parted /dev/sda -- mklabel gpt
parted /dev/sda -- mkpart ESP fat32 1MiB 512MiB
parted /dev/sda -- set 1 esp on
parted /dev/sda -- mkpart primary 512MiB 100%
Format both partitions:
mkfs.fat -F 32 -n boot /dev/sda1
mkfs.ext4 -L nixos /dev/sda2
If you prefer btrfs or XFS, substitute accordingly — NixOS supports both fully. For a BIOS/MBR system, swap the GPT label for msdos, skip the ESP partition, and create a single root partition with the boot flag.
Mount the Filesystems
NixOS's installer generates your initial config from the currently mounted layout, so mount everything before running nixos-generate-config.
mount /dev/disk/by-label/nixos /mnt
mkdir -p /mnt/boot
mount /dev/disk/by-label/boot /mnt/boot
Generate the Initial Configuration
This command inspects your hardware and mounted filesystems, then writes two files: configuration.nix (system config) and hardware-configuration.nix (auto-detected hardware — treat this as read-only).
nixos-generate-config --root /mnt
ls /mnt/etc/nixos/
# hardware-configuration.nix configuration.nix
Edit configuration.nix
Open the main config with any editor available on the live ISO (nano is always present; vim may need nix-shell -p vim first).
nano /mnt/etc/nixos/configuration.nix
The generated file is heavily commented. Here is a practical baseline to work from — read every option, they are all meaningful:
{ config, pkgs, ... }:
{
imports = [ ./hardware-configuration.nix ];
# Bootloader — systemd-boot for UEFI, GRUB for BIOS
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
# Hostname
networking.hostName = "mymachine";
# Enable NetworkManager for easy WiFi/Ethernet management
networking.networkmanager.enable = true;
# Locale and timezone
time.timeZone = "America/New_York";
i18n.defaultLocale = "en_US.UTF-8";
# Desktop environment (remove if you want headless)
services.xserver.enable = true;
services.xserver.displayManager.gdm.enable = true;
services.desktopManager.gnome.enable = true;
# Enable sound via PipeWire (modern default)
hardware.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
pulse.enable = true;
};
# Define a user account
users.users.alice = {
isNormalUser = true;
extraGroups = [ "wheel" "networkmanager" ];
initialPassword = "changeme";
};
# Allow wheel group to use sudo
security.sudo.wheelNeedsPassword = true;
# System packages available to all users
environment.systemPackages = with pkgs; [
vim
git
wget
curl
htop
];
# OpenSSH — enable if you need remote access
services.openssh.enable = true;
# NixOS release that this config was written for.
# Do NOT change this after the first install.
system.stateVersion = "24.11";
}
Important: The system.stateVersion field is not the version you want to run — it records the NixOS version present when you first installed. Do not bump it on upgrades. It controls stateful data migrations only.
Choosing a Channel
NixOS channels determine which package set you pull from. The two main options are:
- nixos-24.11 (or current stable) — well-tested, recommended for most machines.
- nixos-unstable — rolling, near-latest packages, higher breakage risk.
Check and set the channel from inside the live environment:
nix-channel --list
# nixos https://nixos.org/channels/nixos-24.11
To switch to unstable instead:
nix-channel --add https://nixos.org/channels/nixos-unstable nixos
nix-channel --update
Stick with the stable channel for a first install. You can always switch after booting into the installed system.
Run the Installation
With the config written and the channel set, install the system:
nixos-install
This will download several hundred megabytes to gigabytes of packages depending on your config. At the very end it will prompt you to set a root password — do it. You can disable root login via SSH afterwards in config.
When it finishes without errors:
reboot
Remove the USB drive when the BIOS/UEFI screen appears.
First Boot and Verification
Log in as your user (password is whatever you set in initialPassword — change it immediately with passwd). Then confirm the system is healthy:
systemctl --failed
# Should return: 0 loaded units listed
nixos-version
# Example output: 24.11.20250401.abc1234 (Vicuna)
Making Changes: The nixos-rebuild Workflow
This is the core NixOS loop. Edit /etc/nixos/configuration.nix, then apply:
sudo nixos-rebuild switch
switch builds and activates immediately. If something goes wrong, reboot and select the previous generation from the bootloader menu — every nixos-rebuild switch creates a new boot entry automatically.
To test a config without making it the default boot entry, use:
sudo nixos-rebuild test
To build without activating (verify it compiles cleanly):
sudo nixos-rebuild build
Troubleshooting
nixos-install fails with "out of disk space"
The Nix store is written to /mnt/nix/store. Make sure your root partition has at least 20 GB free. A minimal headless system uses around 4–6 GB; GNOME adds considerably more.
System boots but has no network
Verify networking.networkmanager.enable = true is in your config and your user is in the networkmanager group. Run sudo nixos-rebuild switch after fixing, or check systemctl status NetworkManager.
Wrong bootloader type selected
If you used systemd-boot on a BIOS system (or GRUB on a system that boots in UEFI-only mode), the install will succeed but the machine won't boot. Re-mount from the live ISO, fix the bootloader options in configuration.nix, and re-run nixos-install. No other steps needed — nixos-install is idempotent.
A package is not found
Search the package database before editing config:
nix search nixpkgs firefox
If nix search is unavailable on your channel setup, use search.nixos.org/packages in a browser instead.
Frequently asked questions
- Can I use Flakes instead of channels for a first NixOS install?
- Yes, but Flakes require an extra mental model (flake.nix, flake.lock, the nixos-rebuild --flake flag) and are still marked experimental. Master the channel-based workflow first, then migrate — the concepts transfer directly.
- What happens if I break my configuration and can't boot?
- Every nixos-rebuild switch creates a numbered generation entry in the bootloader. At the GRUB or systemd-boot menu, select an earlier generation, boot into it, fix configuration.nix, and run nixos-rebuild switch again.
- How do I install per-user packages without putting them in configuration.nix?
- Use nix-env or, better, Home Manager. Home Manager lets you declare per-user packages and dotfiles in a separate home.nix file using the same declarative style as the system config.
- Does system.stateVersion need to match my current NixOS channel version?
- No. Set it once at install time and never change it. It only controls how NixOS handles migrations for stateful data (like database formats). Changing it to match the channel version is a common mistake that can corrupt state.
- How large does the root partition need to be?
- 40 GB is a comfortable minimum for a desktop system with a few applications. The Nix store keeps multiple generations of every package; use nix-collect-garbage -d periodically to reclaim space from old generations.
Related guides
How to Back Up Your Linux System
Learn how to back up your Linux system using Timeshift, rsync, Borg, and Restic — then tie it all together with a practical 3-2-1 backup routine.
How to Choose a Linux Distribution
Match a Linux distro to your real needs — desktop, server, rolling vs LTS, hardware quirks, and package ecosystems — without wading through marketing noise.
How to Dual-Boot Linux and Windows
Shrink the Windows partition, install Linux without breaking the bootloader, configure GRUB, and handle Secure Boot — all in the correct order.
10 Things to Do After Installing Linux
Ten essential post-install steps for any Linux desktop: updates, drivers, firewall, codecs, backups, SSH hardening, and service cleanup — all with modern commands.