February 26th, 2026
Short and sweet improvement on my previous post
So, turns out there is a way simple way of doing what have done on the packaging Go with nix post, the more you know…
At the very last part of my post, I introduce the idea of the forEachSystem function. This function is composed of a few steps, where I create an attribute set for each system I would like to support. Although that works and makes sense, there is a far more succinct way of doing it, without introducing any external library.
Alright… So, this is what I had:
let
systems = [
"x86_64-linux"
"aarch64-linux"
"x86_64-darwin"
"aarch64-darwin"
];
forEachSystem = (callback:
# Turns the list of system specific attrsets into an attrset
# where the attribute `name` is the system name.
builtins.listToAttrs (
# Iterates over the `systems` array, creating {systemName, attrset} pairs.
builtins.map
(system:
let
pkgs = import nixpkgs { system = system; };
in
{
name = system;
value = callback pkgs;
})
systems
)
);
in
It is as vebose as it gets, every step of the transformation is there.
While working on the Kronk project nix support I stumbled on a better way of doing it. Using the genAttrs, we do pretty much exactly what I was doing combining map and listToAttrs.
let
systems = [
"x86_64-linux"
"aarch64-linux"
"x86_64-darwin"
"aarch64-darwin"
];
forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f system);
in
{
devShells = forAllSystems (
system:
let
pkgs = nixpkgs.legacyPackages.${system};
in
{
default = pkgs.mkShell {
buildInputs = [
pkgs.go_1_26
];
};
}
);
.
.
.
And that is it, short and sweet, just as I promised.