setup-macos-developer
Automate your macOS dev environment with one idempotent, opinionated script.
git clone https://github.com/fernandofatech/setup-macos-developer.gitsetup-macos-developer is an idempotent Bash script that provisions a complete macOS development environment from scratch — shell, languages, cloud CLIs, and productivity tools — with a single command.
Why this repository exists
Every time I switch machines, receive a new MacBook, or need to rebuild an environment after a system reinstall, the cost of manually reconfiguring everything — Homebrew, language runtimes, AWS CLIs, terminal tooling, dotfile settings — is high and prone to inconsistency. The standard industry answer is to automate it once and reuse it always.
This repository is my personal answer to that problem. It captures the choices I make as a senior solutions architect: which tools to install, in what order, and with which default settings. It is not a generic framework — it is a set of explicit decisions that reflect my actual workflow across AWS, cloud development, security, and data platforms.
The central principle is idempotency: running the script a second or tenth time breaks nothing, duplicates no installations, and does not overwrite local settings you intentionally changed. That makes the script safe for ongoing use, not just initial setup.
What the script covers
How the script works — execution flow
main.sh acts as the orchestrator: it calls specialized modules in sequence, each responsible for one layer of the environment.
- main.sh · orchestrator
- Homebrew · bootstrap
- Shell & dotfiles · module
- Languages · module
- Cloud CLIs · module
- Productivity · tools module
- Homebrew · registry
- GitHub · (repo clone)
Installation and usage
- 1
Prerequisite: macOS with internet access
The script assumes a clean or existing macOS install. You do not need to install Homebrew manually — the script handles that. You only need internet access and permission to run scripts with
sudowhen prompted. - 2
Clone the repository
Clone to any local directory. The script does not need to be in a specific path.
- 3
Make the script executable
The
chmod +x *.shcommand ensures all Shell modules in the repository have execute permission. Do this before running any script. - 4
Run the main script
Run
./main.shand follow the output. The script will check what is already installed, install what is missing, and configure dotfiles. You may be prompted for your administrator password at certain points. - 5
Re-run when needed
Thanks to idempotency, you can run
./main.shagain after adding new tools to the script or when setting up a new machine. Repeated runs are safe.
# 1. Clone the repository
git clone https://github.com/fernandofatech/setup-macos-developer.git
cd setup-macos-developer
# 2. Make all shell scripts executable
chmod +x *.sh
# 3. Run the main orchestrator
./main.sh
# The script will:
# - Install Homebrew if not present
# - Configure your shell environment
# - Install language runtimes via Homebrew
# - Install cloud CLIs (e.g. AWS CLI)
# - Install productivity tools and applications
#
# Re-running is safe — already-installed items are skipped.
./main.sh # idempotent: run again anytimeHow the script works internally
The entry point is main.sh, which acts as the orchestrator. It calls specialized modules in a deterministic sequence — first the Homebrew bootstrap, then shell configuration, language runtimes, cloud CLIs, and finally productivity tooling. That order matters: each layer depends on the one before it.
Idempotency is implemented through explicit checks before each operation. Before installing a package, the script checks whether it already exists. Before writing a configuration, it checks whether it is already present. This is done primarily through commands like brew list, command -v, and string comparisons against existing config files.
Homebrew is the central delivery mechanism for nearly everything: formulae for command-line tools, casks for macOS applications, and possible taps for third-party sources. This keeps package management uniform and auditable — you can inspect what was installed with brew list at any time.
The modular structure means adding or removing tools is straightforward: you edit the relevant module without touching the orchestrator. If you do not need a specific toolset, you can comment out the corresponding call in main.sh before running.
Customizing for your workflow
This script reflects my personal choices as a solutions architect. If you want to adapt it, the simplest starting point is editing the individual modules to add or remove Homebrew packages. You do not need to understand the orchestrator to do that. Preserve the check-before-install pattern to maintain idempotency.
Frequently asked questions
Does the script work on Apple Silicon (M1/M2/M3)?
Homebrew has native Apple Silicon support since 2021, installing to /opt/homebrew instead of /usr/local. Well-written Bash scripts that delegate to Homebrew work on both architectures. If you encounter architecture-related issues, open an issue on the repository.
Is it safe to run on a machine that already has tools installed?
Yes. That is the central purpose of idempotency. The script checks what already exists before acting. Already-installed tools are skipped. Existing configurations are not destructively overwritten.
Can I use this as a base for my own setup?
Yes, the project is MIT licensed. Fork it, adapt the modules to your needs, and remove tools that are not part of your workflow. The orchestrator + modules pattern is deliberately simple to make customization easy.
Does the script require sudo?
Some steps may prompt for your administrator password — primarily the Homebrew installation itself and possibly certain cask installations. The script should not run entirely as root; it will request elevation only when needed.
Who this repository is for
This repository is useful for any software engineer or architect who works primarily on macOS and wants to eliminate the friction of setting up a new environment. It is especially relevant if your workflow involves AWS and cloud CLIs, development across multiple language runtimes, or if you simply change machines frequently enough that manual setup is a real cost. It is not a universal solution. The tools and configurations reflect my personal choices. If your stack is quite different, you will spend some time adapting the modules — but the structure and idempotency patterns are reusable. For anyone who wants to learn how to structure dotfile automation cleanly in pure Bash with Homebrew, this repository also serves as a concrete, readable example.