name: Nix Helper description: This skill should be used when the user asks to "add a new package", "configure a new program", "troubleshoot Nix build errors", "update flake inputs", "add a new host", "manage secrets with SOPS", "create out-of-store symlink", "use nvfetcher", "use claude-code-overlay", or mentions Nix, Home Manager, or nix-darwin configuration in this dotfiles repository.
Nix Helper
Provide guidance for managing Nix configurations in this dotfiles repository.
Configuration Overview
This dotfiles repository uses:
- Nix Flakes as the primary configuration entry point
- nix-darwin for macOS system-level configuration
- Home Manager for user-level configuration
- SOPS for secrets management
- nvfetcher for external packages not in nixpkgs
- claude-code-overlay for the claude-code package
Directory Structure
.
├── flake.nix # Entry point (inputs, outputs, host configurations)
├── hosts/ # Machine-specific configurations
│ ├── kohei-m4-mac-mini/ # Personal machine config
│ └── SC-N-843/ # Work machine config
├── nix-darwin/ # System-level macOS configurations
│ ├── default.nix # Full configuration (personal machines)
│ └── minimum-for-work.nix # Minimal configuration (work machines)
├── home-manager/ # User-level configurations
│ ├── programs/ # Individual program configurations
│ ├── pkgs/ # Package list (default.nix)
│ ├── services/ # User-level services
│ └── files.nix # Out-of-store symlink configuration
├── configs/ # Raw configuration files (Neovim, WezTerm, etc.)
├── secrets/ # SOPS-encrypted secrets
└── _sources/ # Auto-generated by nvfetcher
Common Tasks
Adding a New Package
Edit home-manager/pkgs/default.nix:
home.packages = with pkgs; [
# ... existing packages
new-package-name
];
See references/package-management.md for nvfetcher and external package patterns.
Adding a New Program Configuration
- Create directory:
home-manager/programs/<program-name>/ - Create
default.nix:
{ pkgs, ... }:
{
programs.<program-name> = {
enable = true;
# Configuration options
};
}
- Import in
home-manager/programs/default.nix:
let
new-program = import ./new-program { inherit pkgs; };
in
[
# ... existing programs
new-program
]
See examples/new-program.nix.example for complete examples.
Adding Config Files with Out-of-Store Symlinks
Use out-of-store symlinks for configs that need editing without Nix rebuild.
- Place files in
configs/.config/<app-name>/ - Edit
home-manager/files.nix:
xdg.configFile."app-name" = {
source = symlink /${rootDir}/.config/app-name;
recursive = true;
};
See examples/out-of-store-symlink.nix.example for patterns.
Working with Secrets
Edit encrypted secrets:
sops secrets/default.yaml
Define in module:
sops.secrets.my-secret = { };
Use the secret path:
config.sops.secrets.my-secret.path
See references/secrets-management.md for detailed SOPS workflow.
Building and Applying Changes
# Apply configuration for specific host
sudo darwin-rebuild switch --flake .#kohei-m4-mac-mini
sudo darwin-rebuild switch --flake .#SC-N-843
# Format all Nix and Lua files
nix fmt
# Update all flake inputs
nix run .#update
# Run pre-commit hooks
nix develop -c pre-commit run --all-files
Key Patterns
userConfig Pattern
Each host defines a userConfig object passed to all modules:
userConfig = {
username = "thinceller";
homeDir = "/Users/${username}";
hostname = "kohei-m4-mac-mini";
dotfilesDir = homeDir + "/.dotfiles";
};
Access in modules via specialArgs:
{ userConfig, ... }:
{
home.username = userConfig.username;
}
Module Import Pattern
Programs return lists for flexible composition:
# home-manager/default.nix
imports = programs ++ files ++ packages ++ services;
External Package Pattern (nvfetcher)
- Define in
nvfetcher.toml - Run
nvfetcherto generate_sources/generated.nix - Import and use:
sources = pkgs.callPackage ../_sources/generated.nix { };
package = sources.package-name;
See references/package-management.md for detailed examples.
Troubleshooting
Build Errors
# Validate flake
nix flake check
# Show detailed error
nix build --show-trace
# Test configuration without applying
darwin-rebuild build --flake .#<hostname>
Common Issues
| Issue | Solution |
|---|---|
| Package not found | Verify name in nixpkgs or use nvfetcher |
| Import errors | Check module path and return type (list vs attrset) |
| Symlink conflicts | Remove existing files before rebuild |
| SOPS decryption fails | Verify age key at ~/.config/sops/age/keys.txt |
Flake Lock Updates
# Update specific input
nix flake lock --update-input <input-name>
# Update all inputs
nix run .#update
Adding a New Host
- Create
hosts/<hostname>/default.nix - Define
userConfig:
userConfig = {
username = "username";
homeDir = "/Users/${username}";
hostname = "<hostname>";
dotfilesDir = homeDir + "/.dotfiles";
};
- Choose nix-darwin module (full or minimum-for-work)
- Add to
flake.nixdarwinConfigurations
See examples/new-host.nix.example for complete template.
Additional Resources
references/package-management.md- nvfetcher, claude-code-overlay, external packagesreferences/secrets-management.md- SOPS workflow and best practicesreferences/home-manager-patterns.md- Program configuration patternsexamples/new-program.nix.example- Program configuration templateexamples/new-host.nix.example- Host configuration templateexamples/out-of-store-symlink.nix.example- Symlink configuration patterns