My declarative way to manage macOS system configuration, including packages, system settings, and development environment using nix-darwin and Determinate Nix Installer.
While this configuration supports both Nix and Homebrew, I recommend using Nix as your primary package manager for a bunch of reasons:
- Ever had to set up a new machine and thought, "this will take days"? Not anymore!
- No more scattered dotfiles or "what did I install again?" moments.
- If you work on developing cross-platform apps, sometimes you need to nuke your system 🥲 this way, you can get it back up and running in a blink.
- Your entire system setup is in code—like Infrastructure as Code, but for your PC.
- That moment when an update breaks everything? Roll back instantly, just
git reset
to go back in time! - Share your setup with your team without writing a 50-page wiki document.
- Need Python 2.7 for that legacy project but Python 3.11 for the new stuff? No problem!
- Though maybe it's time to rewrite it in Rust? 🦀
- Want to try something new? Just
nix run nixpkgs#cowsay -- "Hello"
without installing anything. - No more "but it works in development" when your local Node version is different from production.
- Though maybe it's time to rewrite it in Rust? 🦀
- Each project gets its own little world with exactly what it needs.
- Share your setup with your team without writing a 50-page wiki document.
This still supports Homebrew, although it's mainly a fallback, use it only for:
- Apps that just won't play nice with Nix
- Apps not available in Nix (rare but happens)
- Apps that require system integration that Nix can't provide
- System stuff that needs special macOS permissions
- When you absolutely need that one app that's only on the Mac App Store
First, install Nix using the Determinate Nix Installer:
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
This will install nix
with:
- Flakes enabled by default
- Multi-user installation
- macOS upgrade survival
- Automatic store optimization
- Other sensible defaults
Note
This configuration uses the flakes feature of Nix, which is automatically enabled by the Determinate Nix Installer.
After installing nix
, clone this repo:
git clone https://github.com/CuriousCorrelation/nix-darwin ~/.config/nix-darwin
cd ~/.config/nix-darwin
Warning
The following configuration changes are required before building. The install might fail and system won't work correctly without updating these details.
Update your personal information in these files:
- In
modules/home-manager/main.nix
, replace the Git configuration:
programs.git = {
userEmail = "your.email@example.com"; # Replace with your email
userName = "Your Name"; # Replace with your name
};
- In
profiles/main.nix
, replace the username:
user.name = "yourusername"; # Replace with your username
- In
flake.nix
, replace the hostname:
darwinConfigurations."Your-MacBook-Name" = darwin.lib.darwinSystem { # Replace with your hostname
Tip
Find your hostname by running: scutil --get LocalHostName
After updating your personal information, build and activate the configuration:
nix run nix-darwin -- switch --flake .
Note
The first build might take some time as it downloads and builds all required packages.
This configuration uses several flake inputs:
nixpkgs
: The main Nix packages repositorynix-darwin
: For macOS system configurationhome-manager
: For user environment managementstable
: Stable NixOS channel for certain packagesdevenv
: For development environment management- And various utilities like
flake-utils
andtreefmt-nix
- flake.nix - Flake configuration and inputs
- apps.nix - macOS applications (via Homebrew)
- aqua.nix - Window manager settings (yabai + skhd)
- brew.nix - Homebrew configuration
- core.nix - Core system settings
- preferences.nix - macOS system preferences
- alacritty.nix - Terminal emulator config
- bat.nix - bat (cat alternative) config
- fzf.nix - Fuzzy finder config
- git.nix - Git configuration
- ssh.nix - SSH configuration
- zsh.nix - Shell configuration
- profiles/main.nix - Main system profile
- profiles/home-manager/main.nix - Main user profile
Edit config file (e.g., modules/darwin/brew.nix
for Homebrew packages or modules/home-manager/default.nix
for Nix packages) and run the rebuild command.
Tip
After making any changes, remember to run darwin-rebuild switch --flake .
to apply them.
To update all packages and apply changes:
nix flake update # Updates all flake inputs
darwin-rebuild switch --flake .
Tip
You can update specific inputs using nix flake lock --update-input home-manager
for example.
If you encounter issues:
- Check system logs:
tail -f /var/log/system.log
- Check nix logs:
tail -f /nix/var/log/nix/daemon.log
- Run with verbose output:
darwin-rebuild switch --flake . --show-trace -v
Tip
If you get permission errors, make sure you've properly set up your username in the configuration files.
Important
Make sure to uninstall in the correct order to avoid system issues.
- First uninstall nix-darwin:
nix run nix-darwin -- uninstall
- Then uninstall Nix:
/nix/nix-installer uninstall