A public, multi-host Nix configuration for reproducible Macs today and NixOS servers later.
It combines Nix flakes, nix-darwin, Home Manager, and declarative Homebrew. Nix owns portable tools and user configuration; Homebrew owns native/vendor macOS applications; 1Password owns secrets and SSH private keys. There is no chezmoi layer.
Status: activated and verified on one Apple Silicon Mac. New hosts must still complete validation and the interactive post-install checklist.
- macOS defaults, Dock contents, fonts, and native applications;
- Nix-managed Zsh, Starship, Git, developer tools, and Herdr;
- Karabiner keyboard rules and LinearMouse configuration through Home Manager;
- public-safe Git identity inputs and 1Password references;
- dormant shared AI renderers that remain disabled in the basic profile.
The precise ownership model is documented in
docs/architecture.md. The canonical package lists are
the Nix modules themselves.
.
├── ai/ # Shared, currently dormant AI sources
├── docs/ # Setup, operations, architecture, and research
├── hosts/ # Host compositions
├── modules/
│ ├── darwin/ # macOS, Nix, Dock, fonts, and Homebrew
│ └── home/ # Home Manager user configuration
├── profiles/ # Reusable user profiles
├── secrets/ # 1Password and secret-boundary reference
├── flake.nix
└── local.example.nix # Generic, public host-input template
The repeatable setup wizard handles the two-pass bootstrap:
./scripts/setup-mac.sh-
In Setup Assistant, create the account with the same short name as the old Mac (the computer name can be anything; the configuration never uses it).
-
Plug in the external
Datadrive and join the network the 1Password Connect server is on. -
In Terminal, run:
curl -fsSL https://raw.githubusercontent.com/DivMode/nix-config/main/scripts/bootstrap.sh | bash -
Type your Mac password once. When asked, paste the two Connect values, both in 1Password (on a phone is fine; copy there, then Cmd-V on the Mac):
- Connect URL: open the Secure Note
nix-config local.nixand copy the value ofonePassword.connectHost(anhttp://…:8091address). - Connect token: search 1Password for "Connect", open the Connect
server's credentials item, and copy its
access-tokenfield.
- Connect URL: open the Secure Note
-
Grant the Karabiner and LinearMouse permissions it lists at the end.
It installs the Command Line Tools and Nix, clones this repository, and runs the
setup wizard, which asks only for the 1Password Connect URL and token, restores
local.nix from its 1Password Secure Note, and applies everything. Details: docs/setup/new-mac.md.
The manual short path is:
-
Install Nix and clone the repository. Do not install 1Password manually.
-
Create the ignored host input. For the first pass, replace only the Mac account, architecture, and home-directory placeholders; leave the public Git/1Password bootstrap placeholders until Nix installs 1Password:
cp local.example.nix local.nix export NIX_CONFIG_LOCAL="$PWD/local.nix"
-
Validate and build without changing the Mac:
nix fmt nix flake check --impure nix build --no-link --impure \ .#darwinConfigurations.example-mac.system -
Review the result. On a new Mac, use the first-generation command in the setup guide. On an existing nix-darwin host, switch deliberately:
sudo env NIX_CONFIG_LOCAL="$NIX_CONFIG_LOCAL" \ /run/current-system/sw/bin/darwin-rebuild switch --impure \ --flake "path:$PWD#example-mac"
Do not put passwords, tokens, SSH private keys, recovery material, or private
repository information in local.nix. The ignored file contains host identity,
public Git metadata, and an SSH public signing key only.
The everyday operations are:
nix flake check --impure
nix build --no-link --impure .#darwinConfigurations.example-mac.system
./scripts/rebuild.shscripts/rebuild.sh is the activation path. It builds first, then activates
without a password: declared sudoers rules (modules/darwin/sudo.nix) allow
exactly the darwin-rebuild activation command for this account, plus
/usr/sbin/installer and /usr/sbin/pkgutil for the privileged installers
Homebrew nests inside brew bundle, so rebuilds run unattended from any shell.
Anything else under sudo still prompts — the askpass dialog remains as the
fallback (and covers the one first switch on a wiped machine, before the rules
exist). Do not hand-assemble the darwin-rebuild switch command.
To move the pinned inputs forward and apply the result in one step, type
nixup (a shell alias for scripts/update.sh; arguments pass through):
nixup # every input and every pin
nixup codex # ChatGPT/Codex: the cask definition, and where the app stands
nixup gcx # gcx: its release tag and Go vendor hash
nixup homebrew-cask # any flake input, by its nameVersions live in flake.lock; the script moves it and it is not edited by
hand. Two things update themselves instead: Claude Code, whose native install
keeps itself current in the background (claude update forces it), and
ChatGPT.app, which carries the codex CLI — launching it is the update, and
the script reports where it stands.
Format and inspect changes before switching. Lock updates and detailed operating
procedures are in docs/operations/rebuild.md.
macOS and third-party security controls require these one-time interactive steps:
- nothing for 1Password: everything reads it through Connect, set up by the wizard;
- complete the Karabiner and LinearMouse approvals;
- disable Raycast's native Hyper Key;
- verify Git identity and a signed test commit before publishing;
- confirm the declared Dock, Finder, keyboard, terminal, and mouse behavior.
Nix does not bypass macOS privacy controls or manufacture authentication sessions.
The repository rebuilds declared packages and configuration. It does not rebuild
chat history, browser profiles, application databases, authentication sessions,
Keychain contents, caches, or mutable terminal sessions. See
docs/state-boundary.md.
- New Mac setup
- Rebuild and activation
- Local CLIProxyAPI and CPA Manager Plus
- Architecture and ownership
- Orchestration architecture
- Mutable-state boundary
- macOS and Homebrew
- Karabiner keyboard
- Application launcher hotkeys
- Terminal and Zsh
- Developer tools
- Mouse
- AI source model
- 1Password and secrets
- Research notes
- Validate Intel Darwin if that platform is added.
- Add merge-safe adapters before enabling mutable AI client configuration.
- Add NixOS host modules when the first server is defined.