Skip to main content
This guide covers creating custom modules for your homelab infrastructure. Modules are the building blocks that make your configuration reusable and maintainable.

Module Structure

Modules in this homelab are organized by scope:
  • modules/nixos/ - System-level NixOS modules
  • modules/home/ - User-level Home Manager modules
  • modules/droid/ - Nix-on-Droid modules
Each category is further organized by function:

Creating a Module

1

Create Issue

Follow the Issue-First policy:
2

Create Feature Branch

3

Choose Module Location

Decide where your module belongs based on its scope:
  • System hardware? → modules/nixos/core/hardware/
  • Desktop feature? → modules/nixos/desktop/features/
  • User application? → modules/home/userapps/
4

Create Module File

Create a new .nix file in the appropriate directory:
5

Write Module Code

Follow the standard module pattern:
modules/nixos/core/hardware/bluetooth.nix
6

Register Module

Add your module to the appropriate default.nix file:
modules/nixos/core/hardware/default.nix
7

Validate Module

Test that your module compiles:
8

Commit Changes

Use conventional commits:

Module Patterns

Basic Enable Module

Simplest form - just an enable option:

Module with Options

Add configuration options:

Nested Module Structure

For complex features, use nested modules:

Home Manager Module

User-level modules follow similar patterns:

Module Best Practices

  • Use descriptive, lowercase names
  • Separate words with hyphens in filenames: bluetooth.nix, network-manager.nix
  • Use dot notation in option paths: core.hardware.bluetooth
  • Always use lib.mkEnableOption for boolean enables
  • Provide sensible defaults
  • Include descriptions for all options
  • Add example values where helpful
  • Use proper types: lib.types.str, lib.types.int, lib.types.path, etc.
  • Group related configuration together
  • Use let ... in for computed values
  • Keep config section clean and readable
  • Use lib.mkIf to conditionally apply configuration
  • Declare module inputs: lib, config, pkgs
  • Import other modules through default.nix files
  • Avoid circular dependencies

Testing Your Module

Local Testing

Test on a system configuration:
systems/test-system/default.nix

Flake Checks

Ensure it passes validation:

Manual Validation

Build the configuration:

Common Module Types

Hardware Module

Enables hardware support:

Service Module

Configures system services:

Application Module

Installs and configures applications:

Next Steps