Nixpkgs module system config modules graph

We can now trivially obtain a Nix data structure that is a tree of the modules that took part in the evaluation of a configuration :evergreen_tree:

Try it yourself! :dancer: First, make sure of course that your Nixpkgs checkout includes the merged PR (which branches it landed in). Now, simply do something like

$ nix eval --json '.#nixosConfigurations.termitomyces.graph' > graph.json

Or pipe it to a fancy TUI json explorer:

$ nix eval --json '.#nixosConfigurations.termitomyces.graph' | nix run 'nixpkgs#fx'

See that .graph attribute? That’s new :sparkles:. And everyone gets it for free :muscle:. Normally, you’d access .config and thanks to the lazy nature of the language, if you don’t access .graph, its mere existence has practically no performance penalty, because it remains a thunk :egg:.

Explore the graph :face_with_monocle:. It lets you know what modules took part in the evaluation of a configuration, be it NixOS, home-manager, nix-darwin, NixVim–whichever. It shows you which modules imported which other modules. For each module, several attributes are provided. Here’s an example snippet:

{
  "disabled": false,
  "file": "/nix/store/3ya3mf8fa6l9sr1d84v1sq75h2kl05fh-source/inputs/nixpkgs/nixos/modules/services/networking/hylafax/default.nix",
  "imports": [
    {
      "disabled": false,
      "file": "/nix/store/3ya3mf8fa6l9sr1d84v1sq75h2kl05fh-source/inputs/nixpkgs/nixos/modules/services/networking/hylafax/options.nix",
      "imports": [],
      "key": "/nix/store/3ya3mf8fa6l9sr1d84v1sq75h2kl05fh-source/inputs/nixpkgs/nixos/modules/services/networking/hylafax/options.nix"
    },
    {
      "disabled": false,
      "file": "/nix/store/3ya3mf8fa6l9sr1d84v1sq75h2kl05fh-source/inputs/nixpkgs/nixos/modules/services/networking/hylafax/systemd.nix",
      "imports": [],
      "key": "/nix/store/3ya3mf8fa6l9sr1d84v1sq75h2kl05fh-source/inputs/nixpkgs/nixos/modules/services/networking/hylafax/systemd.nix"
    }
  ],
  "key": "/nix/store/3ya3mf8fa6l9sr1d84v1sq75h2kl05fh-source/inputs/nixpkgs/nixos/modules/services/networking/hylafax/default.nix"
}

So, what can I do with it, you ask? Good question. Well, you might not care about this at all :man_shrugging:. But for example, I used it to find out which flake-parts module files contain NixOS modules that merge into flake.modules.nixos.pc (this option); otherwise, I would have had to use some unsound regex on my Nix code :open_mouth:. Or, you could collect some statistics from the graph :bar_chart: or draw a graphical tree (I’d love to see that).

One possible future addition to this graph could be computed statistics, such as total number of modules. Consider contributing that :nerd_face: !

By the way, one thing this graph makes immediately apparent, if you examine it, is a problem some large module system projects have; they import all modules unconditionally. Here’s the NixOS issue for that.

Thank you AJ for presenting the original use case and then mobbing on this with me start to finish! Thank you @roberth and @hsjobeki for providing invaluable feedback.

I hope you benefit from this addition to the module system and are inspired to contribute in our growing ecosystem. If you wish to see what other things I’m working on or would like to work on, check out my profile.

12 Likes

Amazing, I just tested on my config and it works, thanks for this feature !!!

1 Like

Is that also possible from a config without flakes?