/docs · Using it
Customizing
Your own modules, the shared modules you can add to, and how the config is organized.
How it’s organized
The config follows the dendritic pattern:
- Every
.nixfile undermodules/is a flake-parts module. import-tree loads all of them, so there’s no import list to keep up to date. Paths containing/_are skipped. - Each file is one feature: Syncthing, the boot splash, zsh, the theme. A single file can set NixOS and Home Manager options together.
- Files don’t import each other. They add to a few shared modules, such as
flake.modules.nixos.pcorflake.modules.homeManager.dotfiles, and a machine is built by combining those. - Settings are a normal NixOS option (
config.ephemeral.settings), not extra function arguments.
Adding a feature means adding a file, and removing one means deleting it. mightyiam/infra and Bad3r/nixos are larger configs built the same way. Architecture shows how a machine is put together from them.
Your own modules
Every .nix file in /persist/etc/nixos/modules/ is loaded the same way. These are the shared modules you can add to:
| module | applies to |
|---|---|
flake.modules.nixos.base, flake.modules.nixos.pc |
every machine, both profiles |
flake.modules.nixos.full |
the full profile |
flake.modules.nixos.minimal |
the small install ("profile": "minimal") |
flake.modules.nixos.gnome, .plasma, .niri, .umbriel |
the desktop chosen in settings.json, full profile |
flake.modules.nixos.minimal-gnome, .minimal-plasma, .minimal-niri, .minimal-umbriel |
the same, small install |
flake.modules.homeManager.base, flake.modules.homeManager.dotfiles |
your user (full system only; the small install has no Home Manager) |
flake.modules.nixos.extras, flake.modules.homeManager.extras |
full profile with "extras": true |
A file in modules/ can add to any of them:
{
flake.modules.nixos.pc =
{ pkgs, ... }:
{
environment.systemPackages = [ pkgs.helix ];
services.openssh.enable = true;
};
flake.modules.homeManager.dotfiles = {
programs.git.settings.user = {
name = "Your Name";
email = "you@example.com";
};
};
}
If a module of yours needs another shared module, import it through ephemeral.aspects rather than flake.modules, so it’s only applied once however many modules import it. Both are on the file’s own config, the one outside the NixOS module:
{ config, ... }:
{
flake.modules.nixos.pc = {
# sets home-manager options, so it brings Home Manager along
imports = [ config.ephemeral.aspects.nixos.home-manager ];
home-manager.sharedModules = [ { programs.htop.enable = true; } ];
};
}
Settings are config.ephemeral.settings in NixOS modules and osConfig.ephemeral.settings in Home Manager. To turn off something the config sets, use lib.mkForce.
lib.mkFlake brings the config’s inputs along, so flake.nix only names ephemeral. Add your own inputs next to it and they’re available to your modules as inputs.<name>; one named like the config’s (say nixpkgs) replaces it.
Rebuild with ephemeral-update, and check a change first with ephemeral-update --check. If you run nix or nixos-rebuild yourself, use path:/persist/etc/nixos#nixos rather than /persist/etc/nixos#nixos: without path:, Nix only sees files tracked by git, so it misses settings.json and hardware-configuration.nix.
If you’d rather work in a clone of the config repo, put your files in modules/local/ instead. That folder is gitignored; modules/local/_example.nix shows the shape.