Skip to content

osConfig in home-manager

A home-manager module often needs its host’s NixOS config: { osConfig, pkgs, ... }:. In yen, osConfig is a sink. Each host gives its realized config to it, and a module names it like any sink arg. pkgs stays open, so home-manager fills its own pkgs.

modules/fleet.nix
# Hosts build NixOS. Users live under hosts; a standalone home lives under a host too, and builds its own config.
{
yen,
lib,
inputs,
...
}:
let
inherit (yen.lib) same is;
in
{
yen.kinds.fleet = {
spawns.host = _: yen.host;
sinks.out.reduce = yen.lib.reduce.merge;
};
yen.kinds.host = {
spawns = {
user = s: lib.filterAttrs (_: u: lib.any (same s) u.hosts) yen.user;
home = s: lib.filterAttrs (_: h: same h.on s) yen.home;
};
sinks.nixos.out =
{ host, nixos, ... }:
{
nixosConfigurations.${host.name} = inputs.nixpkgs.lib.nixosSystem { modules = nixos; };
};
sinks.osConfig.reduce = yen.lib.reduce.one; # the host's realized NixOS config
};
yen.kinds.user = {
fields.hosts = is lib.isList;
sinks.homeManager.nixos =
{ user, homeManager, ... }:
{
home-manager.users.${user.name}.imports = homeManager;
};
};
yen.kinds.home = {
fields = {
user = yen.kinds.user;
on = yen.kinds.host;
system = lib.types.str;
};
sinks.homeManager.out =
{ home, homeManager, ... }:
{
homeConfigurations.${home.name} = inputs.home-manager.lib.homeManagerConfiguration {
pkgs = inputs.nixpkgs.legacyPackages.${home.system};
modules = homeManager;
};
};
};
yen.aspects.home-manager = {
at = yen.lib.has yen.kinds.user;
nixos = {
imports = [ inputs.home-manager.nixosModules.home-manager ];
home-manager.useGlobalPkgs = true;
};
};
yen.aspects.os-config = {
at = yen.kinds.host;
osConfig = { host, out, ... }: out.nixosConfigurations.${host.name}.config; # lazy: read only when a module asks
};
yen.fleet.main = { };
yen.flake = { out, ... }: out;
}
  • The os-config aspect gives out.nixosConfigurations.<host>.config. It is lazy: Nix reads it only when a module asks.
  • A home has on, so it lives under that host. It reads the host’s sinks like any child, and still builds homeConfigurations.
modules/alice.nix
# alice: an account on the server, and a standalone home that lives under the server.
{ yen, ... }:
let
alice = yen.user.alice;
hers = [
alice
(s: s.kind == "home" && yen.lib.same s.user alice)
];
in
{
yen.user.alice.hosts = [ yen.host.server ];
yen.home."alice@server" = {
user = alice;
on = yen.host.server;
system = "x86_64-linux";
};
yen.aspects.alice-account = {
at = alice;
nixos.users.users.alice.isNormalUser = true;
};
yen.aspects.editors = {
at = hers; # one module, in NixOS and standalone
homeManager =
{ osConfig, pkgs, ... }: # osConfig: the host's sink; pkgs: home-manager's own
{
home.sessionVariables.EDITOR_HOST = osConfig.networking.hostName;
home.packages = [ pkgs.nano ];
home.stateVersion = "25.05";
};
};
yen.aspects.standalone = {
at = yen.kinds.home;
homeManager =
{ home, ... }:
{
home.username = home.user.name;
home.homeDirectory = "/home/${home.user.name}";
};
};
}

editors lands in two places: in the server’s NixOS (home-manager.users.alice) and in homeConfigurations."alice@server". Both read the same osConfig.

Terminal window
sudo nixos-rebuild switch --flake .#server
home-manager switch --flake '.#alice@server'
Contribute Community Sponsor