My nix-darwin / NixOS configuration.
My daily driver is macOS. There are also a NixOS homelab setup and NixOS VM setups (for experiments).
- Nix flakes provide a reproducible, pin-exact configuration shared across all machines.
- On macOS, nix-darwin manages system-level settings and packages declaratively.
- home-manager manages the user environment (dotfiles, packages, shell) across both macOS and NixOS hosts.
- Terminal: Ghostty, using its built-in splits and tabs instead of a multiplexer
- Font: Berkeley Mono™ Typeface
- On macOS, it sets a beautiful wallpaper from Raycast
- General zsh configuration:
- Prompt: Starship with a customized Pure prompt
- Theme: Catppuccin Macchiato (Blue accent wherever available)
- A number of handy aliases and functions and shell scripts
- Automatic shell proxy propagation from macOS settings
- CLI apps of choice:
- Editor: Helix
- Shell History: Atuin
- Git TUI: lazygit (a quick starter video)
- File Manager: Yazi (invoke with
yfor shell integration) - Directory Navigation: zoxide
- fzf shell integration
- CTRL-T - Paste the path of selected files and directories
- ALT-C - cd into the selected directory
- fzf-tab for fuzzy-searching zsh completion results, including a smart preview window
Custom Zsh keybindings are configured in home/files/shell/keys.zsh.
This is designed to work with default Ghostty macOS keybindings, or the iTerm2 Natural Text Editing keymappings preset.
Keybinding Reference
| Key Combo | Description |
|---|---|
Ctrl+U |
Delete everything to the left of the cursor |
Ctrl+X then Delete |
Delete entire line to the left of cursor |
Ctrl+B |
Jump to beginning of line |
Alt+Q |
Push aside current command line to type a new one (re-inserted on next prompt) |
Ctrl+X then Ctrl+_ |
Redo last undone edit |
Ctrl+X then Ctrl+E |
Edit current command line in $EDITOR |
Alt+V |
Show next key combo's terminal code and description |
Alt+Shift+S |
Prefix current/previous command with sudo |
Shell functions are defined in home/files/shell/functions.zsh.
A non-exhaustive list:
Video & Media
burnsrt <input.mp4> <input.srt> <output.mp4>- Burn SRT subtitles into MP4 videoshrinkvid <input> <output> [bitrate]- Compress video (uses hardware acceleration on macOS)impaste > file.png- Output clipboard image data to stdoutfavicon <input.png>- Generate multi-size favicon.ico from an imagedirtypdf <input.pdf> <output.pdf>- Apply scanner effect to a PDF
Development & Git
gg <repo-url>- Clone repo and cd into itaic- Generate conventional commit message using LLMs from staged changese [file]- Edit file with$VISUAL, or open current directory if no arguments <pattern>- Search in files and visualize with Delta
Directory & File Management
take <dir>- Create directory and cd into it (equivalent tomkdir -p && cd)tt- Create and cd into a temporary directorycdls <dir>- Change to directory and list its contentsdecrypt_pdfs <password>- Decrypt all PDFs in current directory
Network & Diagnostics
t <host>- Traceroute with Trippy (auto-updates GeoIP database)tu <host>- UDP traceroute with Trippyhttps <domain> [port]- Show TLS certificate details (default port: 443)ttfb <url>- Measure Time To First Byte with curllistening [pattern]- List all processes listening on TCP portspingu <host>- Ping until success or cancelledlip <ip>- Lookup IP address detailsdns <domain>- Lookup IP address of domain's A record
Nix Utilities
nix-pkgdir <package>- Get the Nix store path for a packagenr <package> [args...]- Run a package from nixpkgs-unstable without installingns <pkg1> [pkg2...]- Start a shell with packages from nixpkgs-unstable
Commonly used commands baked into [justfile](justfile)
# Switch darwin configuration
just switch
# Updates all flake inputs
just update
# Updates one flake input
just update-input <flake-input-name>
# For more, run `just` to get all receipes.Installation instructions on a new macOS machine without Nix installed
Note:
- I currently use macOS Sequoia 15.7.3.
- Full Disk Access has to be enabled for the terminal app via
System Settings > Privacy & Security > Full Disk Accessto overcomeCould not write domain com.apple.universalaccess; exitingwhen applying user defaults.
xcode-select --install
# Clone the dotfiles
mkdir $HOME/.config
git clone https://github.com/birkhofflee/dotfiles $HOME/.config/dotfiles
# Install nix using the official beta intaller
# The Lix installer could also be used: https://lix.systems/install/#on-any-other-linuxmacos-system
# @see https://github.com/nix-darwin/nix-darwin/issues/1588
# @see https://github.com/NixOS/nix-installer?tab=readme-ov-file#installation-nix-installer-install
curl -sSfL https://artifacts.nixos.org/nix-installer | sh -s -- install \
--explain --no-confirm --extra-conf "trusted-users = $USER"
# Source the nix daemon so that the nix command is available immediately
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
# Temporarily mitigate 'too many open files' issue
# @see https://github.com/NixOS/nix/issues/6557
ulimit -n 4096
# Activate the configuration
nix run nixpkgs#nh -- darwin switch $HOME/.config/dotfiles --hostname AlexMBP --accept-flake-configNixOS Homelab provisioning instructions
nixos-anywhere is used to remotely setup NixOS host. The machine to provision should be running Linux with kexec support, or simply a minimal NixOS installer.
nixos-facter is used in conjunction to dynamically determine configurations from hardware.
# CAUTION: This IMMEDIATELY erases target host, repartitions it, installs NixOS
# and applies this flake configuration.
nix run github:nix-community/nixos-anywhere -- \
--generate-hardware-config nixos-facter ./hosts/homelab-nuc/facter.json \
--flake .#homelab-nuc \
--target-host root@<machine-ip> \
--build-on remoteTo apply new flake config, use the just receipe:
just switch-homelabNixOS VM bootstrap instructions on macOS (VMware Fusion)
During my test, it appears that NAT DHCP in VMWare Fusion 13.6.4 doesn't work; use 13.6.3 instead (on macOS Sequoia 15.6.1).
Note that a desktop environment is yet to be properly implemented.
My personal settings are hardcoded in the justfile, you should inspect and modify accordingly, otherwise it is going to fail. After that, proceed to follow the instructions on configuring VMWare Fusion, which can be found in this YouTube video by Mitchell.
After setting the root password, execute the following to bootstrap the VM automatically:
# This will run `./vm-installer.sh`, that erases the disk, makes partitions on it, configures Nix for the next step.
$ just vm-bootstrap0 <vm-ipv4-address>
# Ensure the VM reboots into the disk instead of the installer.
# After that, run this to initiate the flake switch:
$ just vm-bootstrap <vm-ipv4-address>
# When it finishes, you will be able to SSH into the machine:
$ just vm-ssh [user]NixOS VM bootstrap instructions on macOS (OrbStack)
Note that there's no GUI support on OrbStack Linux VMs. This setup focuses on usage only via SSH. It's fairly simple to setup on OrbStack compared to doing that on VMWare Fusion. This dotfiles intends to use the default system configurations provided by OrbStack, since it's heavily customized to be used with macOS shell.
# Ensure OrbStack is running, and create the VM:
$ just orb-create
# After that, simply run this to bootstrap it:
$ just orb-configureRepairing the Nix setup on macOS after a major update from Apple
The following steps were applicable to installations with upstream Nix installations. It is unknown whether they are needed to follow for a Determinate Systems installation.
- Upgrade Xcode CLI tools
- Uninstall nix: https://nix.dev/manual/nix/2.18/installation/uninstall.html#macos
- A system restart may be required
- Review CHANGELOG of nix-darwin
# Install nix
bash <(curl -L https://nixos.org/nix/install) --daemon --yes --no-modify-profile
# Propagate /run
printf 'run\tprivate/var/run\n' | sudo tee -a /etc/synthetic.conf
/System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t
# Fix certs (the uninstallation of nix breaks a symbolic link)
# https://github.com/NixOS/nix/issues/2899#issuecomment-1669501326
# https://discourse.nixos.org/t/ssl-ca-cert-error-on-macos/31171/1
sudo rm /etc/ssl/certs/ca-certificates.crt
sudo ln -s /nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt /etc/ssl/certs/ca-certificates.crt
nix build "$HOME/.config/dotfiles#darwinConfigurations.AlexMBP.system" --extra-experimental-features "nix-command flakes"
sudo ./result/sw/bin/darwin-rebuild switch --flake "$HOME/.config/dotfiles#AlexMBP"- Development Environments should be managed using nix-shell.
- Supercharge has to be downloaded manually due to licensing constraints.
- While I'd like Nix to handle every app on my Mac, most GUI apps are better managed by Homebrew due to the conflicting nature of Nix and the self-updating capabilities of those apps.
Here are some reads you might find interesting:
- Faster and enjoyable ZSH (maybe)
- Comparison of ZSH frameworks and plugin managers
- fzf examples (fzf wiki)
- A simple dotfiles template to kick-start/bootstrap your zsh config
Some completions setups:
- https://github.com/mashehu/dotfiles/blob/236af8d7d71989f9755a6ea29ee66e33cbbce1f8/zshrc#L89-L105
- https://github.com/finnurtorfa/zsh/blob/master/completion.zsh
This project was heavily inspired by other open-source dotfiles. A non-exhaustive list:
- https://github.com/mitchellh/nixos-config
- https://github.com/malob/nixpkgs
- https://github.com/ahmedelgabri/dotfiles
- https://github.com/kornicameister/dotfiles/
- https://github.com/Aloxaf/dotfiles/tree/master/zsh/.config/zsh
- https://github.com/paulmillr/dotfiles
- https://github.com/mashehu/dotfiles
- https://github.com/finnurtorfa/zsh
Credits are given in the source code where applicable.
This project is released under the MIT License.
