Skip to content

Dendritic Pattern

The Dendritic pattern is a convention where each file is a self-contained Nix module. Rather than large monolithic files, your configuration becomes a directory tree where each concern lives in its own file.

modules/
networking.nix # network config
openssh.nix # SSH server
desktop/
sway.nix # window manager
waybar.nix # status bar
notifications.nix # notification daemon
users/
alice.nix # user account

Each file is a standard Nix module:

modules/openssh.nix
{ ... }: {
services.openssh.enable = true;
services.openssh.settings.PasswordAuthentication = false;
}
  • Locality — each concern in its own file, easy to find and modify
  • Composability — add or remove features by adding or removing files
  • No boilerplateimport-tree handles the wiring
  • Git-friendly — file additions don’t cause merge conflicts in import lists
  • Discoverable — directory structure documents the system

With flake-parts, each file is a flake-parts module:

flake.nix
{
inputs.import-tree.url = "github:vic/import-tree";
inputs.flake-parts.url = "github:hercules-ci/flake-parts";
outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; }
(inputs.import-tree ./modules);
}
modules/dev-shell.nix
{ inputs, ... }: {
perSystem = { pkgs, ... }: {
devShells.default = pkgs.mkShell {
packages = [ pkgs.nil pkgs.nixfmt-rfc-style ];
};
};
}

Files under /_ prefixed paths are ignored by default. This gives you a place for shared utilities:

modules/
feature.nix
_lib/
helpers.nix # not auto-imported
modules/feature.nix
let helpers = import ./_lib/helpers.nix;
in { ... }: { /* use helpers */ }
Contribute Community Sponsor