setup-macos-developer
Your engineering Mac as code: Homebrew, dotfiles and defaults, reproducible in Bash
git clone https://github.com/fernandofatech/dot-setup-macos-developer.gitListen to guide
generated on playGenerated only on first play
Powered by Amazon Polly + OmniVoice
Bash scripts that turn a freshly wiped Mac into a predictable engineering workstation — Homebrew, dotfiles and macOS defaults applied in the same order, as many times as needed.
Why it exists
After years of switching machines — personal laptop, client laptop, lab Mac Mini — the bill I kept paying wasn't the day lost installing tools. It was the following week: finding out git had a different alias, node was a two-year-old version, the terminal didn't have the same theme and every command felt foreign. A hand-built environment isn't slow — it's irreproducible.
This repository solves that in the simplest way that still works: versioned Bash scripts that describe the workstation as code. Homebrew installs whatever is installable as a package; dotfiles carry shell, git and editor configuration; what's left are macOS tweaks I click through today and won't remember tomorrow.
The success criterion: run the same command on two Macs and end up with the same environment. Not "similar" — the same. If one machine drifts, the fix goes into the repository, not into the terminal history of a single machine.
It is not a dotfiles framework. Several exist, some excellent, and all of them charge a learning cost I didn't want to pay for something I run a few times a year. Plain Bash is what any engineer reads in five minutes.
What it covers
~/.zshrc, ~/.gitconfig and friends) linked by symlink, so editing the repository is editing the machine.fernandofatech/platform.Flow of one run
The main script drives three fronts in the same order every time: packages, dotfiles, system tweaks.
- Script de bootstrap · ordena os passos
- Lista de pacotes · formulae + casks
- Dotfiles · zsh, git, editor
- Ajustes do macOS · `defaults write`
- Homebrew · /opt/homebrew ou /usr/local
- $HOME · symlinks para os dotfiles
- Preferências do sistema · Finder, teclado, Dock
How it works
Order matters and it is the same on every run. First the script checks whether Homebrew exists and installs it if not — nothing else runs without it, so it is step zero. Next comes the package list: command-line formulae and application casks, which Homebrew processes in one batch. Only then are the dotfiles linked into $HOME by symlink, because several of them reference binaries that were just installed. Last, the macOS tweaks worth automating: the ones I forget, and the ones that change keyboard and Finder behavior.
Idempotency: the script was written to be re-run. An installed package is skipped, an existing symlink is not recreated, and Homebrew knows to ignore what is already at the right version. That is what lets the same repository maintain the machine, not just build it.
Bash on purpose: there is no Python, Ansible or Nix. On a freshly wiped Mac what exists is zsh, bash and curl — everything here runs on that. The price is less abstraction; the gain is that anyone can open the script and understand what it will do to the machine before running it. In a script that asks for the administrator password, that is not a detail.
Since the README is short, the source of truth for file names and flags is the repository itself. Read the main script before the first run; it is the manual.
Install and use
- 1
Clone the repository
git clone https://github.com/fernandofatech/dot-setup-macos-developer.git ~/dot-setup-macos-developer. On a new Macgitships with the Command Line Tools; macOS offers to install them on first call. - 2
Read before running
Open the main script and the package list. Remove what you don't use — the goal is your machine, not mine. Five minutes here save an hour uninstalling.
- 3
Run the bootstrap
Run the main script from the repository root. It will ask for the administrator password to install Homebrew and for the system tweaks.
- 4
Reload the shell
exec zshor open a new terminal so the dotfiles take effect. Check withbrew --versionandgit config --list. - 5
Re-run when something changes
Add a package to the list, commit, and run the script again. What already exists is skipped; only the delta is installed.
# 1. Clone
git clone https://github.com/fernandofatech/dot-setup-macos-developer.git ~/dot-setup-macos-developer
cd ~/dot-setup-macos-developer
# 2. Read what is about to run (the script is the manual)
ls -la
less ./*.sh
# 3. Run the bootstrap (asks for the admin password)
bash ./setup.sh # replace with the main script's actual name
# 4. Reload the shell
exec zsh
# 5. Verify
brew --version && brew list | head
git config --list | headThis script changes the machine
Tweaks via defaults write change system preferences and some only revert by hand. On a corporate MDM-managed Mac, check with IT first: a configuration profile can override or block what the script does, and the failure is silent — the command succeeds and the preference doesn't change.
Conventions and pipeline
The repository follows the rules of fernandofatech/platform, the same place that governs my other public projects. Branches carry a type prefix — feat/, fix/, chore/, docs/ — and commits use Conventional Commits. The version comes from the commits; nobody types a version number by hand, and that holds even for a repository of scripts.
Why so much pipeline for dotfiles: because the cost is not writing the script — it's keeping it alive for years without rot. pr-lint rejects PRs with a non-conforming title; CI runs shell lint; the security scan catches a secret pasted by mistake into a .zshrc — and a dotfile is exactly where an API token ends up "just for today". Automated release tags every relevant change, so you can tell which version of the setup built which machine.
Fixing the bar means changing one file in platform, not here. That is the gain of centralizing: a small scripts repository gets the same discipline as a service, without carrying the YAML.
If you fork, you can ignore all of this: the scripts don't depend on the pipeline. It exists for the maintainer, not for whoever runs them.
FAQ
Does it work on Apple Silicon and Intel?
Homebrew handles the difference — /opt/homebrew on Apple Silicon, /usr/local on Intel. Check with brew --prefix that your shell points at the right path. Casks that exist for only one architecture are resolved in the package list, not in the script.
Can I use just the dotfiles without installing packages?
Yes; the symlink step is independent of installation. But some dotfiles reference binaries the list installs, so expect shell warnings until you complete the rest.
How do I keep my own version without losing updates?
Fork, keep your packages and dotfiles on your branch, and rebase now and then. The split between script (mechanism) and list (content) exists so merges conflict rarely.
References
When to use it
Use it when you switch Macs with some frequency, when you maintain more than one machine and want them identical, or when you join a team and need the environment up on day one without relying on a stale wiki. Don't use it if you want a framework with plugins and themes — this is Bash and a list, on purpose. And read the script before running it: a setup that asks for the administrator password deserves five minutes of reading.
Architecture, AWS, AI and market deep dives — straight to your inbox. Free.
No spam · unsubscribe anytime