Skip to content

Project layout

yen reads one module. A module is a path, a function or an attrset with three keys: imports, _module.args and yen. yen does not know what inputs or lib are. You give them as args, and they flow down the imports tree to every file below.

  • default.nix
  • flake.nix
  • Directorymodules/
    • aspects.nix
    • fleet.nix
    • host.nix
  • query.nix

modules/ is the fleet. Every file there is a module: put each kind, feature or host in its own file, and move files freely. File order never changes a result.

flake.nix
{
description = "yen: flake and no-flake entry points";
outputs =
inputs:
inputs.yen.lib.mkFlake {
imports = [ (inputs.import-tree ./modules) ];
_module.args = {
inherit inputs;
inherit (inputs.nixpkgs) lib;
};
};
inputs = {
yen.url = "github:vic/yen";
import-tree.url = "github:denful/import-tree";
nixpkgs.url = "https://nixos.org/channels/nixos-25.05/nixexprs.tar.xz";
};
}

mkFlake gives the flake outputs. eval gives every query, flake included. Both read the same modules/.

query.nix
# Queries on the command line:
# nix eval --impure --file query.nix errors
# nix eval --impure --json --file query.nix agent
import ./default.nix { }
Terminal window
nix eval --impure --file query.nix errors # [ ] when the fleet is valid
nix eval --impure --file query.nix graph.scopes # every scope
nix build -f query.nix flake.nixosConfigurations.laptop.config.system.build.toplevel

nixpkgs.lib.nixosSystem exists only on the nixpkgs flake. nixos/lib/eval-config.nix works with a flake input and with a plain path, so one host file serves both entry points:

modules/host.nix
# eval-config.nix works with a flake input and with a plain nixpkgs path.
{
yen,
lib,
inputs,
...
}:
{
yen.kinds.host = {
fields.system = lib.types.str;
sinks.nixos.out =
{ host, nixos, ... }:
{
nixosConfigurations.${host.name} = import "${inputs.nixpkgs}/nixos/lib/eval-config.nix" {
inherit (host) system;
modules = nixos;
};
};
};
yen.host.laptop.system = "x86_64-linux";
}
Contribute Community Sponsor