My macOS setup using Nix (nix-darwin + Home Manager) + Homebrew. Clean, modular, and pragmatic.
These dotfiles have been around since 20xx with thousands of commits over 20+ years*. Recently did a fresh start to clean things up and remove legacy stuff.
Prerequisites: macOS with Apple Silicon, just command runner
# Install just (if not already installed)
brew install just
# Clone the repo
git clone git@github.com:d1egoaz/dotfiles.git ~/dotfiles
cd ~/dotfiles
# Install Nix (Determinate Systems installer with flakes enabled)
just install-nix
# Install nix-darwin (first time setup)
just install-darwin
# Apply configuration (auto-detects your machine based on username)
just switchNote: Uses nixpkgs 25.05-darwin (stable) for reliability — avoiding constant updates for basic commands. Select packages pull from unstable when needed.
- office-mbp – Office MacBook Pro (user: diego.alvarez)
- personal-mbp — Personal MacBook Air M3 (user: diego)
- personal-mini — Personal Mac Mini M4 (user: diegoalvarez)
All machines use Apple Silicon (aarch64-darwin) and auto-detect based on username.
- Shell: Fish & Zsh with Starship prompt
- Terminal: Ghostty, WezTerm
- Editor: Emacs (built from Nix), with custom wrapper
- Window Management: AeroSpace tiling window manager
- Status Bar: SketchyBar with custom plugins
- CLI Tools: ripgrep, fd, bat, jq, yq, eza, and many more
- Dev Tools: Git with SSH signing (via 1Password), GitHub CLI, Docker, kubectl
- Secrets: 1Password CLI for on-demand secret access
- AI Tools: Claude Code with custom agents
just switch # Apply changes (uses nh if available)
just update # Update flake inputs
just fmt # Format Nix code
just check # Validate configuration
just lint # Format and check (combines fmt + check)
just gc # Clean up old generations
just brew # Update and upgrade Homebrew apps
just dry-run # Preview changes without applying
just --list # See all available commandsDefine what gets installed on each machine:
profiles/base.nix— Shared across all machinesprofiles/office.nix— Work-specific stuffprofiles/personal.nix— Personal machines
Manages user environment:
- Packages organized in
home-manager/packages.nix - App configs in
home-manager/config/ - Mix of Nix modules and real config files for flexibility
Direct config editing (hybrid approach):
Some configs are symlinked directly from the repo for live editing without rebuilds:
config/sketchybar/→~/.config/sketchybarconfig/wezterm/→~/.config/weztermconfig/ghostty/→~/.config/ghosttyconfig/aerospace/→~/.config/aerospace
Edit these directly and changes take effect immediately!
macOS-specific settings live in systems/darwin/
Custom utility scripts in bin/files/ are automatically symlinked to ~/.local/bin/ via Nix:
- Emacs diff tools:
ediff,ediff3— Git merge/diff wrappers - Kubernetes shortcuts:
k,kc,kn,kk,kstern,ktmux— kubectl helpers - GitHub:
pr-approve— PR approval helper
AWS helpers (awsprofile) are sourced directly by Fish config as shell functions.
Secrets are managed with 1Password CLI for the office profile.
Prerequisites:
brew install 1password-cliSign in to 1Password:
eval (op signin)Secrets are loaded at shell startup from the Employee vault. Available secrets:
OPENAI_API_KEY: OpenAI API keyHOMEBREW_GITHUB_API_TOKEN: GitHub token for Homebrew
Secrets are session-scoped and require 1Password authentication.
User packages (installed in home directory):
- Add to relevant profile:
nix/profiles/base.nix,nix/profiles/office.nix, ornix/profiles/personal.nix - Packages are organized in
hmPackageslist
System packages (available system-wide):
- Add to
darwinPackagesin the profile files
Two approaches:
- Nix modules — Configure under
home-manager/config/programs.nixor app-specific modules- Example:
programs.git,programs.zsh,programs.bat - Managed by Home Manager, changes require
just switch
- Example:
- Direct files — Drop configs in
config/<app>/and link inhome-manager/config/xdg.nix- Example:
config/sketchybar/,config/wezterm/,config/ghostty/ - Symlinked directly, changes take effect immediately
- Use
config.lib.file.mkOutOfStoreSymlinkfor live editing
- Example:
Add to Brewfile (shared across machines) or Brewfile.<host> (machine-specific):
Brewfile— Shared appsBrewfile.office-mbp— Office machine onlyBrewfile.personal-mbp— Personal MBP onlyBrewfile.personal-mini— Personal Mini only
Then run:
just brew# Build failing? Check and format
just check # or: cd nix && nix flake check
just fmt # or: cd nix && nix fmt
just lint # runs both fmt + check
# Preview changes before applying
just dry-run
# Need to rollback?
darwin-rebuild --rollback
# Or jump to a specific generation
darwin-rebuild --list-generations
darwin-rebuild --switch-generation 23
# Clean up old generations
just gc
# Brew app not showing up in Applications?
brew reinstall --cask <app>
# Secrets not loading?
op whoami # Check if authenticated
eval (op signin) # Sign in if needednix-darwin + Home Manager give you:
- Declarative system configuration
- Easy rollbacks when things break
- Reproducible setup across machines
+ Homebrew for:
- GUI apps that work better through Brew
- Things that need macOS-native integration
- Pragmatic balance between purity and practicality
