Without Flakes
new-scope — named aspect namespaces
Section titled “new-scope — named aspect namespaces”new-scope creates an isolated aspect namespace within any lib.evalModules evaluation:
let result = lib.evalModules { modules = [ (new-scope "my") { my.aspects = { aspects, ... }: { laptop = { nixos = { pkgs, ... }: { environment.systemPackages = [ pkgs.vim ]; }; includes = [ aspects.base ]; }; base.nixos = { lib, ... }: { networking.hostName = "laptop"; }; }; } ]; };in lib.nixosSystem { modules = [ result.config.my.modules.nixos.laptop ]; }new-scope "my" creates:
my.aspects— input: aspect definitions (type:aspectsType)my.modules— output: transposed + resolved modules (read-only)
Multiple scopes
Section titled “Multiple scopes”Independent scopes can coexist and merge. Each creates its own <name>.aspects / <name>.modules pair:
modules = [ (new-scope "foo") (new-scope "bar") { foo.aspects.a.nixos.x = [ "from-foo" ]; } { bar.aspects.a.nixos.x = [ "from-bar" ]; } ({ config, ... }: { bar = config.foo; }) # merge foo into bar];After merging, bar.modules.nixos.a contains both "from-foo" and "from-bar".
new — low-level factory
Section titled “new — low-level factory”new is the callback-based primitive underneath new-scope:
new (option: transposed: { options.myLib.aspects = option; config.myLib.modules = transposed;}) config.myLib.aspectsnew-scope is sugar for the common ${name}.aspects / ${name}.modules pattern. Use new directly when you need custom option paths or additional logic in the callback.
Useful for libraries that want isolated aspect scopes or flake-parts independence (see Den’s scope).