Skip to main content
Isabel’s Dotfiles is a modular NixOS configuration framework built on flake-parts and easy-hosts. The architecture separates concerns into distinct layers: flake outputs, system definitions, and reusable modules.

Core principles

The configuration follows these architectural principles:

Modularity

Configuration is split into small, focused modules that can be composed together

Cross-platform

Supports NixOS, macOS (nix-darwin), WSL2, and ISO images from a single codebase

Type safety

Uses Nix’s module system with type-checked options for reliable configuration

Reusability

Shared modules work across different system classes, reducing duplication

Architectural layers

The configuration is organized into three distinct layers:

1. Flake layer

The top-level flake.nix defines inputs and delegates to flake-parts:
{
  description = "Isabel's dotfiles";

  outputs =
    inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } { imports = [ ./modules/flake ]; };

  inputs = {
    nixpkgs.url = "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz";
    darwin = { /* ... */ };
    home-manager = { /* ... */ };
    flake-parts = { /* ... */ };
    easy-hosts = { /* ... */ };
    # Additional inputs...
  };
}
The modules/flake/ directory contains flake-parts modules that generate outputs:
  • args.nix - Base arguments passed to all systems
  • checks/ - Custom validation checks
  • lib/ - Shared library functions
  • packages/ - Custom packages provided by the flake
  • programs/ - Development shell programs

2. System definitions

The systems/ directory contains per-host configurations using easy-hosts:
{ self, inputs, ... }:
{
  imports = [ inputs.easy-hosts.flakeModule ];

  config.easy-hosts = {
    additionalClasses = {
      wsl = "nixos";
    };

    perClass = class: {
      modules = [
        "${self}/modules/${class}/default.nix"
      ];
    };

    hosts = {
      amaterasu = { };
      tatsumaki = {
        arch = "aarch64";
        class = "darwin";
      };
      valkyrie = {
        class = "wsl";
      };
      # More hosts...
    };
  };
}
Each host has its own directory in systems/ with host-specific configuration.

3. Module layer

The modules/ directory contains reusable configuration modules organized by system class. This is covered in detail in the Modules page.

Configuration flow

Here’s how configuration flows through the system:
1

Flake evaluation

Nix evaluates flake.nix and loads flake-parts modules from modules/flake/
2

Host selection

easy-hosts generates system configurations based on systems/default.nix
3

Class modules

The system class (nixos/darwin/wsl/iso) determines which base modules are imported
4

Host configuration

Host-specific settings from systems/<hostname>/ override defaults
5

Option resolution

The NixOS module system evaluates all options and generates the final configuration

The garden namespace

All custom options are namespaced under garden.* to avoid conflicts:
garden = {
  profiles = {
    graphical.enable = true;
    workstation.enable = true;
  };

  device = {
    cpu = "intel";
    gpu = "nvidia";
    capabilities = {
      tpm = true;
      bluetooth = true;
    };
  };

  system = {
    boot.loader = "systemd-boot";
    users = [ "isabel" ];
  };
};
The garden namespace was chosen to represent a carefully cultivated configuration that grows over time.

System classes

The framework supports multiple system classes:
Full NixOS configurations for desktops, laptops, and servers. Includes all base modules plus NixOS-specific modules for boot, hardware, networking, and services.Module path: modules/nixos/
macOS configurations using nix-darwin. Includes base modules plus Darwin-specific modules for Homebrew, preferences, and macOS-specific settings.Module path: modules/darwin/
NixOS on WSL2 configurations. Treated as a nixos subclass with WSL-specific modules.Module path: modules/wsl/
Bootable ISO images for installing NixOS. Used for system installation and recovery.Module path: modules/iso/
Home Manager configurations are imported by base modules and share the same garden namespace.Module path: modules/home/

Integration with home-manager

Home Manager is integrated at the base level, meaning user environment configuration is part of system configuration:
  • Home Manager modules are imported by modules/base/default.nix
  • User-specific settings use the same garden.* options
  • Home Manager and system configuration share the same module system
This tight integration ensures consistency between system and user configuration.

Next steps

Module system

Learn how modules are organized and how to create new ones

System definitions

Understand how to configure individual hosts

Build docs developers (and LLMs) love