name: nix-manager
description: Manage Nix packages, flakes, and configurations using Determinate Nix installer patterns. Use when installing/updating packages, creating flakes, troubleshooting Nix issues, or optimizing Nix workflows. Keywords: nix, flake, package, nixpkgs, nix profile, flake.nix, flake.lock, determinate, nix-installer
Nix Package & Configuration Manager
Comprehensive Nix management following Determinate Systems best practices and this repository's patterns.
Instructions
1. Understand Repository Context
Check current Nix setup:
- Flake location:
/Users/wcygan/Development/dotfiles/flake.nix
- Installation script:
scripts/install-packages.sh
- Package management:
nix profile (user-scoped, modern approach)
- Installer: Determinate Systems installer (macOS/Linux)
- Update mechanism:
make update or nix flake update && nix profile upgrade
Read current flake.nix to understand:
- Input sources (currently:
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable")
- Package definitions (buildEnv with ~60+ packages)
- Outputs:
packages, devShells, formatter
- Supported systems: x86_64-linux, aarch64-linux, x86_64-darwin, aarch64-darwin
2. Package Management Operations
Install New Package
Process:
- Add package to
flake.nix in appropriate category
- Run
nix flake check to validate
- Run
nix profile upgrade dotfiles to apply changes
- Test package availability
Example:
# flake.nix packages section
paths = [
# ... existing packages ...
# New package
cowsay # Fun terminal tool
];
nix flake check
nix profile upgrade dotfiles
which cowsay
Update All Packages
Process:
nix flake update
nix profile upgrade dotfiles
nix profile list
Or use Makefile shortcut:
make update
Remove Package
Process:
- Remove from
flake.nix
- Run
nix flake check
- Run
nix profile upgrade dotfiles
- Old package remains in store but not in PATH
Note: Garbage collection removes unreferenced packages:
make clean
3. Flake Configuration
Modify flake.nix
Common operations:
Add new input:
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
# Add new input
home-manager.url = "github:nix-community/home-manager";
home-manager.inputs.nixpkgs.follows = "nixpkgs"; # Prevent duplicate nixpkgs
};
Add platform-specific packages:
paths = [
# Universal packages
git gh lazygit
] ++ lib.optionals stdenv.isDarwin [
# macOS-only
darwin.apple_sdk.frameworks.Security
] ++ lib.optionals stdenv.isLinux [
# Linux-only
libnotify
];
Modify devShell:
devShells = forAllSystems ({ pkgs }: {
default = pkgs.mkShell {
packages = with pkgs; [
fish
nixpkgs-fmt
shellcheck
# Add development tools here
];
inputsFrom = [ self.packages.${pkgs.system}.default ];
shellHook = ''
echo "🐠 Dotfiles development environment"
echo "Run: make test-pre"
'';
};
});
Validate Flake
Always validate before applying:
nix flake check
nix flake metadata
nix flake show
Common issues:
- Package renamed in nixpkgs (e.g.,
du-dust → dust)
- Missing comma in package list
- Invalid attribute path
- Syntax errors in Nix expressions
Update Lock File
When to update:
- Regular maintenance (weekly/monthly)
- Security updates needed
- Specific package version required
How:
nix flake update
nix flake lock --update-input nixpkgs
git diff flake.lock
4. Troubleshooting
Slow Nix Operations
Diagnosis:
nix store info
nix store gc --dry-run
Solutions:
- Run
nix-collect-garbage -d to remove old generations
- Run
nix store optimise to deduplicate files
- Check network connectivity (binary cache downloads)
Package Not Found
Error: error: attribute 'package-name' missing
Solutions:
- Check nixpkgs version: some packages only in unstable
- Search for package:
nix search nixpkgs package-name
- Check if package was renamed
- Try alternative package names
Evaluation Errors
Error: error: ... while evaluating ...
Common causes:
- Syntax error in
flake.nix
- Recursive attribute access
- Type mismatch (string vs list)
Debug:
nix eval .#packages.aarch64-darwin.default.name
nix repl
:lf .
packages.aarch64-darwin.default.name
Lock File Conflicts
Error: error: flake.lock is dirty
Solutions:
rm flake.lock
nix flake update
nix flake check --impure
Profile Issues
List installed profiles:
nix profile list
Output format:
Index: 0
Flake attribute: legacyPackages.aarch64-darwin.dotfiles
Original flake URL: git+file:///Users/wcygan/Development/dotfiles
Locked flake URL: git+file:///Users/wcygan/Development/dotfiles?rev=...
Store paths: /nix/store/...-system-packages
Rollback to previous generation:
nix profile rollback
Remove specific profile:
nix profile remove <index-number>
5. CI/CD Integration
This repository uses Determinate Systems GitHub Actions for CI.
GitHub Actions setup (.github/workflows/ci.yml):
- name: Setup Nix cache
uses: DeterminateSystems/magic-nix-cache-action@v2
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@v14
with:
extra-conf: |
experimental-features = nix-command flakes
- name: Run install script
run: ./install.sh
Benefits:
- Magic Nix Cache: ~90% faster CI (uses GitHub Actions cache)
- Automatic cache population
- No configuration required
Local equivalent:
make test-docker
./install.sh && ./install.sh
6. Best Practices (Determinate Nix Patterns)
Use nixos-unstable Instead of master
Reasoning:
nixos-unstable: Tested, passes Hydra CI
master: Untested, may have broken packages
Current setup:
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
Never Use --impure
Problem: Breaks reproducibility by allowing environment variable access
Correct:
nix profile add .
nix profile upgrade dotfiles
Incorrect:
nix profile add . --impure
Exception: Only use --impure if flake explicitly uses getEnv or similar
Pin Dependencies in Lock File
Why:
- Ensures reproducible builds across machines
- Prevents "works on my machine" issues
- Required for CI/CD reliability
How:
git add flake.lock
git commit -m "chore: update flake lock"
Use buildEnv for Package Groups
Pattern in this repo:
packages.default = pkgs.buildEnv {
name = "system-packages";
paths = [ git gh lazygit ... ];
};
Benefits:
- Single derivation for all packages
- Atomic updates (all packages succeed or fail together)
- Easier to manage than individual
nix profile install calls
Enable Flakes in Config
User-level config (~/.config/nix/nix.conf):
experimental-features = nix-command flakes
This is automatically set by scripts/install-packages.sh
7. Development Workflows
Create New Project Flake
Use repository root as template:
cp flake.nix /path/to/new-project/
cd /path/to/new-project
$EDITOR flake.nix
Or use templates directory:
nix flake init -t .#template-name
Test Flake Locally
Without installing:
nix develop
nix build
nix run .#package-name
Format Nix Code
Using formatter output:
nix fmt
Manual formatting:
nixpkgs-fmt flake.nix
8. Migration Guidance
From Homebrew
Don't uninstall Homebrew—it coexists peacefully. Fish PATH priority:
- Homebrew (
/opt/homebrew/bin) - highest priority
- User bins (
~/.local/bin, ~/bin)
- Language toolchains (
~/.cargo/bin, ~/go/bin)
- Nix (
~/.nix-profile/bin) - lowest priority
Migration strategy:
which package-name
brew uninstall package-name
which package-name
From apt/dnf
Linux distros:
- Nix coexists with system package managers
- System packages have priority over Nix (via PATH ordering)
- Use Nix for tools not in distro repos or needing newer versions
9. Output Format
When modifying flake.nix:
Use Edit tool for existing files:
- Modify specific sections
- Preserve comments and formatting
- Minimize diff size
Use Write tool for new files:
- Complete flake.nix from scratch
- Include comments explaining choices
- Follow repository formatting style
After changes, always:
- Validate:
nix flake check
- Test build:
nix build --dry-run
- Apply:
nix profile upgrade dotfiles
- Verify:
nix profile list
Include testing commands:
nix flake check
nix flake show
nix profile upgrade dotfiles
Repository Patterns
This dotfiles repository follows these conventions:
File Structure:
flake.nix - Package definitions and outputs
flake.lock - Pinned dependency versions
scripts/install-packages.sh - Installation wrapper
scripts/link-config.sh - Dotfile symlinking
config/ - Dotfile configurations (fish, starship, etc.)
Package Organization:
Packages grouped by purpose with comments:
paths = [
# Version control
git gh lazygit
# Build tools
gnumake cmake pkg-config
# Programming languages
rustup go python3 deno
# ... etc
];
Testing:
make test-pre - Pre-flight validation
make test-local - Ephemeral HOME test
make test-docker - Multi-distro Docker matrix
Common Commands:
make install - Run full installation
make update - Update flake + upgrade packages
make clean - Garbage collect
make verify - Check Nix installation health
Reference Documentation
Quick Reference
Essential Commands:
nix search nixpkgs <package>
nix profile list
nix profile upgrade dotfiles
nix-collect-garbage -d
nix flake update
nix flake check
nix flake show
nix flake metadata
nix develop
nix build
nix fmt
nix run .#package
nix store info
nix store gc --dry-run
nix profile rollback