Nix flakes

As of 2021-06-30, the version used for this note is at v2.3 so it needs to be invoked with the unstable version.

What are Nix flakes?

A self-contained Nix module that takes inputs (can be from other flakes) and create outputs. It is comparable to Guix channels (or the NUR) in the way any arbitrary value can be exported, thus extending a Nix module in any direction the author can make it to. Also, it supercedes Nix channels as a way to manage your system.

So, why use flakes?

Exploring a Nix flake

To get started with a flake, you can quickly create one with nix flake init. This will create flake.nix which is also required for Nix to recognize the project as a flake.

Here's the skeleton of a flake.

{
  description = "A basic flake.";
  inputs = {};
  outputs = {};
}

It is really just an attribute set that mainly deals with three attributes:

Here's a real example of a basic flake.

{
  description = "A basic flake with some real inputs this time.";
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs";

    home-manager.url = "github:nix-community/home-manager";
    home-manager.inputs.nixpkgs.follows = "nixpkgs";
  };
  outputs = attrs@{ self, nixpkgs, home-manager, ... }: {
    homeManagerConfiguration = import ./hmUsers;
    packages.x86_64-linux = {
      hello = nixpkgs.pkgs.hello;
    };
  };
}

The flake requires other flakes from the nixpkgs and home-manager as indicated from the URL. This will get the latest revision of both inputs.

This is not ideal as it will get the latest revisions every time it requests the inputs. While you can pin the version by adding more information (e.g., nixpkgs.url = "github:NixOS/nixpkgs/nixos-21.11", home-manager.url = "github:nix-community/home-manager/781d25b315def05cd7ede3765226c54216f0b1fe"), this isn't really necessary for the most part as we have lockfiles to secure our dependencies version. These lockfiles can be found at flake.lock where complete metadata for the flakes are found.

Selected list of attributes for outputs

While you can export attributes of any type, there are common attributes you'll mostly see.

As an example, here's the flake of my NixOS configuration.

nix flake show github:foo-dogsquared/nixos-config | nix run nixpkgs#gnused -- 's/\x1b\[[0-9;]*m//g'
github:foo-dogsquared/nixos-config/12077bfc601e5465e343e590a830e8d3cb6a1a59 ├───devShells │ ├───aarch64-darwin │ │ ├───flatpak: development environment 'nix-shell' │ │ ├───hugo: development environment 'nix-shell' │ │ └───rust: development environment 'nix-shell' │ ├───aarch64-linux │ │ ├───flatpak: development environment 'nix-shell' │ │ ├───hugo: development environment 'nix-shell' │ │ └───rust: development environment 'nix-shell' │ ├───i686-linux │ │ ├───flatpak: development environment 'nix-shell' │ │ ├───hugo: development environment 'nix-shell' │ │ └───rust: development environment 'nix-shell' │ ├───x86_64-darwin │ │ ├───flatpak: development environment 'nix-shell' │ │ ├───hugo: development environment 'nix-shell' │ │ └───rust: development environment 'nix-shell' │ └───x86_64-linux │ ├───flatpak: development environment 'nix-shell' │ ├───hugo: development environment 'nix-shell' │ └───rust: development environment 'nix-shell' ├───homeManagerConfigurations: unknown ├───homeManagerModules: unknown ├───lib: unknown ├───nixosConfigurations │ └───ni: NixOS configuration ├───nixosModules │ ├───agenix: NixOS module │ ├───archiving: NixOS module │ ├───desktop: NixOS module │ ├───dev: NixOS module │ ├───hardware-setup: NixOS module │ ├───themes: NixOS module │ └───users: NixOS module └───packages ├───aarch64-darwin │ ├───doggo: package 'doggo-0.4.1' │ ├───gnome-shell-extension-burn-my-windows: package 'gnome-shell-extension-burn-my-windows-2' │ ├───gnome-shell-extension-desktop-cube: package 'gnome-shell-extension-desktop-cube-5' │ ├───gnome-shell-extension-fly-pie: package 'gnome-shell-extension-fly-pie-12' │ ├───gnome-shell-extension-pop-shell: package 'gnome-shell-extension-pop-shell-unstable-2021-11-30' │ ├───libcs50: package 'libcs50-10.1.1' │ ├───llama: package 'llama-1.0.2' │ ├───neo: package 'neo-0.6' │ ├───pop-launcher: package 'pop-launcher-1.1.0' │ ├───pop-launcher-plugin-duckduckgo-bangs: package 'pop-launcher-plugin-duckduckgo-bangs-1.3.0' │ ├───sioyek: package 'sioyek-1.0.0' │ └───tic-80: package 'tic-80-unstable-2021-12-18' ├───aarch64-linux │ ├───doggo: package 'doggo-0.4.1' │ ├───gnome-shell-extension-burn-my-windows: package 'gnome-shell-extension-burn-my-windows-2' │ ├───gnome-shell-extension-desktop-cube: package 'gnome-shell-extension-desktop-cube-5' │ ├───gnome-shell-extension-fly-pie: package 'gnome-shell-extension-fly-pie-12' │ ├───gnome-shell-extension-pop-shell: package 'gnome-shell-extension-pop-shell-unstable-2021-11-30' │ ├───libcs50: package 'libcs50-10.1.1' │ ├───llama: package 'llama-1.0.2' │ ├───neo: package 'neo-0.6' │ ├───pop-launcher: package 'pop-launcher-1.1.0' │ ├───pop-launcher-plugin-duckduckgo-bangs: package 'pop-launcher-plugin-duckduckgo-bangs-1.3.0' │ ├───sioyek: package 'sioyek-1.0.0' │ └───tic-80: package 'tic-80-unstable-2021-12-18' ├───i686-linux │ ├───doggo: package 'doggo-0.4.1' │ ├───gnome-shell-extension-burn-my-windows: package 'gnome-shell-extension-burn-my-windows-2' │ ├───gnome-shell-extension-desktop-cube: package 'gnome-shell-extension-desktop-cube-5' │ ├───gnome-shell-extension-fly-pie: package 'gnome-shell-extension-fly-pie-12' │ ├───gnome-shell-extension-pop-shell: package 'gnome-shell-extension-pop-shell-unstable-2021-11-30' │ ├───libcs50: package 'libcs50-10.1.1' │ ├───llama: package 'llama-1.0.2' │ ├───neo: package 'neo-0.6' │ ├───pop-launcher: package 'pop-launcher-1.1.0' │ ├───pop-launcher-plugin-duckduckgo-bangs: package 'pop-launcher-plugin-duckduckgo-bangs-1.3.0' │ ├───sioyek: package 'sioyek-1.0.0' │ └───tic-80: package 'tic-80-unstable-2021-12-18' ├───x86_64-darwin │ ├───doggo: package 'doggo-0.4.1' │ ├───gnome-shell-extension-burn-my-windows: package 'gnome-shell-extension-burn-my-windows-2' │ ├───gnome-shell-extension-desktop-cube: package 'gnome-shell-extension-desktop-cube-5' │ ├───gnome-shell-extension-fly-pie: package 'gnome-shell-extension-fly-pie-12' │ ├───gnome-shell-extension-pop-shell: package 'gnome-shell-extension-pop-shell-unstable-2021-11-30' │ ├───libcs50: package 'libcs50-10.1.1' │ ├───llama: package 'llama-1.0.2' │ ├───neo: package 'neo-0.6' │ ├───pop-launcher: package 'pop-launcher-1.1.0' │ ├───pop-launcher-plugin-duckduckgo-bangs: package 'pop-launcher-plugin-duckduckgo-bangs-1.3.0' │ ├───sioyek: package 'sioyek-1.0.0' │ └───tic-80: package 'tic-80-unstable-2021-12-18' └───x86_64-linux ├───doggo: package 'doggo-0.4.1' ├───gnome-shell-extension-burn-my-windows: package 'gnome-shell-extension-burn-my-windows-2' ├───gnome-shell-extension-desktop-cube: package 'gnome-shell-extension-desktop-cube-5' ├───gnome-shell-extension-fly-pie: package 'gnome-shell-extension-fly-pie-12' ├───gnome-shell-extension-pop-shell: package 'gnome-shell-extension-pop-shell-unstable-2021-11-30' ├───libcs50: package 'libcs50-10.1.1' ├───llama: package 'llama-1.0.2' ├───neo: package 'neo-0.6' ├───pop-launcher: package 'pop-launcher-1.1.0' ├───pop-launcher-plugin-duckduckgo-bangs: package 'pop-launcher-plugin-duckduckgo-bangs-1.3.0' ├───sioyek: package 'sioyek-1.0.0' └───tic-80: package 'tic-80-unstable-2021-12-18'

