nix-module-options
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".
- Category: discovered
- Tags: github, community
- Version: 1.0.0
- Author: walid
- Downloads: 0
- GitHub stars: 2
- Updated: 2025-11-21
Download the latest version (v1.0.0) from this page.
SKILL.md
---
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
1. **Offline queries** - No need for web searches or option search sites
2. **Upstream purity** - Queries pure Home Manager/NixOS modules (excludes user custom modules)
3. **Performance** - Reuses pre-evaluated `pkgs` from flake debug
4. **System-agnostic** - Uses `currentSystem` for portability
5. **Complete documentation** - Returns type, description, default, examples via `optionAttrSetToDocList`
## Home Manager Module Options
### Check if option exists
```bash
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
```bash
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
```bash
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
```bash
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
```bash
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
```bash
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?":
```bash
nix eval --impure --expr '...' | jq 'if . == null then "NOT FOUND" else "EXISTS" end'
```
### Get option details
When user asks "what options does programs.git have?":
```bash
nix eval --impure --expr '...' | jq 'map(select(.visible == true)) | map({name, type, description})'
```
### List available options
When user asks "what programs are available in home manager?":
```bash
nix eval --impure --expr '... builtins.attrNames opts.programs' | jq -r '.[]'
```
## Technical Details
### Why use `currentSystem.allModuleArgs`?
1. **Pre-evaluated** - `pkgs` already instantiated by flake-parts
2. **System-aware** - `args.system` provides current system automatically
3. **Overlay-aware** - Includes your overlays (though doesn't affect options)
4. **Faster** - Reuses existing evaluation instead of re-accessing inputs
### Purity Guarantees
These expressions query **upstream modules only**:
- Imports directly from `${flake.inputs.home-manager}/modules/modules.nix`
- Imports directly from `${flake.inputs.nixpkgs}/nixos/modules/module-list.nix`
- Does NOT include user's custom modules from `.claude/` or `home/`
- Does NOT evaluate user's actual `homeConfigurations` or `nixosConfigurations`
To query user's actual config (including custom modules):
```bash
nix eval --impure --expr '
(builtins.getFlake (builtins.toString ./.))
.homeConfigurations.USERNAME.options.OPTION.PATH
'
```
## Best Practices
1. **Use `jq` for filtering** - Pipe to `jq` for readable output
2. **Filter visible options** - Use `select(.visible == true)` to hide internal options
3. **Cache results** - For repeated queries, consider adding to flake outputs
4. **Check existence first** - Use `or null` pattern before getting full docs
5. **Reference declarations** - Use `.declarations` field to find upstream source
## Troubleshooting
### "path does not exist" error
The flake path must exist. This skill uses `builtins.getFlake (builtins.toString ./.)` which refers to the current project directory. Ensure you're running commands from within your flake repository.
### "attribute does not exist" error
The option path is wrong. Check:
- Correct category (e.g., `programs` vs `services`)
- Correct nesting (e.g., `programs.git.enable` not `programs.git`)
- Option exists in upstream (not a custom module)
### Evaluation too slow
Consider adding frequently-used queries as flake outputs for caching.
### Wrong module system
Ensure you're using the right command:
- Home Manager queries use `hmLib.evalModules` with HM modules
- NixOS queries use `pkgs.lib.evalModules` with NixOS modules
## Version History
- **v1.0** (2025-10-28) - Initial skill creation with optimized flake-parts evaluation