Template: Example
The example template demonstrates Den’s advanced features: namespaces, angle brackets, cross-platform hosts, mutual providers, and custom aspect libraries.
Initialize
Section titled “Initialize”mkdir my-nix && cd my-nixnix flake init -t github:denful/den#examplenix flake update denProject Structure
Section titled “Project Structure”flake.nixmodules/ den.nix # host/home declarations dendritic.nix # flake-file + den wiring inputs.nix # flake inputs namespace.nix # creates the "eg" namespace nh.nix # exposes per-host/home build apps tests.nix # CI checks vm.nix # VM runner aspects/ defaults.nix # global config + angle brackets demo alice.nix # user aspect igloo.nix # host aspect eg/ # namespace aspects autologin.nix ci-no-boot.nix vm.nix vm-bootable.nix xfce-desktop.nixKey Features Demonstrated
Section titled “Key Features Demonstrated”Cross-Platform Hosts
Section titled “Cross-Platform Hosts”{ den.hosts.x86_64-linux.igloo.users.alice = { }; den.hosts.aarch64-darwin.apple.users.alice = { }; den.homes.x86_64-linux.alice = { };}One user (alice) across a NixOS host, a Darwin host, and a standalone Home-Manager config. The same aspects produce appropriate configs for each platform.
Namespaces
Section titled “Namespaces”{ inputs, den, ... }:{ imports = [ (inputs.den.namespace "eg" true) ]; _module.args.__findFile = den.lib.__findFile;}Creates a local namespace eg accessible as a module argument. The true flag exposes it as a flake output (flake.denful.eg). Angle brackets are enabled via __findFile.
Namespace Aspects
Section titled “Namespace Aspects”The eg/ directory defines reusable aspects under the eg namespace:
{ eg, ... }:{ eg.vm = { gui.includes = [ eg.vm eg.vm-bootable.gui eg.xfce-desktop ]; tui.includes = [ eg.vm eg.vm-bootable.tui ]; };}Aspects can have nested sub-aspects — eg.vm.gui and eg.vm.tui are children of eg.vm, selected by referencing them directly (e.g. eg.vm.gui in an includes list).
Angle Brackets
Section titled “Angle Brackets”{ config, __findFile ? __findFile, den, ... }:{ den.default.includes = [ <den/hostname> # resolves to den.batteries.hostname <den/define-user> # resolves to den.batteries.define-user # only on CI hosts: (if config ? _module.args.CI then <eg/ci-no-boot> else { }) ];}The <name> syntax is shorthand for aspect lookup. <den/define-user> resolves to the den.batteries.define-user battery; <eg/ci-no-boot> resolves to the ci-no-boot aspect in the eg namespace. See Angle Brackets.
Mutual Providers
Section titled “Mutual Providers”Hosts and users can contribute configuration to each other through aspect-included policies that emit den.lib.policy effects:
# modules/aspects/alice.nix — user delivers NixOS config TO the hostden.aspects.alice = { includes = [ den.aspects.alice.policies.to-igloo ]; policies.to-igloo = { host, user, ... }: lib.optional (host.name == "igloo") ( den.lib.policy.provide { class = "nixos"; module.programs.nh.enable = true; } );};
# modules/aspects/igloo.nix — host delivers Home-Manager config TO the userden.aspects.igloo = { includes = [ den.aspects.igloo.policies.to-alice ]; policies.to-alice = { host, user, ... }: lib.optional (user.name == "alice") ( den.lib.policy.include { homeManager.programs.tmux.enable = user.name == "alice"; } );};A policies.<name> entry is a context-aware function that fires once its argument signature (here { host, user, ... }) is satisfied by scope context. den.lib.policy.provide delivers a typed module into a named class on the other entity, while den.lib.policy.include pulls config into the current scope. Alice enables nh on igloo (NixOS), and igloo enables tmux for alice (Home-Manager).
# modules/tests.nix — verifies the template works{ checks."alice enabled igloo nh" = checkCond "alice.igloo" igloo.programs.nh.enable; checks."igloo enabled alice tmux" = checkCond "igloo.alice" alice-at-igloo.programs.tmux.enable;}Data Flow
Section titled “Data Flow”graph TD D["den.nix: igloo/apple + alice"] --> CH["host scope"] CH --> AI["aspects.igloo<br/>nixos + policies.to-alice"] CH --> CU["user scope"] CU --> AA["aspects.alice<br/>includes + policies.to-igloo"] AA -->|"policy.provide: nh"| AI AI -->|"policy.include: tmux"| AA CH --> HM["hm scope"] AI --> NixOS["nixosConfigurations.igloo"] AA --> NixOS AI --> Darwin["darwinConfigurations.apple"] AA --> Darwin
What It Provides
Section titled “What It Provides”| Feature | Provided |
|---|---|
| NixOS + Darwin hosts | ✓ |
| Home-Manager | ✓ |
| Standalone HM config | ✓ |
Namespaces (eg) | ✓ |
| Angle brackets | ✓ |
| Mutual providers | ✓ |
| VM testing | ✓ |
| CI checks | ✓ |
Next Steps
Section titled “Next Steps”- Study the
eg/namespace aspects as examples for your own libraries - Read Namespaces and Angle Brackets
- Explore the CI Tests template for comprehensive feature coverage