Declarative macOS system configuration using nix-darwin with machine-specific setups and Homebrew integration.
This configuration manages macOS systems declaratively using Nix, providing:
- Reproducible environments across multiple machines
- Package management via Nix and Homebrew
- System preferences and defaults configuration
- Machine-specific configurations for different hardware setups
- Font management with Nerd Fonts
.config/nix-darwin/
├── flake.nix # Main flake with machine configurations
├── darwin.nix # Shared system configuration
├── machines/ # Machine-specific configurations
│ ├── mac-mini.nix # Personal Mac mini server
│ └── [work machines] # Work MacBook Pro configurations
├── flake.lock # Dependency lockfile
└── README.md # This file
- Purpose: Home server and development machine
- Additional packages: Docker, file managers, development tools
- Services: Docker Compose daemon for home services
- Dock: Minimal setup with essential apps
- Purpose: Professional development workstations
- Focus: Development tools and productivity applications
- Configuration: Optimized for software engineering workflows
- Development:
neovim,gh,lazygit,ripgrep,fd - Shell:
fish,zellij,tmux,fzf,zoxide,atuin - Tools:
stow,oh-my-posh,volta,asdf-vm - AI:
claude-code,codex
- CLI tools:
helix,opencode,herdr(terminal workspace manager for AI agents — installed via brew for fast release tracking) - Applications: 1Password, Arc, ChatGPT, Claude, Ghostty, VS Code
- Productivity: Raycast, Hyperkey, Leader Key
- Creative: Adobe Creative Cloud
- Position: Left side (space-efficient on wide screens)
- Process indicators: Enabled for running applications
- Tile size: Optimized per machine
- Show all extensions: Enabled for transparency
- Default search scope: Current folder
- View style: List view for detailed information
- Tap to click: Enabled on trackpads
- Full keyboard control: Enabled for accessibility
- Key repeat: Enabled in VS Code
- System beep: Disabled
- Network .DS_Store: Disabled to prevent clutter
- Auto-termination: Disabled for stability
- Install Nix with flakes support:
sh <(curl -L https://nixos.org/nix/install)- Install nix-darwin:
sudo nix --extra-experimental-features nix-command --extra-experimental-features flakes run nix-darwin/master#darwin-rebuild -- switch --flake ~/dotfiles/shared/.config/nix-darwin- Apply configuration using the convenience alias:
nix_rebuildOr manually:
darwin-rebuild switch --flake ~/dotfiles/shared/.config/nix-darwinThis configuration includes shell aliases for easier management:
# Apply configuration changes
nix_rebuild
# Update flake dependencies
nix_update
# Update and rebuild in one command
nix_update && nix_rebuildThe nix_rebuild alias uses a smart wrapper script (darwin-rebuild-wrapper.sh) that:
- Detects your machine by hostname
- Determines if you're on a work or personal machine
- Checks for work submodule availability (for work machines)
- Applies the correct flake configuration automatically:
- Work machines: Uses impure evaluation with submodules
- Personal machines: Uses pure evaluation
This means you never have to remember the complex darwin-rebuild command syntax or worry about which configuration to use.
If you prefer to run commands manually or need more control:
# Personal machines
darwin-rebuild switch --flake ~/dotfiles/shared/.config/nix-darwin
# Work machines (requires work submodule)
darwin-rebuild switch --impure --flake "git+file://$HOME/dotfiles?dir=shared/.config/nix-darwin&submodules=1#$(hostname -s)"
# Update flake dependencies
nix flake update --flake ~/dotfiles/shared/.config/nix-darwinEach machine has its own configuration file in machines/ that extends the base darwin.nix:
- Additional packages specific to the machine's purpose
- Custom dock layouts and application preferences
- Hardware-specific settings (Intel vs Apple Silicon)
- Service configurations (like Docker on the Mac mini)
Personal machine configs are auto-discovered from machines/*.nix. Drop a new file named after hostname -s and the flake picks it up — no edits to flake.nix required. The easiest way is ./install.sh --bootstrap from the repo root, which generates an empty-overrides stub for the current hostname if none exists:
{ pkgs, lib, ... }:
{
# Machine-specific overrides for <hostname>.
nixpkgs.hostPlatform = "aarch64-darwin"; # or "x86_64-darwin"
}Work machines remain hardcoded in flake.nix under workConfigs because they gate on the private submodule being initialized.
Managed Nerd Fonts for terminal and editor compatibility:
- Meslo LG Nerd Font - Primary terminal font
- Fira Code Nerd Font - Alternative with ligatures
- Permission errors: Ensure user has admin privileges
- Homebrew conflicts: Run
brew doctorto check for issues - Nix store corruption: Run
nix store verify --all
# Check current generation
darwin-rebuild --list-generations
# Rollback to previous generation
sudo darwin-rebuild rollback
# Garbage collect old generations
nix-collect-garbage -d