My repeatable Apple Silicon macOS setup, built with Determinate Nix, nix-darwin, Home Manager, Homebrew, and the Mac App Store.
The repository contains the public machine configuration. Private identity,
account metadata, keys, and sync settings are restored from the dedicated
Mac Setup vault in 1Password and never stored in Git.
Before starting:
- finish macOS updates and enable FileVault;
- use macOS 27 or later for the native menu-bar workflow;
- use the intended local administrator account;
- sign in to the Mac App Store; and
- make sure the required 1Password items are recoverable.
Open Terminal and paste:
/usr/bin/curl -qfsSL --proto '=https' --tlsv1.2 \
https://raw.githubusercontent.com/philippgerard/mac-setup/main/setup.sh \
| /bin/bash -pThis checks the Command Line Tools, creates a transactional checkout of the
current main commit at ~/.config/mac-setup, installs Homebrew and Determinate
Nix when needed, validates the checkout, and builds the configuration. It does
not activate the build yet. Setup records the exact commit it checked out in
.local/bootstrap-revision for later auditing.
The developer-tool check compiles a small C translation unit against the selected macOS SDK. After an OS upgrade, update Command Line Tools or Xcode and complete Xcode's first-launch prompts if this check fails.
If macOS opens the Command Line Tools installer, finish it and leave Terminal open; setup waits and continues automatically. The Homebrew installer remains interactive even though the outer bootstrap is piped, so follow its Terminal prompts. After the checkout exists, any Homebrew or Nix failure prints an exact local command to resume. Setup waits for the Nix daemon itself; a Terminal restart is not part of the normal flow.
After the build succeeds and its changes look right, run:
"$HOME/.config/mac-setup/setup.sh" --provisionProvisioning validates, builds, and switches the configuration in one pass, then starts the guided prompts. These connect 1Password, restore Git identity, personal Mail and configured DAV services, check and restore any missing declared S/MIME identities in the login keychain, restore legacy GPG keys and Filen Menubar configuration, launch Filen Menubar, and open the macOS profiles that require approval. Filen authentication uses the application's in-app Login flow when needed.
The flow is resumable. If activation stops for App Management permission,
enable the terminal in System Settings > Privacy & Security > App
Management, quit and reopen Terminal, then run the setup command printed with
the error. Once base activation has completed, an interrupted profile approval
or sign-in resumes only the private restore; run the exact
scripts/finish-setup command printed with that error instead of provisioning
again.
That is the regular fresh-Mac setup.
Provisioning selects only personal-mail by default. To add another saved
account on this Mac, list every account you want:
"$HOME/.config/mac-setup/setup.sh" --provision -- \
--mail-account personal-mail --mail-account work-mailRun ~/.config/mac-setup/scripts/finish-setup --help for account, vault, and
skip options. See Mail and account setup for profile,
password, Microsoft 365, and migration details.
- macOS defaults, Fish, Git/SSH policy, tmux, Otty, and editable Zed settings
- the pinned CLI and development toolchain
- GUI and Mac App Store applications from the configured profiles
- Filen Menubar with its bundled patched sync backend and Node runtime
- private Git and GPG state, password-free Mail/DAV metadata, and Filen configuration from 1Password
The complete application policy is in the app inventory. App Store and application sign-ins, Apple privacy approvals, browser sessions, private repositories, and other vendor-managed state still require their supported restore flows.
From ~/.config/mac-setup:
# Check the repository and configuration
scripts/validate
# Build without changing the live system
scripts/rebuild build
# Review package and Homebrew/MAS declaration changes before activation
scripts/rebuild preview
# Build and activate local changes
scripts/rebuild switch
# Intentionally update pinned Nix inputs, Filen Menubar, and OMC, then build
scripts/update
# Check installed state without restoring or changing it
scripts/doctorHomebrew and Mac App Store application removal is never automatic. Review
scripts/homebrew-dry-run before removing software.
- Clean-install runbook — extended setup, approvals, alternative flows, and interruption recovery
- Mail and account setup — IMAP/DAV, iCloud restrictions, Microsoft 365, MFA, and profile migration
- Private state — 1Password items, Git/GPG identity, SSH hosts, and backup boundaries
- Architecture and bootstrap safety — repository layout, checkout and resume safety, source filtering, and activation design
- Maintenance — updates, Topgrade, Homebrew, and mutable application settings
- Post-install verification — thorough automated and manual checks
- Disposable-Mac rehearsal — first activation, interrupted restore, and repeated activation
- Pre-wipe checklist — required checks before erasing an existing Mac
- Public release safety — PII and Git-history policy