Flake templates

Nix registry

Per the Nix manual:

Flake registries are a convenience feature that allows you to refer to flakes using symbolic identifiers such as nixpkgs, rather than full URLs such as git://github.com/NixOS/nixpkgs.

Here's an example of the registry list with some overriden flakes such as the nixpkgs flake following from my NixOS configuration.

nix registry list
system flake:agenix path:/nix/store/yka795vkb7ny5fnybf8dafbypcjfmi9n-source?lastModified=1638837456&narHash=sha256-WHLOxthAGx%2fwXw3QUa%2flFE3mr6cQtnXfFYZ0DNyYwt4=&rev=57806bf7e340f4cae705c91748d4fdf8519293a9 system flake:config path:/nix/store/3nlagaj6748w4ffxx4vp5jss2k571f8i-source?lastModified=1640442672&narHash=sha256-Gkt2On9szrFlOo6QiYMOA90qTp4PICd7STHFhGA4bCs= system flake:home-manager path:/nix/store/ijh6v700kpssfyw44v4awbm2gmjx26qs-source?lastModified=1640296831&narHash=sha256-Mu32vTcfZru4VrvgnpvQKmwC4uY0oF3vnnC2o9SgnRU=&rev=f15b151ca1c4aea23515c241051d71f1b5cf97c8 system flake:nixpkgs path:/nix/store/lgfhg4n6445yizgf0xjirb4bc4j86fr9-source?lastModified=1640269308&narHash=sha256-vBVwv3+kPrxbNyfo48cB5cc5%2f4tq5zlJGas%2fqw8XNBE=&rev=0c408a087b4751c887e463e3848512c12017be25 global flake:agda github:agda/agda global flake:blender-bin github:edolstra/nix-warez?dir=blender global flake:dreampkgs github:nix-community/dreampkgs global flake:dwarffs github:edolstra/dwarffs global flake:fenix github:nix-community/fenix global flake:flake-utils github:flake-utils/numtide global flake:gemini github:nix-community/flake-gemini global flake:home-manager github:nix-community/home-manager global flake:hydra github:NixOS/hydra global flake:mach-nix github:DavHau/mach-nix global flake:nimble github:nix-community/flake-nimble global flake:nix github:NixOS/nix global flake:nixops github:NixOS/nixops global flake:nixos-hardware github:NixOS/nixos-hardware global flake:nixos-homepage github:NixOS/nixos-homepage/flake global flake:nur github:nix-community/NUR global flake:nixpkgs github:NixOS/nixpkgs/nixpkgs-unstable global flake:templates github:NixOS/templates global flake:patchelf github:NixOS/patchelf global flake:nix-serve github:edolstra/nix-serve global flake:nickel github:tweag/nickel

So how does a flake registry work?

More information about flakes

Backlinks