Nix Module Conventions (options.michal)
Quick start
- •Modules live under
modules/orservices/and are imported bymodules/default.nixorservices/default.nix. - •Custom options always live under
options.michal.*with a config mirror underconfig.michal.*. - •Use
cfg = config.michal.<path>and gate changes withlib.mkIf cfg.enablewhen the option supportsenable. - •Prefer
lib.mkEnableOption+lib.mkOption, andlib.typesfor type definitions. - •Keep indentation at 2 spaces, use relative imports, and avoid non-obvious comments.
Module skeleton
nix
{
config,
lib,
pkgs,
...
}: let
cfg = config.michal.<namespace>.<feature>;
in {
options.michal.<namespace>.<feature> = {
enable = lib.mkEnableOption "<feature description>";
# Additional options
port = lib.mkOption {
type = lib.types.ints.u16;
description = "...";
};
};
config = lib.mkIf cfg.enable {
# NixOS settings
};
}
Layout and imports
- •
modules/default.niximports the core module set. Add new modules there unless they belong to a sub-tree with its owndefault.nix. - •Subtrees use a
default.nixthat only collects imports (example:modules/network/default.nix). - •
services/default.nixdefines helper options and exposes_module.argsfor shared helpers. - •Relative imports only, no absolute paths.
Option naming and structure
- •Namespace roots used today:
- •
michal.programs.*for apps/features (e.g.,michal.programs.tailscale). - •
michal.services.*for services (e.g.,michal.services.home-assistant). - •
michal.network.*for network features. - •
michal.browsers.*for browser modules. - •
michal.environment.*,michal.theme,michal.graphicalas global knobs.
- •
- •When a module supports toggling, it should define
enable = mkEnableOption .... - •Keep the
optionstree mirrored inconfig(cfg = config.michal.<path>).
Common patterns
- •
mkIf cfg.enableto gate config blocks. - •
mkOptionwithlib.typesand explicitdescriptionfor public options. - •Use small helper generators for repeating option sets:
- •Browsers:
modules/gui-packages/browser/options.nixexportsmkBrowserOptions. - •Services:
services/default.nixexportsmyServiceOptionsvia_module.args.
- •Browsers:
- •Use
config.michal.*values inconfigblocks, notoptionsdirectly. - •All new modules should be imported from default and enabled.
- •Consider which hosts should have the module enabled
Special args and module arguments
- •Host config passes
username,hostname,inputs,self,libviaspecialArgsinhosts/default.nix. - •If your module needs these, add them to the argument list in the module signature and use them directly.
- •
services/default.nixexposesmyServiceOptionsvia_module.argsfor services.
File placement expectations
- •GUI/app options under
modules/gui-packages/. - •Service modules under
services/and imported byservices/default.nix. - •Hyprland-related modules under
modules/hyprland/. - •Submodules should be named with kebab-case;
default.nixis the entry point for a folder.
Type conventions and gotchas
- •Use
lib.types.ints.u16for ports (see services). - •Use
lib.types.floatfor fractional thresholds (seemodules/battery.nix). - •Prefer
lib.types.attrsOforlib.types.listOffor collections. - •If an option can be a scalar or list, use
lib.types.either+lib.toList(example: Hyprland keybinds). - •Ensure option descriptions are clear and avoid commas when the option is used in comma-sensitive contexts (see Hyprland keybinds assertions).
Examples to follow
- •Minimal
enabletoggle:modules/network/cloudflare-warp.nix. - •Service with shared options:
services/service_proxy.nix+services/default.nix. - •Generator-based options:
modules/gui-packages/browser/options.nix. - •Complex structured options:
modules/hyprland/keybinds.nix.
Docs generation
- •Options docs are generated by
generate-docs.nixand expectoptions.michal.*to be well-typed. - •If you add new modules, consider adding them to
generate-docs.nixso options show up in docs.
Expectations for agent edits
- •Match existing indentation and style (2 spaces,
with lib;blocks are common). - •Keep comments minimal and focused on non-obvious behavior.
- •Avoid introducing new top-level option roots unless explicitly requested.