A single Nix flake covering my NixOS hosts and macOS hosts.
The repo follows the dendritic pattern.
.
├── flake.nix # Inputs; imports everything in modules/
├── Makefile # Common rebuild, update, and check commands
└── modules/
├── base.nix # Composes features into nixos.base, darwin.base, homeManager.base
├── configurations/ # Instantiates hosts and generates system checks
├── flake-parts.nix # Flake-parts module integrations
├── systems.nix # Systems supported by per-system outputs
├── formatter.nix # Repository-wide Nix formatter
├── profile/ # Identity and shared appearance settings
├── hosts/ # Hosts definitions
├── nixos/ # NixOS-only system features
├── darwin/ # macOS-only system features
├── desktop/ # Desktop integration (apps, gtk, qt, cursor, xdg, …)
│ └── wm/ # Window manager choices (niri, aerospace)
├── programs/ # Program-oriented modules, mostly for Home Manager
│ └── scripts/bin/ # Scripts packaged into a Home Manager derivation
└── *.nix # Repository-level features for one or more module classes
- Files under
modules/nixos/,modules/darwin/, ormodules/programs/typically declare modules of a single class (nixos.*,darwin.*,homeManager.*). Vertical program features such as Zsh, Podman, Brave, and Mos may declare modules for more than one class. - Files at the root of
modules/, and files undermodules/desktop/, may span more than one class. For example,fonts.nixdeclares bothdarwin.fontsandhomeManager.fonts, andusers.nixdeclares bothnixos.usersanddarwin.users. Single-class modules may also live there (e.g.catppuccin.nix,desktop/gtk.nix). modules/base.nixcollects default workstation features intonixos.base,darwin.base, andhomeManager.base. Opt-in features are composed by their owning host or parent feature instead.- Hosts in
modules/hosts/importnixos.baseordarwin.basetogether with any opt-in extras such asnixos.niri,nixos.gaming, ordarwin.aerospace. - Files and directories prefixed with
_(for example_hardware.nix) are skipped byimport-treeand imported explicitly where needed.
Fork this repository and clone the fork.
modules/profile/preferences.nix declares the personal settings shared across all hosts: name, email, Git signing key ID, Catppuccin flavor, icon and cursor theme, fonts, locale, and timezone.
Note
profile is an untyped option, so edit the values in place and keep the existing attribute names and nesting. A misspelled attribute is not reported against this file — it surfaces later as a missing-attribute error in whichever module consumes it (for example desktop/gtk.nix or programs/alacritty.nix).
Replace the asset files with your own:
modules/profile/avatar.jpgmodules/profile/wallpaper.jpg
The remaining files in modules/profile/ declare the primaryUser option and configure its Home Manager state version. modules/users.nix configures the corresponding NixOS or Darwin user.
Remove hosts under modules/hosts/ that do not apply. energy/ and xps/ are NixOS examples; work-mac.nix is a macOS example.
For NixOS:
mkdir -p modules/hosts/laptop
sudo nixos-generate-config --show-hardware-config > modules/hosts/laptop/_hardware.nixmodules/hosts/laptop/default.nix:
{ config, ... }:
let
inherit (config.flake.modules) nixos;
in
{
configurations.nixos.laptop.module = {
imports = [
./_hardware.nix
nixos.base
nixos.niri
];
primaryUser = "your-user";
system.stateVersion = "26.05";
};
}Important
Substitute the placeholders before building:
laptopinconfigurations.nixos.laptop.module: the machine's hostname and the flake output name used by theMakefile; using the same name for the directory is only a conventionyour-user: the managed account name on NixOS; on macOS it must match the existing login short name- the feature list (
nixos.niri, …) — adjust to taste
For macOS:
copy modules/hosts/work-mac.nix and substitute the same placeholders. The shape mirrors the NixOS example, with three differences: the attribute key is configurations.darwin."<hostname>".module, the base is darwin.base (plus macOS-only extras like darwin.aerospace), and there is no _hardware.nix.
New host files are picked up by import-tree without further registration (but don't forget git add . new files).
make nixos-rebuild # NixOS
make darwin-rebuild # macOS
make fmt # format the repository
make flake-check # validate the flakemake help lists all targets. The Makefile defaults to .#$(hostname), so flake outputs named after the machine's hostname are selected automatically. Complete NixOS and Darwin system checks must be built on their matching platforms.
- A new Home-Manager program lives in
modules/programs/<name>.nixand declaresflake.modules.homeManager.<name>. Register default workstation programs inhomeManager.base; import opt-in programs from their owning feature. - A new NixOS-only or Darwin-only system feature lives in
modules/nixos/<name>.nixormodules/darwin/<name>.nixand declaresflake.modules.{nixos,darwin}.<name>. Register defaults in the matching base and import opt-in features from hosts. - A feature spanning more than one class may live beside its primary concern or under
modules/desktop/for compositor-adjacent features. Register each default class module independently; parent features may compose subordinate modules directly.
MIT — see LICENSE.

