NixOS
Declarative, reproducible, and fundamentally different.
Overview
| Based on | Independent |
| Package manager | Nix |
| Package format | Nix expressions (functional language) |
| Release model | Stable (every 6 months) + Unstable (rolling) |
| Default DE | None (you declare it in config) |
| Init system | systemd |
| Website | nixos.org |
Why NixOS?
- Declarative configuration - Your entire system is defined in one file. Rebuild it identically on any machine.
- Atomic upgrades and rollbacks - Updates either fully succeed or don't happen at all. Roll back to any previous state from the bootloader.
- Reproducible builds - Same inputs always produce the same outputs. Eliminates "works on my machine."
- 80,000+ packages - Nixpkgs is one of the largest and most up-to-date package repositories
- Dev environments -
nix developandnix shellcreate isolated, reproducible development environments - No dependency conflicts - Every package version is stored in its own path in
/nix/store/
How NixOS Works
Unlike traditional distros where you install packages imperatively, NixOS is configured declaratively. You edit /etc/nixos/configuration.nix to describe what your system should look like, then rebuild.
Example configuration.nix
{ config, pkgs, ... }:
{
# Bootloader
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
# Networking
networking.hostName = "my-nixos";
networking.networkmanager.enable = true;
# Timezone and locale
time.timeZone = "America/New_York";
i18n.defaultLocale = "en_US.UTF-8";
# Desktop environment
services.xserver.enable = true;
services.xserver.displayManager.gdm.enable = true;
services.xserver.desktopManager.gnome.enable = true;
# Audio
services.pipewire = {
enable = true;
alsa.enable = true;
pulse.enable = true;
};
# Users
users.users.myuser = {
isNormalUser = true;
extraGroups = [ "wheel" "networkmanager" "docker" ];
};
# System packages
environment.systemPackages = with pkgs; [
vim
neovim
git
curl
wget
firefox
htop
tmux
];
# Enable Docker
virtualisation.docker.enable = true;
# Enable SSH
services.openssh.enable = true;
# Firewall
networking.firewall.enable = true;
networking.firewall.allowedTCPPorts = [ 22 80 443 ];
system.stateVersion = "24.05";
}
Applying changes
# Edit your configuration
sudo nano /etc/nixos/configuration.nix
# Rebuild and switch to new configuration
sudo nixos-rebuild switch
# Rebuild but don't switch yet (test first)
sudo nixos-rebuild test
# Build and add to bootloader without switching
sudo nixos-rebuild boot
# Roll back to previous generation
sudo nixos-rebuild switch --rollback
# List all generations
nix-env --list-generations --profile /nix/var/nix/profiles/system
Nix Package Manager Commands
# Search for a package
nix search nixpkgs firefox
# Run a package without installing
nix run nixpkgs#cowsay -- "Hello"
# Open a shell with temporary packages
nix shell nixpkgs#python3 nixpkgs#nodejs
# Create a development environment (from a flake)
nix develop
# Garbage collect old generations
sudo nix-collect-garbage -d
# Optimize the Nix store
sudo nix store optimise
Flakes (Modern Nix)
Flakes are the modern way to manage Nix projects. They provide reproducible, hermetic builds with a lock file.
# Enable flakes (add to configuration.nix)
nix.settings.experimental-features = [ "nix-command" "flakes" ];
# Initialize a flake in a project
nix flake init
# A flake.nix for a dev environment:
{
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
outputs = { self, nixpkgs }: {
devShells.x86_64-linux.default =
nixpkgs.legacyPackages.x86_64-linux.mkShell {
packages = with nixpkgs.legacyPackages.x86_64-linux; [
nodejs
python3
postgresql
];
};
};
}
# Enter the dev environment
nix develop
Home Manager
Home Manager lets you declaratively manage your user environment (dotfiles, user packages, shell config) with the same Nix approach.
# In your Home Manager config:
programs.git = {
enable = true;
userName = "Your Name";
userEmail = "your@email.com";
};
programs.neovim = {
enable = true;
defaultEditor = true;
};
programs.zsh = {
enable = true;
shellAliases = {
ll = "ls -la";
update = "sudo nixos-rebuild switch";
};
};
Tips
- Start with the NixOS manual and the Nix Pills tutorial series
- Use nixos-unstable channel if you want the latest packages
- Learn Flakes from the start - they're the future of Nix
- Use Home Manager to manage your dotfiles declaratively
- The learning curve is steep, but the payoff is enormous for reproducibility
- You can use Nix without NixOS - install the package manager on Ubuntu, Fedora, macOS, etc.
- Join the NixOS Discourse and Matrix channels - the community is helpful