Skip to content

Use Batteries

import { Aside } from ‘@astrojs/starlight/components’;

Batteries are pre-built aspects shipped with Den. They are opt-in — you explicitly include them where needed. They are replaceable — you can write your own alternative.

Access batteries via den._. (shorthand for den.provides.).

Defines a user at both OS and Home-Manager levels:

den.default.includes = [ den._.define-user ];

Sets users.users.<name>, home.username, and home.homeDirectory automatically for NixOS, Darwin, and standalone Home-Manager.

Makes a user an administrator:

den.aspects.vic.includes = [ den._.primary-user ];

On NixOS: adds wheel and networkmanager groups. On Darwin: sets system.primaryUser. On WSL: sets wsl.defaultUser if host has a wsl attribute.

Sets a user’s default shell at OS and HM levels:

den.aspects.vic.includes = [ (den._.user-shell "fish") ];

Enables the shell program on both NixOS/Darwin and Home-Manager, and sets it as the user’s default shell.

Enables unfree packages by name:

den.aspects.my-laptop.includes = [ (den._.unfree [ "discord" "slack" ]) ];

Works for any class — NixOS, Darwin, Home-Manager.

Enables automatic tty login for a given username:

den.aspects.my-laptop.includes = [ (den._.tty-autologin "root") ];

Recursively imports non-dendritic Nix files by class:

den.ctx.host.includes = [ (den._.import-tree._.host ./hosts) ];
den.ctx.user.includes = [ (den._.import-tree._.user ./users) ];

Given a directory structure like ./hosts/my-laptop/_nixos/, it auto-imports files under the matching class directory. Useful for migration.

Provide per-system inputs' and self' to NixOS/HM modules:

den.default.includes = [ den._.inputs' den._.self' ];
den.aspects.igloo.nixos = { inputs', ... }: {
environment.systemPackages = [ inputs'.nixpkgs.legacyPackages.hello ];
};

Create custom Nix classes that forward configs into target submodules:

den.aspects.igloo.includes = [
({ class, aspect-chain }:
den._.forward {
each = lib.singleton class;
fromClass = _: "custom";
intoClass = _: "nixos";
intoPath = _: [ ];
fromAspect = _: lib.head aspect-chain;
})
];

This is how Home-Manager integration is implemented internally.

Any aspect can serve as a battery. Publish it in a namespace for others:

{ den, ... }: {
den.provides.my-battery = den.lib.parametric {
includes = [
({ host, ... }: { nixos.my-setting = host.name; })
];
};
}