Agent skill
nix-config
This skill provides comprehensive guidance for working with the nix-config framework - a platform-agnostic modular configuration system for NixOS and Darwin (macOS). Use this skill when adding new modules, hosts, users, or services; when troubleshooting configuration issues; or when modifying any aspect of the nix-config/nix-secrets ecosystem.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/nix-config
SKILL.md
Nix-Config Framework
Overview
This skill provides comprehensive knowledge of the nix-config framework - a platform-agnostic modular configuration system that supports both NixOS and Darwin (macOS) through a unified architecture. The framework separates public configuration logic (nix-config) from private sensitive data (nix-secrets) using a three-file pattern for platform-agnostic design.
Core Architecture
Three-File Pattern
Each module uses three files to separate platform-specific logic:
default.nix- Platform-agnostic common logicnixos.nix- Linux-specific (systemd, NetworkManager)darwin.nix- macOS-specific (launchd, Homebrew paths)
Priority System: lib.mkDefault (low) → normal → lib.mkForce (high)
Configuration Inheritance Hierarchy
Layer 1: hosts/common/core/ - Core system configuration
Layer 2: hosts/common/optional/ - Optional services
Layer 3: hosts/common/users/ - User configurations
Layer 4: hosts/nixos/${hostname}/ - Host-specific config
Separation of Concerns
| Location | Type | Content |
|---|---|---|
nix-config/ |
Public | Module logic, configuration structure |
nix-secrets/ |
Private | Sensitive data (IPs, passwords, keys) |
Quick Task Guide
Adding a New NixOS Host
To add a new NixOS host:
- Create host directory:
hosts/nixos/${hostname}/ - Copy or generate
hardware-configuration.nix:- From existing host:
cp hosts/nixos/ExistingHost/hardware-configuration.nix hosts/nixos/NewHost/ - From target machine: Run
sudo nixos-generate-config --root /mnton the host
- From existing host:
- Create
default.nixwith host-specific imports and settings - Add host entry to
nix-secrets/nix/network.nix(network info) - Create encrypted secrets file:
nix-secrets/secrets/${hostname}.yaml - Test build:
./scripts/rebuild.sh NewHost build
Adding a New Darwin Host
To add a new Darwin (macOS) host:
- Create host directory:
hosts/darwin/${hostname}/ - Create
default.nixwith host-specific imports - Critical: Set
hostSpec.isDarwin = true - Add host entry to
nix-secrets/nix/network.nix - Create encrypted secrets file:
nix-secrets/secrets/${hostname}.yaml - Test build:
./scripts/rebuild.sh NewMac build
Adding a New User
To add a new user:
- Create user directories:
hosts/common/users/${username}/home/${username}/common/{core,dotfiles,optional}/
- Create platform-agnostic config:
hosts/common/users/${username}/default.nix - Create platform-specific configs:
nixos.nixanddarwin.nix - Add SSH public keys to:
hosts/common/users/${username}/keys/ - Create Home Manager config:
home/${username}/common/core/default.nix - Update
hosts/common/core/default.nixto import the new user
Adding a New Service Module
To create a reusable service module:
- Determine module type:
- Optional service: Place in
hosts/common/optional/services/ - Reusable module: Place in
modules/hosts/common/,modules/hosts/nixos/, ormodules/hosts/darwin/
- Optional service: Place in
- Create module file with options and config
- Reference in host config via imports or hostSpec flags
Common Patterns
lib.custom Functions
# Relative path from project root
lib.custom.relativeToRoot "modules/common"
# Scan directory for .nix files
lib.custom.scanPaths ./optional
Import Patterns
# Flatten nested imports
imports = lib.flatten [
./hardware-configuration.nix
(map lib.custom.relativeToRoot [
"hosts/common/core"
"hosts/common/optional/services/docker.nix"
])
];
# Conditional imports
imports = lib.optionals (!isDarwin) [
(lib.custom.relativeToRoot "hosts/common/core/openssh-server.nix")
];
Platform Detection
# Method 1: hostSpec
lib.mkIf (!config.hostSpec.isDarwin) { ... }
# Method 2: pkgs.stdenv
lib.optionalAttrs pkgs.stdenv.isLinux { ... }
# Method 3: File-level separation
hosts/common/users/${username}/default.nix # Always imported
hosts/common/users/${username}/nixos.nix # Only NixOS
hosts/common/users/${username}/darwin.nix # Only Darwin
Key Files and Locations
Critical Files
| File | Purpose |
|---|---|
flake.nix |
Root configuration, defines inputs and outputs |
modules/common/host-spec.nix |
Host specification module (username, network info, flags) |
hosts/common/core/default.nix |
Core system config, imports HM and SOPS |
scripts/rebuild.sh |
Cross-platform rebuild script |
nix-secrets Structure
nix-secrets/
├── nix/ # Nix-exposed configuration
│ ├── network.nix # Network config per host (no sensitive data)
│ ├── network-storage.nix # NFS/Samba configurations
│ └── services.nix # Service-specific secrets
└── secrets/ # SOPS encrypted files
└── ${hostname}.yaml # Host-specific encrypted secrets
Common Pitfalls and Solutions
| Issue | Solution |
|---|---|
| Option conflicts | Use lib.mkDefault in base config |
Missing group on Darwin |
Use lib.optionalAttrs pkgs.stdenv.isLinux { group = "wheel"; } |
Wrong stateVersion type |
NixOS = string, Darwin = integer |
| Auto-optimise-store on Darwin | Use nix.optimise.automatic instead |
| SOPS SSH key paths differ | Conditional sshKeyPaths in sops.nix |
| Secrets not decrypting | Check AGE key recipients and SSH agent |
Essential Commands
System Rebuild
# On NixOS
sudo nixos-rebuild switch --flake .#hostname
# On Darwin
sudo darwin-rebuild switch --flake .#hostname
# Cross-platform script
./scripts/rebuild.sh [hostname] [trace|build]
# Using nh (if installed)
nh os switch .
nh darwin switch .
Secrets Management
# Edit secret
sops secrets/${hostname}.yaml
# Encrypt file
sops -e -i secrets.txt
# Decrypt file
sops -d -i secrets.txt
# Add new AGE key
sops keys add age1...
# Rotate keys
sops rotate -i secrets.yaml
Development
# Enter dev shell
nix develop
# Format code
nix fmt
# Run checks
nix flake check
# Build ISO
nix build --impure .#nixosConfigurations.iso.config.system.build.isoImage
Platform-Specific Notes
NixOS
- Use
system.stateVersion = "25.05"(string) - Use
fileSystems.*for mounting - Use
systemd.services.*for services - Use
networking.networkdorNetworkManager - SSH keys go to
/etc/ssh/authorized_keys.d/
Darwin (macOS)
- Use
system.stateVersion = 6(integer; 5 = nix-darwin 25.05) - Use
launchd.agents.*for services - No NetworkManager (uses macOS networking)
- SSH keys managed differently
- Homebrew paths in config
- Touch ID integration available
Additional Resources
For detailed documentation and references, consult the bundled resources in the references/ directory:
architecture.md- Detailed architecture and design patternsdirectory-structure.md- Complete directory structure referencehostspec-reference.md- hostSpec module options referencemodule-creation.md- Module creation patterns and examplesnetwork-storage.md- Network storage module documentation
These files provide in-depth information for complex operations and should be referenced when detailed guidance is needed beyond this quick guide.
Didn't find tool you were looking for?