Flakes

Table of Contents

1. Preface

Use this stuff for hashless updates, lock files and more. Seems like the same situation as with tmux and cigaretters - you never know how much you need it before you start using it. Most importantly flakes provide a way to standardize inputs and outputs of a package.

2. Questions

2.1. TODO look into nixConfig top level attribute.

3. Readup

4. Structure

Flakes are structured, i.e. represent a specific attr set, unlike default.nix, etc. A flake is a directory that contains a file named flake.nix in the root dir. The file contains defenition for an attr set, containing inputs and outputs, along with package metadata, like description. name was discussed at some point but doesn't have an implementation atm. At one point flakes required a git repositoty to be evaluated, but that is no longer the case. Nevertheless, evaluation under a git tree imposess some sensible limitations:

  • files outside of the tree are invisible to the flake.
  • dirty tree may be configured to be considered an evaluation error.
  • git revision in a clean tree is used in some meta attributes of a flake and can be used to adress flake revisions.

nixConfig, another possible top-level attribute, may be used to manipulate nix.conf on a flake-local level.

flake.lock is a file, used to track dependencies. When written, it's populated by flake revisions. Existing lock file won't be overwritten by future builds until user requests that by specifying inputs to update or removing the file all together.

4.1. Inputs

An attr, describing dependencies of a flake. This dependencies may include locally or remotely accessible flakes, most notably nixpkgs, or simple files (similarly to fetch...). The later requires input.<name>.flake to be set to false. Inputs can be inherited with input.<name>.follows from other inputs.

4.1.1. Defining an input

Most staight-forward way of defining inputs is by inputs.<name>.url, which is a string containing a path, under which the input is accessible. This paths follow some conventions, first of which is the registry.

  1. Registry

    Registry is a utility, containing a number of shorthands for commonly used paths and flakes.

    ~ $ nix registry list
    ...
    global flake:nimble github:nix-community/flake-nimble
    global flake:nix github:NixOS/nix
    global flake:nix-darwin github:LnL7/nix-darwin
    global flake:nixops github:NixOS/nixops
    global flake:nixos-hardware github:NixOS/nixos-hardware
    global flake:nixos-homepage github:NixOS/nixos-homepage
    global flake:nixos-search github:NixOS/nixos-search
    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:poetry2nix github:nix-community/poetry2nix
    ...
    

    Registry can be maniputated to pin, add, delete and alter these definitions.

  2. URL-like paths

    Some examples of URL-like paths are:

    • registry entries: nixpkgs
    • revision-specific paths: nixpkgs/a3a3dda...
    • github repos: github:NixOS/nixpkgs
      • with specific branch: github:NixOS/nixpkgs/nixos-20.09
      • with specific revision
      • with specific subdir: github.edolstra/nix-warez?dir=blender
    • a url to a tarball
    • a git repo: git+https://...
  3. Local paths

    May be absolute or relative (starting with ./). If the path is a git repo, it will be treated as a git+file: URL. Otherwise it's interpreted as path:. If the path doesn't contain flake.nix, nix will search for one upwards.

  4. Types
    • indirect flakes are entries in the registry.
    • simple types include file, path, tarball.
    • supported VCS's are git, mercurial.
    • optimised shorthands for remote VCS's are github, gitlab, sourcehut.

4.1.2. Automatic defenitions

Inputs are used as arguments to the outputs function, which is where input's name (or id) is used. Some inputs, like nixpkgs, can be ommitted form inputs set and only left as arguments to outputs. In that case, necessary defenitions will be provided automatically with input.<name>.type = "indirect";. This only works for flakes that are registry entries.

4.1.3. Follows/parent

In order to reduce dependency creep, i.e. not have 10 separate nixpkgs, input-heavy configurations may want to force flakes to share inputs. This can be done with follows.

inputs = {
  home-manager.inputs.nixpkgs.follows = "nixpkgs";

  home-manager.url = "github:nix-community/home-manager/release-23.11";
  nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
};

4.2. Outputs

outputs is a function, taking inputs and self - directory of this flake in the store, and returning an attr set. The return value contains sets, used by specific nix tools depending on the name. Many of the sets put their content under speficic attirubtes, most notably <system>, which is a platform tag of the form <cpu>-<os> - like "x86_64-linux" . Other common attribute is <name> - a name, under which specific output is accessible. Value under default will be used by most tools when specific name isn't provided.

4.2.1. Output attributes

Atributes in output may be arbitrary. Some of them are interpreted by specific tools. Most notable outputs are:

  • checks."<system>"."<name>" - a derivation, used by nix flake check.
  • packages."<system>"."<name>" - used by nix build.
  • apps."<system>"."<name>" - used by nix run.

Other known outputs include:

  • lib - place to define utility expressions. Notably used in nixpkgs.
  • formatter."<system>" - formatter derivation.
  • legacyPackages - similar to packages, used in nixpkgs.
  • overlays."<name>" - overlays, consumed by other flakes.
  • nixosModules."<name>" - modules, consumed by other flakes.
  • hmModules."<name>" - same as nixosModules, but used by home-manager.
  • nixosConfigurations."<hostname>" - used by nixos-rebuild --flake.#<hostname>.
  • devShells."<system>"."<name>" - used by nix develop.
  • hydraJobs."<attr>"."<system>" - Hydra build jobs.
  • templates."<name>" - templates, used by nix flake init -t <flake>#<name>.

4.2.2. legacyPackages

Functionally simillar to packages. From nixpkgs:

The "legacy" in `legacyPackages` doesn't imply that the packages exposed through this attribute are "legacy" packages. Instead, `legacyPackages` is used here as a substitute attribute name for `packages`. The problem with `packages` is that it makes operations like `nix flake show nixpkgs` unusably slow due to the sheer number of packages the Nix CLI needs to evaluate. But when the Nix CLI sees a `legacyPackages` attribute it displays `omitted` instead of evaluating all packages, which keeps `nix flake show` on Nixpkgs reasonably fast, though less information rich.

Keep your head up. Rev: 0.1.20240131.b741ea0.