Nix: Access inputs in flake home-manager module

I’m trying to make a home-manager module using this flake:

{
  outputs =
    { self }:
    {
      homeManagerModules.myModule = ./my-module.nix;
    };
}

Which works fine until I want to add an input:

{
  inputs = {
    input.url = "input/path";
  };

  outputs =
    { self, input }:
    {
      homeManagerModules.myModule = ./my-module.nix;
      };
    };
}

The problem is, I can’t access inputs.input in my-module.nix:

{  inputs, ...}:

{
home.packages = [ inputs.input.somePackage];
}

How do I make inputs available in my-module.nix?

I thought I might be able to just use the input itself by name:

{  input, ...}:

{
home.packages = [ input.somePackage];
}

but that’s not accessible either.

I’m sure I’m missing something obvious! Thanks

In the context of an HM module? You don’t, because modules aren’t evaluated in isolation.

Assume inputs is provided and write your code. Then tell consumers to pass inputs in.

When you initialize home manager you can pass extra stuff to the module system by adding them to extraSpecialArgs.

In the nixos module system you can do the same thing with specialArgs my configuration looks roughly like this:

nixpkgs.lib.nixosSystem {
    inherit system;
    specialArgs = { inherit inputs; };
    modules = [
      nixpkgs.nixosModules.notDetected
      ./configuration.nix
      ./hardware-configuration.nix
      home-manager.nixosModules.home-manager
      {
        home-manager.extraSpecialArgs = { inherit inputs; };
        home-manager.users.youruser = { ... };
      }
    ]
  }

I’ve paired it down a bit cause I have some other stuff going on.

Later in a home manager module you can add inputs to the argument list and it will be populated for you:

{ config, lib, pkgs, inputs, ... }: {
  ...
}

If you’re exporting a module and can’t affect the specialArgs of whoever imports the module, the only way to do it is:

{
  inputs = {
    input.url = "input/path";
  };

  outputs =
    { self, input }@inputs:
    {
      homeManagerModules.myModule = import ./my-module.nix { inherit inputs; };
    };
}

But then the file my-module.nix has to have 2 separate argument sets at the top: the one that accepts in the local flake’s arguments, and the one that accepts the module system’s arguments. So technically the file itself can no longer be considered a module. Also, to help error messages reference the file, you may need to add a hint to the module system of what file the module is in by setting _file inside the module.

3 Likes

thanks, I was hoping for one home manager module to be able to use packages from another but I guess that’s not possible