How to Install NixOS in 2026: The Flakes-First Way (Skip the Legacy Detour)

✅ Tested on NixOS 26.05 "Yarara" (May 2026 release) — flake-based install with disko · Last updated: September 2026
Every guide to installing NixOS starts the same way: boot the ISO, run the graphical or manual partitioner, edit configuration.nix, run nixos-install — then, as an afterthought in "part 2," mentions that flakes exist. That order is backwards for how most of the NixOS community actually works in 2026. This guide installs NixOS the way experienced users actually do it: flakes and declarative partitioning (via disko) from the first command, no legacy detour, plus an honest look at why flakes are still officially "experimental" four years after most people started depending on them.
Don't have spare hardware to test this on? You can run the same setup on a cloud server in minutes — see our comparison of the best Linux VPS hosting providers for 2026. The remote install method further down uses exactly that.
- What NixOS Actually Is (Before You Install It)
- Why This Guide Skips the Classic Installer
- The "Experimental" Paradox — Four Years Later
- Step 1 — Enable Flakes and Boot the ISO
- Step 2 — Partition Declaratively with Disko
- Step 3 — Write Your flake.nix and configuration.nix
- Step 4 — Install and Reboot
- Step 5 — Rebuilds, Updates and Rollbacks
- Installing Remotely on a VPS with nixos-anywhere
- Understanding flake.lock Before It Confuses You
- NixOS vs Arch vs Omarchy
- Troubleshooting Common Questions
- Why does my system feel like it randomly breaks after an update?
- Why is my rebuild taking hours instead of minutes?
- What does "unsupported lock file version" actually mean?
- Do I need Home Manager to use flakes?
- Is it safe to run flakes on a production server, given they're still "experimental"?
- Further Reading
What NixOS Actually Is (Before You Install It)
Skip this section and the rest of the guide will feel like following steps you don't understand. NixOS isn't "Arch with a different package manager" — the entire system is built differently at a structural level:
Traditional distro (Debian, Fedora, Arch) NixOS
──────────────────────────────────────── ────────────────────────────────────────
apt/dnf/pacman installs mutate configuration.nix / flake.nix describes
/usr, /etc, /var directly. the ENTIRE desired system state.
/usr/bin/nginx (one mutable copy, /nix/store/9fb3k2...-nginx-1.27.1/bin/nginx
overwritten on every upgrade) (immutable, content-addressed by hash —
every version that ever existed can
coexist on disk)
"sudo apt upgrade" changes the "nixos-rebuild switch" builds a NEW
running system in place. No easy generation from your config, then
undo if something breaks. atomically flips /run/current-system
to point at it.
Rollback = reinstall, restore a Rollback = pick the previous generation
backup, or hope a snapshot exists. from the bootloader menu, or run
"nixos-rebuild switch --rollback".
The old generation never left disk.Two consequences that matter before you install anything: first, your entire system config is one (or a few) text files — reproducible on another machine by copying them. Second, nothing is ever silently overwritten — old package versions and old system generations pile up in /nix/store until you explicitly garbage-collect them, which is exactly what makes rollback instant instead of theoretical.
Why This Guide Skips the Classic Installer
The official NixOS manual still teaches the classic path first: manual partitioning with parted/fdisk, mounting by hand, nixos-generate-config, editing configuration.nix, nixos-install — with flakes covered separately, as an option for later. That ordering made sense when flakes were brand new. It doesn't reflect how the project actually gets used now: according to nix.dev, more than half of the active user base already works with flakes day to day, and nearly every serious NixOS configuration shared online — for servers, for home-manager dotfiles, for CI — is flake-based.
It's also how newer, less mainstream GUI software ships today: Caelestia Shell, a Quickshell-based shell for Hyprland, is officially packaged only for Arch's AUR and NixOS flakes, there's no traditional Nix channel install for it.
Not every shell in that space stays flakes-only, though: Noctalia is officially packaged for NixOS directly, alongside Arch, Fedora and openSUSE, a sign of how quickly it matured after dropping Quickshell for a native rewrite.
Learning the classic configuration.nix-only workflow first, then having to re-learn flakes on top of it later, is the single biggest reason the official path feels harder than it needs to be. This guide teaches the version you're going to end up using anyway.
| Classic install (manual) | Flake-based install (this guide) |
|---|---|
One configuration.nix, no version pinning of nixpkgs | flake.nix pins the exact nixpkgs commit — reproducible on any machine, any time |
Manual partitioning: parted, mkfs, mount by hand | Partitioning described declaratively in a disko config, applied in one command |
| Config lives only on the one machine, unless you copy it manually | Config is a git repo from day one — same flake deploys to a second machine or a VPS |
nixos-rebuild switch (no --flake flag) | nixos-rebuild switch --flake .#hostname |
| No built-in remote/headless install path | Same flake installs remotely and unattended via nixos-anywhere (see below) |
The "Experimental" Paradox — Four Years Later
Here's the detail almost nothing covers honestly: flakes are still, as of NixOS 26.05, an opt-in experimental feature. You have to explicitly enable them — they're not on by default even on a fresh install. The RFC meant to resolve this, RFC 0136 "Stabilize incrementally", was opened in 2022. As of this guide's last update in 2026, it still hasn't completed its final stabilization phase — four years of "experimental" for a feature the majority of the community depends on daily.
What that means practically, not philosophically: nothing about flakes is unstable in the sense of "likely to break your system." The experimental label is a governance and API-stability caveat — the flake CLI syntax could theoretically still change in a breaking way in a future Nix release, and the core team hasn't committed to backward compatibility the way they have for stable features. For a personal desktop, this is a non-issue. For a server config you plan to maintain for years, it's worth pinning your Nix version alongside your nixpkgs commit, not just assuming the flake syntax itself is frozen forever.
Step 1 — Enable Flakes and Boot the ISO
Download the graphical ISO from nixos.org/download and flash it:
sudo dd if=nixos-*.iso of=/dev/sdX bs=4M status=progress conv=fsyncBoot from the USB. The live ISO doesn't have flakes enabled by default, so every Nix command you run from here needs the flag until you're inside your own config:
# Confirm you're on the live ISO and check your target disk
lsblk
# From here on, every "nix" command in this guide needs this flag
# on the live ISO — your installed system will have it enabled
# permanently via configuration.nix, so this is temporary
nix --extra-experimental-features "nix-command flakes" flake --helpStep 2 — Partition Declaratively with Disko
Instead of parted and mkfs by hand, describe the partition layout once, in Nix, and apply it in a single command. A minimal single-disk, ext4, UEFI layout:
// disko-config.nix
{
disko.devices = {
disk.main = {
device = "/dev/nvme0n1"; # confirm with lsblk — this will erase the disk
type = "disk";
content = {
type = "gpt";
partitions = {
ESP = {
size = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
};
root = {
size = "100%";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
};
};
};
};
};
};
}Apply it — this formats the disk, so double-check the device path first:
sudo nix --extra-experimental-features "nix-command flakes"
run github:nix-community/disko -- --mode disko ./disko-config.nixDisko also supports LUKS encryption, LVM, btrfs subvolumes, ZFS and RAID in the same declarative style — see the disko examples directory for those layouts instead of writing partition schemes from scratch.
Step 3 — Write Your flake.nix and configuration.nix
Generate a starting hardware config (skip filesystems — disko already declared them):
sudo nixos-generate-config --no-filesystems --root /mntCreate /mnt/etc/nixos/flake.nix:
{
description = "My NixOS configuration";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05";
disko.url = "github:nix-community/disko";
disko.inputs.nixpkgs.follows = "nixpkgs";
};
outputs = { self, nixpkgs, disko, ... }: {
nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
disko.nixosModules.disko
./disko-config.nix
./configuration.nix
];
};
};
}In configuration.nix, add the one line the live ISO doesn't have permanently — this is what makes flakes "just work" on every future rebuild without the extra-experimental-features flag:
{ config, pkgs, ... }: {
imports = [ ./hardware-configuration.nix ];
nix.settings.experimental-features = [ "nix-command" "flakes" ];
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
networking.hostName = "myhost";
time.timeZone = "UTC";
users.users.you = {
isNormalUser = true;
extraGroups = [ "wheel" "networkmanager" ];
};
environment.systemPackages = with pkgs; [ vim git curl ];
system.stateVersion = "26.05"; # set once, never change on upgrade
}Step 4 — Install and Reboot
sudo nixos-install --flake /mnt/etc/nixos#myhost
rebootYou'll be prompted to set the root password during install. On first boot, log in as the user you defined and confirm the system came up on the generation you just built:
nixos-rebuild list-generationsStep 5 — Rebuilds, Updates and Rollbacks
Every change to your system from here on follows the same three commands — this is the entire workflow, whether you're adding a package or changing a kernel parameter:
# Edit /etc/nixos/configuration.nix or flake.nix, then:
sudo nixos-rebuild switch --flake /etc/nixos#myhost
# Bump nixpkgs and all flake inputs to their latest commits
nix flake update --flake /etc/nixos
# Roll back instantly to the previous generation if something breaks
sudo nixos-rebuild switch --rollback
# Reclaim disk space from old generations once you're confident
# you won't need to roll back further than your last few builds
sudo nix-collect-garbage --delete-older-than 30dInstalling Remotely on a VPS with nixos-anywhere
The same flake you just wrote can install NixOS on a remote server over SSH, with no NixOS pre-installed and no console access needed — the target machine just needs to support kexec (booting a new kernel from a running Linux system without a reboot), which most VPS providers' rescue/generic Linux images do. This is genuinely the fastest way to get NixOS running on a cloud box: no custom ISO upload, no KVM console fiddling.
# From your local machine, with your flake and disko-config.nix ready:
nix run github:nix-community/nixos-anywhere --
--flake .#myhost root@YOUR_SERVER_IPnixos-anywhere kexecs into a minimal NixOS installer environment on the target, runs your disko config to partition the remote disk, installs your flake's configuration, and reboots into it — typically 5-15 minutes depending on disk speed and how much the closure needs to download. See our comparison of the best Linux VPS hosting providers if you're choosing where to run this — Hetzner and Vultr are common choices in the NixOS community specifically because their rescue images support kexec cleanly.
Understanding flake.lock Before It Confuses You
Alongside flake.nix, every flake generates a flake.lock file — this is what actually pins reproducibility, and it's the source of most of the confusing errors newcomers hit on NixOS Discourse:
- What it does:
flake.nixsays "use nixpkgs from the 26.05 branch" — a moving target.flake.lockrecords the exact commit hash that resolved to, the last time you rannix flake update. Without the lock file, two people building "the same" flake on different days could get different package versions. This is git-tracked and committed like any other file in your config repo. - "Unsupported lock file version" errors: the lock file format itself has a version number, bumped occasionally by the Nix team. This error means the Nix binary you're running is older than the one that generated the lock file — the fix is upgrading your local Nix (
nix upgrade-nixon non-NixOS systems, or just rebuilding on NixOS itself), not editing the lock file by hand. - It regenerates more than people expect: if your flake has "sub-flakes" as inputs (an input that is itself a flake with its own inputs), evaluating your flake can silently update parts of the lock tree without you running
nix flake updateexplicitly. If your rebuild pulls in unexpected package versions, check whetherflake.lockchanged before assuming yourconfiguration.nixis the problem.
NixOS vs Arch vs Omarchy
All three give you full control over the system, but the maintenance model is fundamentally different:
| NixOS | Arch Linux | Omarchy | |
|---|---|---|---|
| Config model | Declarative — whole system described in Nix files | Imperative — you install and configure packages one at a time | Imperative Arch underneath, with a pre-built Hyprland desktop layer |
| Rollback | Instant, atomic, built into the bootloader | None built-in — Timeshift/btrfs snapshots if you set them up yourself | Same as Arch — no atomic rollback |
| Reproducing on a new machine | Copy the flake, rebuild — same system, byte-for-byte package versions | Reinstall and manually reproduce your setup, or script it yourself | Re-run the Omarchy installer |
| Learning curve | Steep — a genuinely different mental model, not just new commands | Moderate — you learn Linux internals directly | Low — opinionated defaults out of the box |
| Best for | Reproducible servers, dev environments, people who value "it can't silently break" | People who want to understand and control every layer by hand | People who want a great Hyprland desktop with minimal setup decisions |
Troubleshooting Common Questions
Why does my system feel like it randomly breaks after an update?
This is the most common real complaint about NixOS in practice — audio, Bluetooth or clipboard tools sometimes stop working after a routine nixos-rebuild switch, and the error output can be dozens of lines long with the actual cause (often something as simple as a package being deprecated or renamed upstream, buried in the middle) easy to miss. Read the full rebuild output rather than the last few lines, or check journalctl -xe for the specific failing unit. Because rollback is instant, the safe move when something breaks is sudo nixos-rebuild switch --rollback first, then debug from a working system rather than fighting the broken one.
Why is my rebuild taking hours instead of minutes?
A correctly configured NixOS pulls pre-built packages from cache.nixos.org instead of compiling from source. Multi-hour rebuilds almost always mean you're building something locally that should have come from the binary cache — commonly because you're on an unfree or very recently updated package with no cached build yet, you've overridden a package's inputs (which invalidates the cached hash), or you're tracking nixpkgs-unstable instead of a stable release branch. Check nix.settings.substituters is still pointing at the default cache before assuming your hardware is the bottleneck.
What does "unsupported lock file version" actually mean?
Your local Nix binary is older than the version that generated the project's flake.lock. Upgrade Nix rather than editing the lock file — see the flake.lock section above.
Do I need Home Manager to use flakes?
No — they're separate, composable tools. Flakes are about pinning and structuring inputs (including the whole NixOS system config). Home Manager is about managing your user-level dotfiles and packages declaratively, independent of system-level config. You can use flakes without ever touching Home Manager, and vice versa on non-NixOS systems.
Is it safe to run flakes on a production server, given they're still "experimental"?
Widely used in production despite the label — the risk isn't stability of your running system, it's that the flake CLI syntax itself isn't guaranteed frozen the way fully stable Nix features are. Pin your Nix version alongside your nixpkgs commit for anything you plan to maintain long-term, and you're taking on materially less risk than the "experimental" tag implies on its own.
Further Reading
- Independent Linux Distros: The Complete List
- NixOS Packages Explained: nix-env, nix profile, and the Nix Store
- Is NixOS Good for Gaming? Steam, Proton and GPU Drivers Guide
- Arch Linux Installation Guide
- How to Install Omarchy on Arch Linux
- Omarchy vs Omakub: Which Should You Choose?
- How to Set Up a VPS on Hetzner
- Best Linux VPS Hosting in 2026
- Linux Disk Encryption with LUKS
