zerforschen.plus/content/posts/why-i-do-not-use-flake-utils.md
2025-04-07 18:25:01 +02:00

114 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

+++
date = '2025-04-06T14:49:03+02:00'
draft = false
title = 'Why I do not use flake-utils'
tags = ['nix']
+++
I have been using [Nix] for a while now. Around a year ago, I switched everything from the [servicepoint] library to my [machine configuration] over to flakes.
For me the biggest advantage flakes bring is not additional functionality. Instead, they are an easier and semi-standardized way to do what you could before.
When learning flakes, you often see [flake-utils] being used. With it, you can shorten your flakes by not having to specify everything per system.
### Without anything
```nix
{
description = "Flake utils demo - without flakes";
outputs = { self, nixpkgs, flake-utils }:
{
packages."x86_64-linux" = rec {
hello = pkgs.hello;
default = hello;
}
packages."aarch64-linux" = rec {
hello = pkgs.hello;
default = hello;
}
# more systems ...
}
}
```
### With flake-utils
```nix
{
description = "Flake utils demo";
inputs.flake-utils.url = "github:numtide/flake-utils";
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let pkgs = nixpkgs.legacyPackages.${system}; in
{
packages = rec {
hello = pkgs.hello;
default = hello;
};
}
);
}
```
### With function in flake
To make a long story short, here is what I usually do instead:
```nix
{
description = "forAllSystems demo";
outputs = { self, nixpkgs }:
let
supported-systems = [ # [1]
"x86_64-linux"
"aarch64-linux"
];
forAllSystems =
f:
nixpkgs.lib.genAttrs supported-systems /* [2] */ (
system:
f rec {
pkgs = nixpkgs.legacyPackages.${system}; # [3]
inherit system;
}
);
in
{
packages = forAllSystems ({ pkgs, ... }: rec {
hello = pkgs.hello;
default = default;
});
}
}
```
Thats definitely more code! - Yes, but it also includes more information in the flake, while getting rid of an external dependency.
While more code can be intimidating for beginners, it actually helps remove a barrier to understanding how the flake works in this case.
For me, it wasnt a problem to ignore boilerplate like this at first, slowly learning more language features until I finally understood everything.
At **[1]**, the supported systems are specified. I personally use `x86_64-linux` and `aarch64-linux`, but I also usually support `x86_64-darwin` and `aarch64-darwin` in public projects.
If you want to support any system, you can use [`nixpkgs.lib.system.flake-exposed`] at **[2]** instead of defining your own list.
Because the definition is right inside the flake, you can tweak what gets passed to the function. For example, the [flake for RedoxOS-development] I contributed[^1] this to passes the custom rust-toolchain.
An example for how to do it is already right there: at **[3]**, `pkgs` is provided.
Another possible tweak: You may want to define separate supported systems for each output.
This is useful, for example, if the target environment you're developing for cannot support a development shell.
For me, the trade-offs are worth it, as they provide greater transparency and control over the flake configuration.
That being said, I fully acknowledge that `flake-utils` can still be a great choice for many people. It simplifies things and reduces the need to write boilerplate code, which can be a big plus depending on your needs and workflow. Ultimately, it's a matter of personal preference and the specific requirements of your project.
[^1]: If you check the history, you will see I am not mentioned. I am still a bit salty about that, as it was my first contribution to a bigger OSS project.
[Nix]: https://nixos.org/
[servicepoint]: https://git.berlin.ccc.de/servicepoint/servicepoint
[machine configuration]: https://git.berlin.ccc.de/vinzenz/nixos-configuration
[flake-utils]: https://github.com/numtide/flake-utils
[`nixpkgs.lib.system.flake-exposed`]: https://github.com/NixOS/nixpkgs/blob/374e6bcc403e02a35e07b650463c01a52b13a7c8/lib/systems/default.nix#L58
[flake for RedoxOS-development]: https://gitlab.redox-os.org/redox-os/redox/-/blob/cb34b9bd862f46729c0082c37a41782a3b1319c3/flake.nix#L38