Flake Parts
Flake Parts is a framework that leverages the NixOS module system to write modular and organized flakes. It provides options that represent standard flake attributes and establishes an easy way to work with system
. It is a minimal and very lightweight mirror of the flake schema.
The major benefit of flake-parts is being able to write modular flakes with the full power of the module system. It is a great option and alternative to flake-utils, a wrapper which is largely discouraged from being used.
There is documentation available for a variety of flake-parts powered modules available on https://flake.parts.
Getting Started
It is very easy to introduce flake-parts into your already existing flake.nix
, or to a completely new project as well. A minimal template is provided below:
{
description = "Your new project, powered by flake-parts!";
inputs = {
flake-parts.url = "github:hercules-ci/flake-parts";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; # This should point to whichever nixpkgs rev you want.
};
outputs = { flake-parts, ... } @ inputs: flake-parts.lib.mkFlake { inherit inputs; } {
imports = [
# ./module.nix
# inputs.foo.flakeModule
];
perSystem = { config, self', inputs', pkgs, system, ... }: {
# Allows definition of system-specific attributes
# without needing to declare the system explicitly!
#
# Quick rundown of the provided arguments:
# - config is a reference to the full configuration, lazily evaluated
# - self' is the outputs as provided here, without system. (self'.packages.default)
# - inputs' is the input without needing to specify system (inputs'.foo.packages.bar)
# - pkgs is an instance of nixpkgs for your specific system
# - system is the system this configuration is for
# This is equivalent to packages.<system>.default
packages.default = pkgs.hello;
};
flake = {
# The usual flake attributes can be defined here, including
# system-agnostic and/or arbitrary outputs.
};
# Declared systems that your flake supports. These will be enumerated in perSystem
systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
};
}
Writing Modules
Modules are written in exactly the same way as NixOS modules. The main exposed attributes are perSystem
and flake
. You can reference the self
and inputs
attribute at the top-level, though generally you will likely not need it. An example of writing a module can be seen below:
# flake/packages.nix
{ self, inputs, ... }: {
perSystem = { pkgs, ... }: {
packages.hello = pkgs.hello;
};
}
The above module can then be imported and referenced in the main flake (or other modules)
# flake.nix
{
inputs = {
flake-parts.url = "github:hercules-ci/flake-parts";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
};
outputs = { flake-parts, ... } @ inputs: flake-parts.lib.mkFlake { inherit inputs; } {
imports = [
./flake/packages.nix
];
systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
};
}
On evaluation the flake will expose 4 distinct outputs under packages:
$ nix flake show --all-systems
path:/path/to/flake.nix?lastModified=omitted&narHash=omitted
└───packages
├───aarch64-darwin
│ └───hello: package 'hello-2.12.1'
├───aarch64-linux
│ └───hello: package 'hello-2.12.1'
├───x86_64-darwin
│ └───hello: package 'hello-2.12.1'
└───x86_64-linux
└───hello: package 'hello-2.12.1'
See also
- Introduction - flake-parts