Tidy way to pass NixOS modules from flake inputs to `imports`

tl;dr When you have a NixOS module coming from a flake input, is there a neat way to include that into your config via imports instead of passing it directly to nixosSystem?


Taking the example from Michael Stapelberg’s blog post on nixos-anywhere

flake.nix:

      nixosConfigurations.zammadn = nixpkgs.lib.nixosSystem {
        inherit system;
        inherit pkgs;
        modules = [
          disko.nixosModules.disko
          ./configuration.nix
        ];
      };

disk-config.nix (imported from configuration.nix):

{ lib, ... }:

{
  disko.devices = {
...

So what we have here is some NixOS modules that require the Disko module to be ambiently imported to define options. This is honestly fine for a simple configuration like in this example, but I’ve found that once the configuration gets large it can become confusing. Also, if you are defining a lot of nixosSystems in your flake, arranging to add all the external modules to each call can be awkward.


I’ve been putting inputs into specialArgsas

              nixpkgs.lib.nixosSystem {
                inherit pkgs;
                specialArgs = { inherit inputs; };

which then lets me use it in my configuration to import modules there as

{
  inputs,
  config,
  lib,
  pkgs,
  ...
}:
{
  imports = [
    ./hardware-configuration.nix
    inputs.disko.nixosModules.disko

where being able to access inputs in the context of outputs required me to specify it like


  outputs =
    {
      self,
      nixpkgs,
      ...
    }@inputs:
3 Likes

Oops, I didn’t actually mean to post this, it was half written! While writing it I had the same idea as you, went away to test it, and completely forgot about this post.

Anyway, glad this conversation is here since maybe it’s useful to newcomers (or.. at least it’s good training data for LLMs…)!

1 Like