Platform batteries
Each platform is a kind you declare, with a sink that collects its modules. A battery turns the sink into the
flake output. The builders and pkgs are roles that read the scope, so each machine can use its own channel.
This fleet has a NixOS host with a guest, a mac, a phone and a standalone home:
# Four kinds of machine and standalone homes. Each kind's sink builds its output with a battery.{ yen, inputs, ...}:let b = yen.lib.batteries; pkgsOf = s: inputs.nixpkgs.legacyPackages.${s.system}; machine = { spawns.user = yen.lib.pointing "on" yen.user; };in{ yen.kinds.fleet = { spawns = { host = _: yen.host; mac = _: yen.mac; phone = _: yen.phone; home = _: yen.home; }; sinks.out.reduce = yen.lib.reduce.merge; }; yen.kinds.host = machine // { fields.system = yen.lib.str; spawns = machine.spawns // { guest = yen.lib.pointing "on" yen.guest; }; sinks.nixos.out = b.nixos.system { # (1) from = yen.kinds.host.sinks.nixos; inherit (inputs) nixpkgs; }; sinks.os.nixos = b.imports { from = yen.kinds.host.sinks.os; }; # (2) a user's home (os) into NixOS }; yen.kinds.guest = { fields = { on = yen.kinds.host; system = yen.lib.str; }; # a guest's NixOS goes into its host as microvm.vms.<guest> sinks.nixos.nixos = b.microvm.guest { # (3) from = yen.kinds.guest.sinks.nixos; pkgs = pkgsOf; }; }; yen.kinds.mac = machine // { fields.system = yen.lib.str; sinks.darwin.out = b.darwin.system { # (4) from = yen.kinds.mac.sinks.darwin; darwinSystem = _: inputs.nix-darwin.lib.darwinSystem; system = m: m.system; }; sinks.os.darwin = b.imports { from = yen.kinds.mac.sinks.os; }; }; yen.kinds.phone = { fields.system = yen.lib.str; sinks.droid.out = b.droid.system { # (5) from = yen.kinds.phone.sinks.droid; inherit (inputs.nix-on-droid.lib) nixOnDroidConfiguration; # nix-on-droid pins its own nixpkgs: newer nixpkgs dropped lib.mdDoc, which it still uses pkgs = s: import inputs.nix-on-droid.inputs.nixpkgs { inherit (s) system; }; }; sinks.homeManager.droid = b.droid.home { from = yen.kinds.phone.sinks.homeManager; }; # (6) }; yen.kinds.home = { fields = { user = yen.kinds.user; system = yen.lib.str; }; sinks.homeManager.out = b.home-manager.system { # (7) from = yen.kinds.home.sinks.homeManager; homeManagerConfiguration = _: inputs.home-manager.lib.homeManagerConfiguration; pkgs = pkgsOf; }; }; yen.kinds.user = { fields.on = yen.lib.listOf ( yen.lib.oneOf [ yen.kinds.host yen.kinds.mac ] ); # a user's home goes into the machine it is on sinks.homeManager.os = b.home-manager.into-host { from = yen.kinds.user.sinks.homeManager; }; # (8) }; yen.fleet.main = { }; yen.flake = { out, ... }: out;}(1)buildsnixosConfigurations.<name>from thenixossink of a host.(2)turns a sink of modules into one module. A user’s home goes into the NixOS host this way.(3)is a guest. Its NixOS config goes into its host asmicrovm.vms.<guest>.(4)buildsdarwinConfigurations.<name>.(5)buildsnixOnDroidConfigurations.<name>, and(6)gives the phone’s home-manager config to it.(7)buildshomeConfigurations.<name>for a standalone home.(8)gives a user’s home to the machine the user is on, ashome-manager.users.<user>.imports.
The machines, and the aspects that give them their configuration:
# One of each: a NixOS host with a guest, a mac, a phone, and a standalone home. ana is on the host and the mac.{ yen, inputs, ... }:let nixos = yen.lib.batteries.nixos; darwin = yen.lib.batteries.darwin;in{ yen.host.server.system = "x86_64-linux"; yen.guest.ci = { on = yen.host.server; system = "x86_64-linux"; }; yen.mac.studio.system = "aarch64-darwin"; yen.phone.pixel.system = "aarch64-linux"; yen.user.ana.on = [ yen.host.server yen.mac.studio ]; yen.home.ana-laptop = { user = yen.user.ana; system = "x86_64-linux"; };
yen.aspects.server = { at = yen.host.server; nixos = { imports = [ (yen.lib.batteries.home-manager.module inputs.home-manager.nixosModules.home-manager) # (1) useGlobalPkgs too inputs.microvm.nixosModules.host ]; boot.loader.grub.device = "nodev"; fileSystems."/" = { device = "/dev/sda1"; fsType = "ext4"; }; nixpkgs.hostPlatform = "x86_64-linux"; system.stateVersion = "25.05"; }; }; yen.aspects.hostname = { at = [ yen.kinds.host yen.kinds.guest ]; nixos = nixos.hostname; }; yen.aspects.guest = { at = yen.kinds.guest; nixos = { imports = [ inputs.microvm.nixosModules.microvm ]; system.stateVersion = "25.05"; }; }; yen.aspects.studio = { at = yen.mac.studio; darwin = { imports = [ inputs.home-manager.darwinModules.home-manager ]; system.stateVersion = 6; }; }; yen.aspects.mac-owner = { at = yen.mac.studio; darwin = darwin.primary-user { user = _: "ana"; }; # (2) }; yen.aspects.brew = { at = yen.mac.studio; brew.casks = [ "firefox" ]; }; yen.kinds.mac.sinks.brew.darwin = darwin.homebrew { from = yen.kinds.mac.sinks.brew; }; # (3) yen.aspects.pixel = { at = yen.phone.pixel; droid.system.stateVersion = "24.05"; homeManager = { home.stateVersion = "24.05"; programs.git.enable = true; }; }; # ana's accounts: a user has no nixos or darwin sink, so these go up to each machine she is on yen.aspects.accounts = { at = yen.kinds.user; nixos = nixos.define-user; darwin = { scope, ... }: { users.users.${scope.name}.home = "/Users/${scope.name}"; }; }; # ana's home: inside the host and the mac, and standalone on her laptop yen.aspects.ana-home = { at = [ yen.user.ana yen.home.ana-laptop ]; homeManager = { home.stateVersion = "25.05"; programs.git.enable = true; }; }; yen.aspects.standalone = { at = yen.kinds.home; homeManager = { home, ... }: { home.username = home.user.name; home.homeDirectory = "/home/${home.user.name}"; }; };}(1) is a battery too: it gives the NixOS host home-manager with the machine’s pkgs. (2) sets system.primaryUser on the mac.
(3) installs homebrew casks, brews and masApps from a sink.
The batteries
Section titled “The batteries”| Battery | Value of | Gives |
|---|---|---|
configurations { from; output; build; } |
out of any module sink |
<output>.<scope name> = build scope modules |
nixos.system { from; nixpkgs; } |
out of the NixOS sink |
nixosConfigurations.<name> |
darwin.system { from; darwinSystem; system; } |
out of the darwin sink |
darwinConfigurations.<name> |
darwin.primary-user { user ? ; }, darwin.homebrew { from; } |
darwin keys | system.primaryUser; homebrew from a sink of casks, brews, masApps |
home-manager.system { from; homeManagerConfiguration; pkgs; } |
out of a home’s sink |
homeConfigurations.<name> |
home-manager.into-host { from; } |
a user sink’s key that gives to the machine | home-manager.users.<user>.imports |
home-manager.module module |
a machine key | home-manager with the machine’s pkgs |
droid.system { from; nixOnDroidConfiguration; pkgs; }, droid.home { from; } |
phone sinks | nixOnDroidConfigurations.<name>, its home-manager config |
microvm.guest { from; pkgs; } |
a guest sink’s key that gives to the host | microvm.vms.<guest> of the host |
imports { from; } |
a sink’s key | the sink’s modules as one module |
configurations is the generic battery behind the platform builders. See Generic batteries.