Skip to content
/ dendrix Public

Commit 38f79df

Browse files
committed
more docs and mention flake-aspects
1 parent 9d879a9 commit 38f79df

File tree

1 file changed

+58
-18
lines changed

1 file changed

+58
-18
lines changed

dev/book/src/Dendritic.md

Lines changed: 58 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,41 @@
55
We say that Dendritic nix configurations are _aspect-oriented_, meaning that each nix file
66
provides config-values for the same _aspect_ across different nix configuration classes.
77

8-
This is done via flake-parts' `flake.modules.<class>.<aspect>` options.
8+
Normally, this is done via flake-parts' `flake.modules.<class>.<aspect>` options.
99

1010
Where `<class>` is a type of configuration, like [`nixos`](https://nixos.org/manual/nixos/stable/options), [`darwin`](https://nix-darwin.github.io/nix-darwin/manual/), [`homeManager`](https://home-manager.dev/manual/23.11/options.xhtml), [`nixvim`](https://nix-community.github.io/nixvim/search/), etc.
1111

1212
And `<aspect>` is the _cross-cutting concern_ or _feature_ that is being configured across
1313
one or more of these classes.
1414

15+
> [!NOTE]
16+
> Dendritic is a configuration *pattern* - a way-of-doing-. Not a library nor a framework.
17+
> See [No Dependencies](#no-dependencies).
18+
1519
### Example of a dendritic configuration.
1620

1721
As an example of what a dendritic nix config looks like, suppose we want to configure ssh facilities
1822
(the `ssh` aspect) across our NixOS, Nix-darwin hosts and user homes.
1923

2024
```nix
2125
# modules/ssh.nix -- like every other file inside modules, this is a flake-parts module.
22-
{ config, ... }: {
26+
{ inputs, config, ... }: let
27+
scpPort = 2277; # let-bindings or custom flake-parts options communicate values across classes
28+
in {
2329
flake.modules.nixos.ssh = {
24-
# Linux config: server, firewall-ports, etc.
30+
# Linux config: setup OpenSSH server, firewall-ports, etc.
2531
};
2632
2733
flake.modules.darwin.ssh = {
28-
# MacOS config: enable builtin ssh server, etc.
34+
# MacOS config: enable MacOS builtin ssh server, etc.
2935
};
3036
3137
flake.modules.homeManager.ssh = {
32-
# setup ~/.ssh/config or keys.
38+
# setup ~/.ssh/config, authorized_keys, private keys secrets, etc.
3339
};
3440
3541
perSystem = {pkgs, ...}: {
36-
# expose custom package/checks/devshells by this aspect.
42+
# custom packages taking advantage of ssh facilities, eg deployment-scripts.
3743
};
3844
}
3945
```
@@ -62,7 +68,7 @@ in
6268
};
6369
6470
flake.modules.darwin.${userName} = {
65-
system.primaryUser = userName; # configuring a user is different on MacOS than on NixOS.
71+
system.primaryUser = userName; # note that configuring a user is different on MacOS than on NixOS.
6672
};
6773
6874
flake.modules.homeManager.${userName} =
@@ -100,7 +106,7 @@ All files being flake-parts modules, means we have no need for manually importin
100106
loaded at once into a single import.
101107

102108
The Dendritic community commonly uses [`vic/import-tree`](https://github.com/vic/import-tree) for this.
103-
Note: import-tree ignores any file that has an `_` anywhere as part of its path.
109+
Note: import-tree ignores any file that has an `/_` as part of its path.
104110

105111
```nix
106112
# flake.nix
@@ -123,9 +129,9 @@ This means we can have:
123129
Instead of having huge `flake.nix` files with lots of nix logic inside. It is now possible
124130
to move all nix logic into well organized auto-imported flake-parts in `./modules`. This way, `flake.nix` serves more as a manifest of dependencies and flake entrypoint.
125131

126-
Some people go a step further and use [vic/flake-file](https://github.com/vic/flake-file) to manage their flake.nix automatically, by letting each flake-part module also define the flake inputs needed by each module.
132+
Some people go a step further and use [`vic/flake-file`](https://github.com/vic/flake-file) to manage their flake.nix automatically, by letting each flake-parts module also define the flake inputs needed by each module.
127133

128-
Any flake-parts module can contribute to flake.nix as needed, either inputs/flake-configuration (by using `vic/flake-file`) or outputs (modules/packages/checks/osConfigurations/etc).
134+
Any flake-parts module contributes to flake.nix as needed, either inputs/flake-configuration (by using `vic/flake-file`) or outputs (modules/packages/checks/osConfigurations/etc by using flake-parts options).
129135

130136
```nix
131137
# ./modules/home/vim.nix
@@ -140,15 +146,17 @@ Any flake-parts module can contribute to flake.nix as needed, either inputs/flak
140146

141147
### Feature Centric instead of Host Centric.
142148

143-
As noted by Pol Dellaiera in [Flipping the Configuration Matrix](https://not-a-number.io/2025/refactoring-my-infrastructure-as-code-configurations/#flipping-the-configuration-matrix):
149+
As noted by Pol Dellaiera in [Flipping the Configuration Matrix](https://not-a-number.io/2025/refactoring-my-infrastructure-as-code-configurations/#flipping-the-configuration-matrix) -a very recommended read-:
144150

145-
> the configuration is now structured around features, not hostnames. It is a shift in the axis of composition, essentially an inversion of configuration control. What may seem like a subtle change at first has profound implications for flexibility, reuse, and maintainability.
151+
> [In a Dendritic setup] the configuration is now structured around features, not hostnames. It is a shift in the axis of composition, essentially an inversion of configuration control. What may seem like a subtle change at first has profound implications for flexibility, reuse, and maintainability.
146152
147153
You will notice that you start naming your files around the `aspect`s (features) they define
148154
instead of where they are specifically applied.
149155

156+
It might be useful to ask yourself **_how_** you like to use your Linux Environment, instead of **_what_** components constitute the environment or **_where_** will the environment finally applied. By doing so, you will start naming your aspects around "usability concerns", eg. `macos-like-bindings`, `scrolling-desktop`, `tui` interfaces, nextgen `cli` utilities, `ai` intergation, etc. Instead of naming modules around specific packages or host-names.
157+
150158
In the following example, the `scrolling-desktop` aspect is included accross different operating systems:
151-
On Linux, `flake.modules.nixos.scrolling-destop` might enable [`niri`](https://variety4me.github.io/niri_docs/) and on MacOS, `flake.modules.darwin.scrolling-desktop` might enable [`PaperWM.spoon`](https://github.com/mogenson/PaperWM.spoon).
159+
On Linux, `flake.modules.nixos.scrolling-desktop` might enable [`niri`](https://variety4me.github.io/niri_docs/) and on MacOS, `flake.modules.darwin.scrolling-desktop` might enable [`paneru`](https://github.com/karinushka/paneru). Each configuration uses the tools available on the respective platform, but the aspect is the same, and you could use flake-parts level options or let-bindings to configure behaviour on both (e.g, the scrolling animations speed).
152160

153161
```nix
154162
# ./modules/hosts.nix
@@ -165,6 +173,8 @@ On Linux, `flake.modules.nixos.scrolling-destop` might enable [`niri`](https://v
165173
}
166174
```
167175

176+
177+
168178
### Feature _Closures_
169179

170180
By closure, we mean: everything that is needed for a given _feature_ to work is
@@ -191,12 +201,42 @@ other impact than the overall capabilities provided into your systems.
191201
This is an easy way to disable loading files while on a huge refactor. Or when some hosts
192202
or features should be decommissioned immediately/temporarily.
193203

194-
### No dependencies other than flake-parts
204+
### No dependencies
205+
206+
> _Dendritic_ is a configuration *pattern* - a _way-of-doing_-, not a library nor a framework.
207+
208+
The Dendritic repository has no code at all and any libraries mentioned on this document are mere recommendations and pointers to things other people using the Dendritic pattern has found useful.
195209

196-
Since the dendritic pattern builds around flake-parts modules, the only dependency is
197-
`flake-parts`. You can load files using import-tree or any other means. You can also use
198-
any flake-parts based library to define your configurations, like [Unify](https://codeberg.org/quasigod/unify),
199-
as long as it exposes `flake.modules.<class>.<aspect>` attribute sets.
210+
You are free and encouraged to explore new ways of doing or wiring Dendritic setups. Be sure to share your insights with the community.
211+
212+
Because all of this, there are many possible implementations of the Dendritic pattern.
213+
214+
Some people like to use inline-style definitions:
215+
216+
```nix
217+
{ inputs, ... }:
218+
{
219+
flake.modules.<class1>.<aspect1> = { ... };
220+
flake.modules.<class2>.<aspect1> = { ... };
221+
flake.modules.<class3>.<aspect1> = { ... };
222+
}
223+
```
224+
225+
Others might prefer nested modules using libs like [unify](https://codeberg.org/quasigod/unify) or [`vic/flake-aspects`](https://github.com/vic/flake-aspects):
226+
227+
All is good as long as you expose `flake.modules.<class>.<aspect>` attribute sets.
228+
229+
```nix
230+
# using vic/flake-aspects:
231+
{ inputs, ... }:
232+
{
233+
flake.aspects.<aspect1> = {
234+
<class1> = { ... };
235+
<class2> = { ... };
236+
<class3> = { ... };
237+
};
238+
}
239+
```
200240

201241
### Dendritic community.
202242

0 commit comments

Comments
 (0)