Flake outputs: `import` input

I’m trying to understand how the nix-systems pattern (used by flake-utils) works. The flake-utils flake.nix contains:

  inputs.systems.url = "github:nix-systems/default";

  outputs = { self, systems }: {
    lib = import ./lib.nix {
      defaultSystems = import systems;

I’m used to seeing the outputs function treat each input as an attribute set (e.g. systems.overlays), so this import surprised me.

The nix flake documentation, describing the inputs passed into outputs, mentions:

In addition to the outputs of each input, each input in inputs also contains some metadata about the inputs. These are:

  • outPath: The path in the Nix store of the flake’s source tree. This way, the attribute set can be passed to import as if it was a path, as in the example above (import nixpkgs).

That seems to explain how the above import works. The default systems input derives from a flake.nix whose outputs produces an empty attr set:

  outputs = _: { };

but this empty set gets augmented with an outPath to facilitate the import.

The default systems has a default.nix containing a list of systems, so presumably this is what the import evaluates to:


This post started out as a question, “how does this work”, but in the process of writing it, I think I’ve come to understand the moving parts. So the remaining question is: are my conclusions correct?

Yeah that’s indeed what that does, the systems variable passed to the outputs function will have an outPath attribute pointing to the store path where the input has been fetched to, and then it’s a normal import statement that’s being passed a directory and so it will look for a default.nix file.

1 Like