name: nix-module-options
description: Query NixOS and Home Manager module options programmatically using flake evaluation. Use this skill when the user asks to check if a module exists, explore available options, get option documentation, or verify what options are available in upstream NixOS/Home Manager (not custom user modules). Activates for queries like "does home manager have a module for X", "what options does service Y have", "check nixos options for Z", or "explore available options".
allowed-tools: Bash, Read
Nix Module Options Explorer
Expert guidance for programmatically querying NixOS and Home Manager module options using flake evaluation.
Core Capability
This skill provides optimized Nix expressions to query module options from your flake-parts configuration, reusing pre-evaluated values for performance.
Key Benefits
- •Offline queries - No need for web searches or option search sites
- •Upstream purity - Queries pure Home Manager/NixOS modules (excludes user custom modules)
- •Performance - Reuses pre-evaluated
pkgsfrom flake debug - •System-agnostic - Uses
currentSystemfor portability - •Complete documentation - Returns type, description, default, examples via
optionAttrSetToDocList
Home Manager Module Options
Check if option exists:
nix eval --impure --expr '
let
flake = builtins.getFlake (builtins.toString ./.);
args = flake.currentSystem.allModuleArgs;
hmLib = args.pkgs.lib.extend (self: super: {
hm = import "${flake.inputs.home-manager}/modules/lib" { lib = self; };
});
in
(hmLib.evalModules {
modules = import "${flake.inputs.home-manager}/modules/modules.nix" {
lib = hmLib;
pkgs = args.pkgs;
check = false;
};
}).options.OPTION.PATH or null
' --json | jq 'if . == null then "NOT FOUND" else "EXISTS" end'
Get full option documentation:
nix eval --impure --expr '
let
flake = builtins.getFlake (builtins.toString ./.);
args = flake.currentSystem.allModuleArgs;
hmLib = args.pkgs.lib.extend (self: super: {
hm = import "${flake.inputs.home-manager}/modules/lib" { lib = self; };
});
in
args.pkgs.lib.optionAttrSetToDocList (
hmLib.evalModules {
modules = import "${flake.inputs.home-manager}/modules/modules.nix" {
lib = hmLib;
pkgs = args.pkgs;
check = false;
};
}
).options.OPTION.PATH
' --json | jq
List all options in a category:
nix eval --impure --expr '
let
flake = builtins.getFlake (builtins.toString ./.);
args = flake.currentSystem.allModuleArgs;
hmLib = args.pkgs.lib.extend (self: super: {
hm = import "${flake.inputs.home-manager}/modules/lib" { lib = self; };
});
opts = (hmLib.evalModules {
modules = import "${flake.inputs.home-manager}/modules/modules.nix" {
lib = hmLib;
pkgs = args.pkgs;
check = false;
};
}).options;
in
builtins.attrNames opts.CATEGORY
' --json | jq -r '.[]'
NixOS Module Options
Check if option exists:
nix eval --impure --expr '
let
flake = builtins.getFlake (builtins.toString ./.);
args = flake.currentSystem.allModuleArgs;
in
(args.pkgs.lib.evalModules {
modules = import "${flake.inputs.nixpkgs}/nixos/modules/module-list.nix" ++ [
{ nixpkgs.hostPlatform = args.system; }
];
}).options.OPTION.PATH or null
' --json | jq 'if . == null then "NOT FOUND" else "EXISTS" end'
Get full option documentation:
nix eval --impure --expr '
let
flake = builtins.getFlake (builtins.toString ./.);
args = flake.currentSystem.allModuleArgs;
in
args.pkgs.lib.optionAttrSetToDocList (
args.pkgs.lib.evalModules {
modules = import "${flake.inputs.nixpkgs}/nixos/modules/module-list.nix" ++ [
{ nixpkgs.hostPlatform = args.system; }
];
}
).options.OPTION.PATH
' --json | jq
List all options in a category:
nix eval --impure --expr '
let
flake = builtins.getFlake (builtins.toString ./.);
args = flake.currentSystem.allModuleArgs;
opts = (args.pkgs.lib.evalModules {
modules = import "${flake.inputs.nixpkgs}/nixos/modules/module-list.nix" ++ [
{ nixpkgs.hostPlatform = args.system; }
];
}).options;
in
builtins.attrNames opts.CATEGORY
' --json | jq -r '.[]'
Common Option Categories
Home Manager top-level:
- •
programs.*- User programs (git, vim, zsh, etc.) - •
services.*- User services (gpg-agent, syncthing, etc.) - •
home.*- Home directory settings - •
xdg.*- XDG directory configuration - •
accounts.*- Email, calendar accounts - •
systemd.*- User systemd units - •
gtk.*,qt.*- Desktop theming - •
wayland.*- Wayland compositors
NixOS top-level:
- •
services.*- System services (nginx, postgresql, etc.) - •
programs.*- System-wide programs - •
hardware.*- Hardware configuration - •
boot.*- Boot loader and kernel - •
networking.*- Network configuration - •
environment.*- System environment - •
systemd.*- System units - •
users.*- User management - •
virtualisation.*- Containers, VMs - •
security.*- Security settings
Option Documentation Fields
lib.optionAttrSetToDocList returns structured documentation:
- •name - Full option path (e.g.,
programs.git.enable) - •description - What the option does (markdown formatted)
- •type - Expected value type (e.g.,
boolean,string,list of string) - •default - Default value if not set
- •example - Usage examples
- •declarations - Source file where option is defined
- •visible - Whether option appears in documentation
- •readOnly - Whether option can be modified
- •internal - Whether option is internal-only
Usage Patterns
Quick existence check: When user asks "does home manager have a duf module?", use null-checking patterns.
Get option details: When user asks "what options does programs.git have?", filter visible options and extract key fields.
List available options: When user asks "what programs are available in home manager?", enumerate attribute names.
Technical Details
Why use currentSystem.allModuleArgs?
- •Pre-evaluated -
pkgsalready instantiated by flake-parts - •System-aware -
args.systemprovides current system automatically - •Overlay-aware - Includes your overlays
- •Faster - Reuses existing evaluation
Purity Guarantees:
These expressions query upstream modules only, importing directly from flake inputs without including user custom modules or actual configurations.
Best Practices
- •Use
jqfor filtering - Pipe tojqfor readable output - •Filter visible options - Use
select(.visible == true)to hide internal options - •Cache results - Add frequently-used queries to flake outputs
- •Check existence first - Use
or nullpattern before getting full docs - •Reference declarations - Use
.declarationsfield to find upstream source
Troubleshooting
"path does not exist" error: The flake path must exist. Ensure running from within your flake repository.
"attribute does not exist" error: Verify correct category, nesting, and that the option exists upstream.
Evaluation too slow: Consider adding queries as flake outputs.
Wrong module system: Use appropriate evalModules function for Home Manager vs NixOS.
Version History: v1.0 (2025-10-28) - Initial skill creation with optimized flake-parts evaluation