From Zero to Den
Step 1. A Den-dritic layout
Section titled “Step 1. A Den-dritic layout”Our first step is creating a directory layout for your Den.
mkdir ./modules # Dendritic modules directorycp -r /etc/nixos ./modules/_nixos # OPTIONAL existing NixOS modules-
All your Dendritic Nix modules will be loaded by
import-treeautomatically from./modules -
(optional) Copy your existing NixOS modules into
modules/_nixos.The
_is important for import-tree to ignore and NOT auto-load_nixos/configuration.nixnor_nixos/hardware-configuration.nixsince they are regular NixOS modules and not Dendritic ones.
Step 2. Pinning Den and dependencies
Section titled “Step 2. Pinning Den and dependencies”This step will use npins to fetch and lock some dependencies that
will integrate all together:
npins init # adds nixpkgs channelnpins add github vic import-tree # for auto-importing ./modulesnpins add github vic flake-aspects # aspects used by Dennpins add github vic den # Den itself, of coursenpins add github vic with-inputs # flake-like inputs without Nix flakes.npins add github nix-community home-manager # OPTIONAL home integrationStep 3. Your Den Entry Point
Section titled “Step 3. Your Den Entry Point”Lets create default.nix. This file will serve as the entrypoint to all your configuration. Once you have default.nix you will very rarely need to touch it again.
let sources = import ./npins; # (1) with-inputs = sources.with-inputs sources { }; # (2) outputs = inputs: (inputs.nixpkgs.lib.evalModules { # (3) modules = [ (inputs.import-tree ./modules) ]; # (4) specialArgs.inputs = inputs; # (5) }).config.flake; # (6)inwith-inputs outputs; # (7)A tiny file, but a lof of things happening on it:
-
Import fetched and already locked dependencies using
npins. -
Flake like input follows and overrides via with-inputs.
This ensures full compatibility between flakes and non-flakes worlds. You can share and re-use Dendritic modules from other people independently if they use flakes or not. Also in case you later move into flakes, nothing in your modules changes, just the entrypoint.
-
Merges all imported modules into an actual unified config.
-
Single usage of import-tree to load all modules recursively.
-
Provide
{ inputs, ... }special argument to all modules. -
Read from Den’s
flakeoutput wherenixosConfigurationsare placed for compatibility between flakes and non-flakes environments. -
Invokes
outputwith resolvedinputs.
Step 4. Host configuration in Den
Section titled “Step 4. Host configuration in Den”{ inputs, den, lib, ... }: { imports = [ inputs.den.flakeModule ]; # (1)
den.schema.user.classes = lib.mkDefault [ "homeManager" ]; # (2)
den.hosts.x86_64-linux.igloo.users.tux = {}; # (3) (4)
den.aspects.igloo = { # (5) includes = [ den.provides.hostname ]; # (6) nixos = { pkgs, ... }: { imports = [ ./_nixos/configuration.nix ]; # (7) environment.systemPackages = [ pkgs.hello ]; }; };
den.aspects.tux = { # (8) includes = [ den.provides.define-user den.provides.primary-user ]; # (9) homeManager = { pkgs, ... }: { packages = [ pkgs.vim ]; }; };}This is all that is happening at modules/den.nix.
-
Imports
den-framework features into the module system.This provides the
denmodule argument as well as allden.*options,nixosConfigurationsoutputs. -
(optional, if you added home-manager dependency). This example shows how to enable
homeManagerintegration for all users by default.Den supports multiple home environments, that is why none of them is enabled by default in Den. Freedom of choice is important, same as with flakes.
Home Integration is a User concern, so it is configured at each independent
<user>.classesorden.schema.userfor all of them. See User Declaration and Homes Integration for more. -
Host definitions go inside
den.hosts.This single line defines a host with hostName
igloo, platformx86_64-linuxfrom whichclass = "nixos"is derived, and a single usertuxin it. See Declare Hosts & Users for more.Den automatically creates an aspect for each host that looks like this:
den.aspects.igloo = parametric {nixos = {};};parametricmeans that this aspect is able to pass its context (the{host}definition forigloointo other aspects being included in it. See Parametric Aspects for more this. -
User definitions inside host.
Hosts can have zero or more users. This example shows only one:
tux.Each user can define its own configuration via freeform attributes, or define values for options from
den.schema.user, likeclasses. See Schema Reference for more.den.hosts.x86_64-linux.igloo.users = {tux = {likes = [ "fishes"; ];classes = [ "homeManager" "hjem" ];};pingu = {likes = [ "music" ];classes = [ "maid" ];};};Just like hosts, users also get an aspect automatically created by Den from their definition:
den.aspects.tux = parametric {homeManager = {};hjem = {};};den.aspects.pingu = parametric {maid = {};}; -
Enhance the
igloohost aspect.Remember that
den.aspects.igloowas already created for you by Den from the host definition?. Well, in this step you are extending the aspect with more configuration. Any file can do this, contribute to any host or user aspect as they please. This is called Incremental Features in the Dendritic Advantages article. -
Include re-usable features from other, generic aspects.
One of the advantages of
flake-aspects’ upon which Den is built is automatic inclusion of other aspects. Unlike NixOS.imports,.includesare safe to use with conditionals because includes are not files to be imported.Den exploits flake-aspects by using contexts. A context like
{host}is simply an attribute set that holds theigloohost definition from our examples. These are arguments to real Nix functions, NOT_module.argsnorspecialArgs. This is why these values can be used for conditional includes.Den provides some common batteries. Re-usable aspects like
den.provides.hostnamewhich is defined like this:den.provides.hostname = { host, ... }: { # host = igloo definitionnixos.networking.hostName = host.hostName; # value from Host Schema}; -
optional if you copied
/etc/nixosintomodules/_nixos) Import Non-Dendritic NixOS modules.The
nixosattribute value is just a regular NixOS module. Because of this, it can import your previous./_nixos/configuration.nixmodule or any other NixOS module from Nix libraries. -
Enhance the User aspect.
As with the host aspect, Den also automatically created a user aspect. Here, you are extending it with more configuration.
-
Include re-usable
{host, user}batteries.Batteries like
den.provides.primary-usertake the{host, user}context wherehostis theigloodefinition anduseris thetuxdefinition.These batteries also serve as example for you to create custom re-usable pieces of configuration shareable on several user/hosts or shared with the community.
Phew, lots of things we’ve learned! Our single and final step is
Step 5. Building your NixOS configuration
Section titled “Step 5. Building your NixOS configuration”nixos-rebuild --file . -A nixosConfigurations.iglooNext Steps
Section titled “Next Steps”You can now head over to other guides or the reference: