den turns Nix configuration into features rather than host modules
Aspect-oriented, context-driven Nix configurations.
At a glance
- What is it?
- den is a Nix configuration library that treats a feature as a function of context: give it your hosts and users and it returns configuration for every Nix class it touches, from nixos to darwin to homeManager. It removes the mkIf and enable clutter of host-first setups, works with or without flakes, and has no dependencies of its own.
- Who is it for?
- den fits a user with several hosts and users who keeps writing the same feature into three separate module files and wants one definition instead, and it does not fit a single-host user whose configuration is already small, because the context model, policies, quirks and custom classes have to be learned before the first feature pays off.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Nix, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A feature as a function of context
The pitch in the README is one line: write a feature once, run it on every host, user and platform you have, and share it with anyone, flake or not. The mechanism is that a Den aspect is a plain function. You give it context, namely your hosts and users, and it returns configuration for every Nix class it touches: nixos, darwin, homeManager, hjem, or a class you invent yourself.
The README shows the shape of one such aspect:
den.aspects.gaming = { host, user }: {
nixos = { pkgs, ... }: { programs.steam.enable = true; };
darwin = { pkgs, ... }: { /* ... */ };
homeManager = { pkgs, ... }: { /* ... */ };Each key is a Nix class and each value is a module function, so one aspect fans out across operating systems and home manager configurations. The two lines after that block show the composition rules: an includes list pulls in other aspects, and an emulation key nests configuration for a specific class, in this case nixos, inside the aspect.
The README names this single idea, a feature as a function, as the thing that makes the rest possible. Everything else in the library is a consequence of it: because the aspect is a function, it can be handed context, and because it returns configuration for many classes, one definition covers a whole fleet.
Four concepts, and each one has a single job
The principles section lists four concepts, and the discipline of the design is that each does exactly one thing.
An entity is what exists: a host, a user, or a home. An aspect is what it does, meaning a feature that spans Nix classes. A policy is how entities relate to each other, described as topology and routing between them. A quirk is structured data that aspects share, without coupling.
The separation of quirks from aspects is the part that decides whether the library scales. If a piece of data had to live inside the function that uses it, sharing it across aspects would mean nesting them, and nesting leads to coupling. By pulling that data out into a named quirk, several aspects can read the same values and still stay independent of each other.
The second principle is that Den is feature-first rather than host-first. Traditional setups start from hosts and push modules down, and Den flips that: features are primary and hosts simply select the ones they want. The README puts the consequence plainly. Add a capability in one line, remove it by deleting that line. There is no enablement flag to hunt for and no other host to edit, because the host list is a set of selections.
A third principle is stated as compatibility. Den embraces your Nix, working with or without flakes, flake-parts or home-manager, and every part is optional and replaceable.
Conditions disappear because the context is the condition
The claim the README makes most forcefully is about conditionals. Traditional Nix setups accumulate mkIf and enable clauses, because a module has to be told when to apply. In Den, the shape of the context is the condition, and the example given is that a function asking for a user simply does not run where there is no user.
That is a real property of writing a function rather than a module. A module with a parameter has to check whether the caller passed it. A function parameter is either bound or the call is not made at all, so the check is unnecessary. The mkIf wrappers disappear because the conditional was already expressed by the call site.
The second claim in the same list is bidirectional: hosts shape their users and users shape their hosts. Cross-entity configuration flows both ways without coupling the two together. In a conventional setup, a user module that wants to know something about the machine it lands on has to be handed that information explicitly, usually through a global option that the host module must set. With entities as context, the flow is already there.
The third claim is about reuse. An aspect can be shared between machines, between people, and between flake and non-flake setups, without forcing everyone to download each other's inputs. That last part matters for teams: sharing a feature should not mean sharing a dependency graph, so a shared aspect is a piece of code you can copy in or pull in, rather than an input every consumer has to resolve.
Custom classes and pipelines are the extension point
The README lists among the things Den makes possible the ability to bring your own classes and whole pipelines. Custom Nix classes, machine fleets, MicroVM guests, terranix, standalone neovim: if you can walk it as data, the claim is that Den can configure it.
That claim rests on the class being a key in the returned attribute set, so nothing in the design limits you to the three built-in classes. The tutorial list backs this up with templates for third-party per-system classes and for a standalone neovim setup that needs neither NixOS nor Darwin.
The companion idea is that hosts just select aspects. If aspects are the unit of definition and hosts are a list of selections, then adding a machine to a fleet means adding a selection, and the feature itself does not change.
Two projects in the repository are worth noting for the scope of the ambition. There is a checkmate/ directory at the top level of the repository, alongside modules/, nix/, templates/, docs/, a default.nix, a shell.nix, a flake.nix and a Justfile. And there are agent instruction files, AGENTS.md and CLAUDE.md, along with a .agents/ and a .claude/ directory, which tells you that the project expects its contributors and its automated tools to read a written description of how the repository works.
One naming note is worth repeating because it will confuse anyone arriving from the older pattern. The README says Den no longer relates to the Dendritic name. Den was born to explore the limits of that pattern and has evolved into something the official dendritic repository no longer considers Dendritic. If you have read about the dendritic pattern, that framing is out of date.
Templates and one-command experiments
The README offers a way to see the library working before you commit to it, using nix run against templates that live in the repository.
nix run github:denful/den?dir=templates/microvm#runnable-microvmnix run github:denful/den?dir=templates/nvf-standalone#my-neovimThe same form without a template runs the qemu VM entry point. The dir parameter selects a template directory in the repository and the fragment after the hash selects an app inside it, so these are runnable artefacts rather than documentation examples.
For adopting it into your own setup, the template list is the catalogue. The default template is a flake file with flake-parts and home-manager. The minimal template is flakes and nothing else. The noflake template uses npins with lib.evalModules and nix-maid, which is the route for people who want Den without flakes. There are templates for a standalone neovim app, a runnable VM with declarative guests, third-party perSystem classes through flake-parts, and a cross-platform example.
Choosing between default, minimal and noflake is the first decision, and it is the one the docs push hardest: the From Zero to Den and From Flake to Den guides sit at the top of the documentation list, followed by Core Principles.
For running Den on real configurations, the guides cover custom Nix classes, home-manager integration, batteries, mutual providers, sharing namespaces and angle bracket syntax, plus a tutorial on tests as code examples. The project site also carries pages on motivation, versioning, community and contributing.
Maintenance, licensing and the shape of the repository
The project is Apache-2.0 licensed, and it moves on a regular release rhythm. The published versions are v0.19.0 on 2026-09-24, v0.18.0 on 2026-06-23 and v0.17.0 on 2026-05-21, with the last push on 2026-10-20. The README does not present the project as stable software with a compatibility promise, and the documentation has a dedicated versioning page under Project, which is where the compatibility story lives.
The repository itself is worth reading for what it reveals about how the project is worked on. Beyond the standard flake.nix, default.nix and shell.nix, there is a Justfile for task running, a ci.bash script, an .agents/ directory, an AGENTS.md, a CLAUDE.md and a .tangled/ directory, which points to the Tangled hosting model for the ecosystem around it.
The README also records adoption, which is the kind of claim that is easy to skip and awkward to check. It lists four public configurations built with Den, including one by the author that shares a fleet configuration, and it says Den is also running on internal infrastructure at The European Commission. There is also a usage search link for code that references den.aspects.
For a library that others build their operating system configuration on, the licensing choice is the safest of the common ones. Apache-2.0 permits use and modification, including inside proprietary products, which matters when the configuration itself is a company asset rather than a personal dotfiles repository.
Where den is the wrong choice
Three situations argue against it.
The first is a single host with a small configuration. The entire value of the aspect model comes from having the same feature apply to more than one host or user. With one machine and a handful of options, the standard home-manager module pattern is fewer concepts, and the README itself is honest that a feature-first design is a different way of thinking rather than a strictly better one.
The second is a team that does not want to change how its configuration is written. Den works with what you have, with zero dependencies and every part optional and replaceable, but adopting it still means rewriting features as functions of context. For a large existing configuration, that is a migration with a payoff that arrives only after the new shape is in place, and the README provides templates but no automated conversion.
The third is a requirement for stability that the project does not promise. This is a library whose output changes your entire machine configuration, the versions move every few months, and the README highlights that Den has moved away from the pattern it was named after, which tells you the design is still moving. If your risk appetite for your operating system configuration is low, pin a version and read the versioning notes before adopting.
None of these are reasons to avoid it if you have the multi-host problem it addresses. They are reasons to start with one aspect rather than migrating everything at once, and to keep the old configuration working until the new one has proved itself on a test host.
Editorial conclusion
den fits a user with several hosts and users who keeps writing the same feature into three separate module files and wants one definition instead, and it does not fit a single-host user whose configuration is already small, because the context model, policies, quirks and custom classes have to be learned before the first feature pays off. Before adopting it, read the core principles page and pick one template, since the default, minimal and noflake templates make very different demands, and confirm that your existing flake-parts or home-manager setup can be expressed as Den classes. The project is Apache-2.0 licensed, version v0.19.0 was released on 2026-09-24, and the last push was on 2026-10-20.
Frequently asked questions
What is den and what problem does it solve?
den is a Nix configuration library described as aspect-oriented and context-driven. An aspect is a plain function that takes context, your hosts and users, and returns configuration for every Nix class it touches, so one feature definition covers nixos, darwin and homeManager instead of being copied into separate files.
Do I need flakes to use den?
No. The README states that Den works with or without flakes, flake-parts or home-manager, and every part is optional and replaceable. The noflake template is described as npins with lib.evalModules and nix-maid, and there are separate templates for flakes only and for the full flake, flake-parts and home-manager setup.
How do den aspects compose with each other?
An aspect can list other aspects in an includes entry, and it can nest configuration for a specific class with the emulation key, shown in the README with a nixos example. The README describes the two lines as aspects compose and nest.
Is den related to the Dendritic pattern?
The README says Den no longer relates to the Dendritic name. Den was born to explore the limits of that pattern and has evolved into something more advanced and flexible, and the official dendritic repository no longer considers it Dendritic.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/denful-den)Was this useful?