Move your whole Mac setup to a new machine without Migration Assistant or Time Machine. Capture your config on the old Mac, carry one folder across, and provision the new Mac from a manifest you control.
It is a small, dependency-light, manifest-driven engine with modular step scripts. You decide what runs by editing JSON, not by hacking the engine.
Early (0.1.x). Use it with eyes open.
What is tested: the engine’s control flow is covered by tests/run.sh and runs in CI on every push (manifest parsing, validation skip/confirm, dry-run, --only, optional vs. required failure, abort). This logic is OS-independent, so the tests run on Linux.
What is NOT yet verified: the macOS-specific commands have conventional implementations but have not been exercised on real hardware end to end. That includes the Xcode CLT install, Homebrew/MacPorts install, hdiutil encrypt/mount of the secrets bundle, defaults import, the pam_tid sudo edit, and the swiftDialog UI. Always run --dry-run first and treat your first real run as a rehearsal on a spare Mac or VM.
Tested on (verified end to end):
| macOS | Chip | Package manager | By |
|---|---|---|---|
| none yet |
If you run it for real, a PR adding a row here is the most valuable contribution you can make.
~/.config, a Homebrew Brewfile, editor settings + extension lists, app preference plists, macOS system defaults, and browser bookmarks. Secrets (SSH/GPG keys, tokens) go into an AES-256 encrypted disk image, never plaintext.The repo is the tool. Your captured config is data, kept in a separate directory so you can carry it between machines (a cloud-synced folder, a USB drive, whatever). Point at it with --data DIR or the MIGRATION_DATA environment variable. Default: ~/migration-data.
migration-machine/ the tool (this repo)
migrate entrypoint
lib/ engine + capture/restore implementations
steps/ one script per provisioning step
manifests/ example manifests (copy + customize)
docs/ RUNBOOK, MANIFEST schema
$MIGRATION_DATA/ your data (NOT in the repo)
payload/ manifest/ secrets/ logs/ backups/
On the OLD Mac:
git clone https://github.com/YOUR_GITHUB_USERNAME/migration-machine.git
cd migration-machine
./migrate --data ~/Sync/migration capture
Carry ~/Sync/migration to the new Mac (cloud sync, drive, etc.).
On the NEW Mac:
git clone https://github.com/YOUR_GITHUB_USERNAME/migration-machine.git
cd migration-machine
cp manifests/example-homebrew.json manifests/local-mymac.json # then edit it
./migrate --data ~/Sync/migration provision -m local-mymac --dry-run # preview
./migrate --data ~/Sync/migration bootstrap -m local-mymac # do it
bootstrap installs the Command Line Tools first, then provisions. If git already works, provision is enough.
migrate [--data DIR] capture export this Mac's config (OLD Mac)
migrate [--data DIR] provision -m MANIFEST provision from a manifest (NEW Mac)
migrate [--data DIR] provision --list list available manifests
migrate [--data DIR] provision -m M --dry-run preview, change nothing
migrate [--data DIR] provision -m M --only ID run a single step
migrate [--data DIR] restore --only PHASE restore captured config only
migrate [--data DIR] bootstrap -m MANIFEST ensure Xcode CLT, then provision
MIGRATE_UI=cli|gui|auto force the progress UI (default auto)
A manifest is a config object plus an ordered list of steps, each with a validation check and a required flag. Copy an example, point dotfilesRepo at your own repo, and edit the steps. Full schema in docs/MANIFEST.md. Keep your real manifest private; local-*.json is gitignored.
.dmg. Its safety is your passphrase. Use a strong one and store it in a password manager.sudo. The GUI shows progress but does not collect the passphrase.Re-granting app permissions (Full Disk Access, Accessibility, Screen Recording), app sign-ins, license keys, and Keychain are not automated by design. See docs/RUNBOOK.md for the manual checklist.
The design borrows ideas from three excellent projects: the manifest-of-steps with per-step validation and a swiftDialog progress UI is inspired by Setup Your Mac; the modular provisioning scripts and curl-able bootstrap echo boblbee; the clone-and-symlink, Brewfile-driven config model is the common dotfiles pattern. Code here is original; the good ideas are theirs.
MIT. See LICENSE.