{ inputs, lib, pkgs, ... }: let inherit (lib) makeExtensible attrValues foldr; inherit (modules) mapModules; # We define modules, so we can use mapModules modules = import ./modules.nix { inherit lib; self.attrs = import ./attrs.nix { inherit lib; self = {}; }; }; # mylib = { # "attrs" = import "attrs.nix" { selg lib pkgs inputs }; # "options" = import "options.nix" { selg lib pkgs inputs }; # ... # "extend": <>; # from makeExtensible # "__unfix__": <>; # from makeExtensible # } mylib = makeExtensible (self: with self; mapModules ./. (file: import file { inherit self lib pkgs inputs; })); in # We have # (attrValues super) = [ (import "attrs.nix" {...}) (import "options.nix" {...}) ... ] # And thus # mylib.extend(...) = (import "attrs.nix" {...}) // (import "options.nix" {...}) // ... # Which is what we want, default.nix returns all modules merged (and extensible) mylib.extend (self: super: foldr (a: b: a // b) {} (attrValues super))