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.
- 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.
- 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
- with specific branch:
- a url to a tarball
- a git repo:
git+https://...
- registry entries:
- Local paths
May be absolute or relative (starting with
./
). If the path is a git repo, it will be treated as agit+file:
URL. Otherwise it's interpreted aspath:
. If the path doesn't containflake.nix
, nix will search for one upwards. - 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 bynix flake check
.packages."<system>"."<name>"
- used bynix build
.apps."<system>"."<name>"
- used bynix run
.
Other known outputs include:
lib
- place to define utility expressions. Notably used innixpkgs
.formatter."<system>"
- formatter derivation.legacyPackages
- similar topackages
, used innixpkgs
.overlays."<name>"
- overlays, consumed by other flakes.nixosModules."<name>"
- modules, consumed by other flakes.hmModules."<name>"
- same asnixosModules
, but used byhome-manager
.nixosConfigurations."<hostname>"
- used bynixos-rebuild --flake.#<hostname>
.devShells."<system>"."<name>"
- used bynix develop
.hydraJobs."<attr>"."<system>"
- Hydra build jobs.templates."<name>"
- templates, used bynix 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.