Nix Module Development
SkillDev toolsCreate and structure Nix modules for darwin, NixOS, or home-manager
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Nix Module Development skill
What this skill tells your AI
The instructions your AI receives, as published by r17x/universe in .claude/skills/nix/module/SKILL.md and read by ahel’s review.
Module Template
{ lib, config, pkgs, ... }:
let
cfg = config.<namespace>.<name>;
in
{
options.<namespace>.<name> = {
enable = lib.mkEnableOption "<description>";
package = lib.mkOption {
type = lib.types.package;
default = pkgs.<package>;
description = "Package to use";
};
settings = lib.mkOption {
type = lib.types.attrs;
default = {};
description = "Configuration settings";
};
};
config = lib.mkIf cfg.enable {
# Implementation here
};
}
Common Option Types
lib.types.bool
lib.types.str
lib.types.int
lib.types.path
lib.types.package
lib.types.listOf lib.types.str
lib.types.attrsOf lib.types.str
lib.types.nullOr lib.types.str
lib.types.enum [ "a" "b" "c" ]
lib.types.submodule { options = { ... }; }
Module Patterns
Platform-specific config
config = lib.mkIf cfg.enable (lib.mkMerge [
{
# Common config
}
(lib.mkIf pkgs.stdenv.isDarwin {
# macOS only
})
(lib.mkIf pkgs.stdenv.isLinux {
# Linux only
})
]);
Import platform modules
let
platformModule = if pkgs.stdenv.isDarwin
then ./darwin.nix
else ./linux.nix;
in {
imports = [ platformModule ];
}
Conditional imports
imports = lib.optional cfg.enableFeatureX ./feature-x.nix;
Darwin-specific
Launchd daemon
launchd.daemons.<name> = {
script = ''
exec ${lib.getExe cfg.package}
'';
serviceConfig = {
RunAtLoad = true;
KeepAlive = true;
};
};
Launchd user agent
launchd.user.agents.<name> = {
command = "${lib.getExe cfg.package}";
serviceConfig.KeepAlive = true;
};
Home-manager specific
XDG config file
xdg.configFile."<app>/config".text = ''
# config content
'';
Program module
programs.<name> = {
enable = true;
package = cfg.package;
settings = cfg.settings;
};
Best Practices
- Use
lib.mkEnableOptionfor enable flags - Use
lib.mkDefaultfor overridable defaults - Use
lib.mkForcesparingly, only when necessary - Keep modules focused on single responsibility
- Document options with
description - Use
lib.getExefor binary paths
Signals
- GitHub stars
- 135
- Forks
- 12
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
nix-module- Source
- github.com/r17x/universe