Skip to content

Bidirectional Dependencies

A host aspect’s homeManager settings apply to all users on that host:

den.aspects.igloo.homeManager.programs.direnv.enable = true;

If igloo has users tux and pingu, both get direnv enabled.

This also works with static includes:

den.aspects.igloo.includes = [
{ homeManager.programs.direnv.enable = true; }
];

And with parametric includes that receive context:

den.aspects.igloo.includes = [
({ host, user }: {
homeManager.programs.direnv.enable = true;
})
];

A user aspect’s nixos or darwin settings apply to every host with that user:

den.aspects.tux.nixos.programs.fish.enable = true;

If tux is on both igloo and iceberg, both hosts get fish enabled.

User includes work the same way:

den.aspects.tux.includes = [
({ host, ... }: {
nixos.users.users.tux.description = "Tux on ${host.name}";
})
];

Combine host and user context for precise control:

let
git-on-linux = { user, host, ... }:
if !lib.hasSuffix "darwin" host.system
then { homeManager.programs.git.enable = true; }
else { };
in {
den.aspects.tux.includes = [ git-on-linux ];
}

User tux gets git only on Linux hosts, not on Darwin.

graph TD
  HA["den.aspects.igloo (host)"] -->|"homeManager class"| U1["tux Home-Manager"]
  HA -->|"homeManager class"| U2["pingu Home-Manager"]
  UA["den.aspects.tux (user)"] -->|"nixos class"| H1["igloo NixOS"]
  UA -->|"nixos class"| H2["iceberg NixOS"]

Den’s context system handles the routing:

  • Host aspect configs flow to all users on that host
  • User aspect configs flow to all hosts with that user
  • Context functions get called with the specific { host, user } pair

Settings in den.default apply to everything — all hosts and all users:

den.default.homeManager.home.stateVersion = "25.11";
den.default.includes = [
({ host, ... }: { ${host.class}.networking.hostName = host.name; })
];