me like nix
0

Configure Feed

Select the types of activity you want to include in your feed.

at main 172 lines 5.0 kB View raw View rendered
1--- 2name: dendritic-nix 3description: Use when the user asks about or wants to implement the "dendritic nix pattern", aspect-oriented Nix configuration, organizing Nix config by feature/aspect instead of hostname, or migrating to flake-parts modules. Also applies when discussing cross-platform Nix configs (NixOS + Darwin + Home Manager) in a single file. 4version: 1.0.0 5--- 6 7# Dendritic Nix Pattern 8 9The dendritic pattern is an **aspect-oriented** approach to Nix configuration built on [flake-parts](https://flake.parts). Each `.nix` file provides configuration for the same **aspect** (feature/concern) across different configuration classes (NixOS, Darwin, Home Manager, etc.). 10 11It is a configuration **pattern** — not a library or framework. 12 13## Core Principle 14 15Instead of organizing by host (`hosts/mira/default.nix`, `hosts/framework16/default.nix`), organize by **feature**. A single file like `modules/ssh.nix` contains the NixOS, Darwin, and Home Manager config for SSH all in one place. 16 17## File Structure 18 19- No mandatory directory structure 20- Every `.nix` file is a **flake-parts module** — uniform semantics 21- Files are auto-loaded (e.g., via `vic/import-tree`) 22- Files with `/_` in their path are ignored by convention 23 24``` 25modules/ 26├── ssh.nix # SSH config across all platforms 27├── vim.nix # Editor config across all platforms 28├── vic.nix # User "vic" across all platforms 29└── desktop/ 30 ├── basic.nix # Basic desktop features 31 └── advanced.nix # Advanced desktop features (incremental) 32``` 33 34## Module Pattern 35 36Each file is a flake-parts module that defines config for multiple configuration classes: 37 38```nix 39{ inputs, config, ... }: let 40 # Shared values — replaces specialArgs 41 sharedPort = 2277; 42in { 43 flake.modules.nixos.aspect-name = { 44 # NixOS system configuration 45 }; 46 47 flake.modules.darwin.aspect-name = { 48 # macOS system configuration 49 }; 50 51 flake.modules.homeManager.aspect-name = { 52 # Home Manager user configuration 53 }; 54 55 perSystem = { pkgs, ... }: { 56 # Per-system packages, devShells, etc. 57 }; 58} 59``` 60 61## Complete Example: SSH 62 63```nix 64# modules/ssh.nix 65{ inputs, config, ... }: let 66 scpPort = 2277; 67in { 68 flake.modules.nixos.ssh = { 69 services.openssh = { 70 enable = true; 71 ports = [ scpPort ]; 72 }; 73 networking.firewall.allowedTCPPorts = [ scpPort ]; 74 }; 75 76 flake.modules.darwin.ssh = { 77 # macOS built-in SSH server config 78 }; 79 80 flake.modules.homeManager.ssh = { 81 # ~/.ssh/config, authorized_keys, etc. 82 }; 83 84 perSystem = { pkgs, ... }: { 85 # Custom packages using SSH facilities 86 }; 87} 88``` 89 90## User Definition Example 91 92```nix 93# modules/vic.nix 94let 95 userName = "vic"; 96in { 97 flake.modules.nixos.${userName} = { 98 users.users.${userName} = { 99 isNormalUser = true; 100 extraGroups = [ "wheel" ]; 101 }; 102 }; 103 104 flake.modules.darwin.${userName} = { 105 system.primaryUser = userName; 106 }; 107 108 flake.modules.homeManager.${userName} = { pkgs, lib, ... }: { 109 home.username = lib.mkDefault userName; 110 home.homeDirectory = lib.mkDefault ( 111 if pkgs.stdenvNoCC.isDarwin 112 then "/Users/${userName}" 113 else "/home/${userName}" 114 ); 115 home.stateVersion = lib.mkDefault "25.05"; 116 }; 117} 118``` 119 120## Minimal flake.nix 121 122```nix 123{ 124 inputs = { 125 flake-parts.url = "github:hercules-ci/flake-parts"; 126 import-tree.url = "github:vic/import-tree"; 127 # other inputs... 128 }; 129 outputs = inputs: 130 inputs.flake-parts.lib.mkFlake { inherit inputs; } 131 (inputs.import-tree ./modules); 132} 133``` 134 135## Dynamic Inputs (Optional) 136 137With `vic/flake-file`, inputs can be declared per-module: 138 139```nix 140# modules/home/vim.nix 141{ inputs, ... }: { 142 flake-file.inputs.nixvim.url = "github:nix-community/nixvim"; 143 flake.modules.homeManager.vim = { 144 # config using inputs.nixvim 145 }; 146} 147``` 148 149## Key Advantages 150 1511. **Feature closures**: Everything needed for a feature lives in one file 1522. **No specialArgs**: Shared values use `let` bindings and flake-parts options 1533. **Uniform file semantics**: Every `.nix` file is a flake-parts module 1544. **Incremental features**: Add `feature/basic.nix` and `feature/advanced.nix` independently 1555. **Cross-platform**: NixOS, Darwin, and Home Manager config coexist naturally 156 157## Configuration Classes 158 159Common classes used in `flake.modules.<class>`: 160- `nixos` — NixOS system config 161- `darwin` — macOS system config 162- `homeManager` — Home Manager user config 163- `nixvim` — Editor config 164- Custom classes as needed 165 166## When Helping Users 167 168- When migrating an existing config: map each "feature" (SSH, users, desktop, etc.) to its own flake-parts module file 169- Each module should define config for all relevant classes in one place 170- Use `let` bindings for values shared across classes instead of `specialArgs` 171- The pattern does NOT require flakes — see `vic/dendritic-unflake` for non-flake usage 172- Tools like `vic/import-tree` and `vic/flake-file` are recommendations, not requirements