Who is 'self' in flake outputs?

I’m diving into flakes for the first time - trying not to skip any detail.

In Flake format the arguments to the function outputs are { self, nixpkgs }:

Some questions:

  1. Who is self in this context?
  2. Can I inspect this instantiated in the nix-repl?
    2.1 If so can someone show me a simple walk-through?

Cheers…

1 Like

self is outputs. The following trivial flake might help:

{
  outputs = { self }: {
    a = 1;
    b = self.a + 1;
  };
}

for which nix eval .#b results in 2.

The self reference is useful. For example the packages, modules, and overlays flake outputs can be used in your nixos host configurations which would be in outputs.nixosConfigurations.

8 Likes

I found it easier to see self as a special argument that refers to whatever a function returns.

self is more than just outputs. It references inputs, outputs, packages, and many other hidden things. It essentially is a reference to the entire flake “object”. Take the following example.

{
  description = "A very basic flake";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
  };

  outputs =
    { self, nixpkgs }:
    {
      inherit self;
      packages.x86_64-linux.hello = nixpkgs.legacyPackages.x86_64-linux.hello;
      packages.x86_64-linux.default = self.packages.x86_64-linux.hello;
    };
}

If I go to my shell and type nix eval .#self. and hit TAB, it’ll show me everything that is in the flake attrset.

% nix eval .\#self.
.\#self.inputs
.\#self.lastModifiedDate
.\#self.outPath
.\#self.packages
.\#self.sourceInfo        
.\#self.lastModified
.\#self.narHash
.\#self.outputs
.\#self.self
.\#self._type

Try it out and you’ll see you can access pretty much anything defined in the flake and more.

2 Likes