Using variables from top-level file in included file?

Hi all,

I guess this is a no-brainer and I just have the wrong keywords. Or it really is not possible.

Say I have a file foo.nix, that includes another file bar.nix. And I would like a variable that I set in foo.nix be used in bar.nix.

Like so, setting username in foo.nix and using it in bar.nix:

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

let
  myusername = "johndoe";

in {
  imports = [
    ./bar.nix
  ]
}
{ config, lib, pkgs, ... }:

  home.username = "${myusername}";
  [...]

}

Kind regards,
Johannes

There are three ways to do this, divided into two groups:

Group 1: import once, use in multiple modules

Using specialArgs, like in the wiki.

This is probably the approach you would want, username looks like a variable that could be useful in multiple places.

Group 2: using values per-module

In case the value you are passing will only be used for that module and it does not make sense to expose to multiple modules, you can do one of:

Import it in the target module

{ config, lib, pkgs, ... }:
+let
+   inherit (import ./foo.nix) myusername;
+in
+{ # Missing bracket in original code?
 
  
  home.username = "${myusername}";
  [...]
  
}

Turn your module into module-producing function

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

let
  myusername = "johndoe";

in {
  imports = [
-    ./bar.nix
+    ((import ./bar.nix) { myusername = "johndoe"; })  # Brackets to delineate functions
  ]
}
+ { myusername }:
{ config, lib, pkgs, ... }:

  home.username = "${myusername}";
  [...]

}

Alternative: just reuse values from config

About username specifically, but applicable to any other variable that already exists in the options – you can just refer to it as config.users.users.<name>.name in any module in your NixOS configuration. config gets passed to every module by default. Here’s the option description.

1 Like