\ \ \
\ \ \
_ _ _ _\_\_\___
_ __ ___ __ _ ___ ___ _ __ ___ (_) |_| |__ | |
| '_ ` _ \ / _` |/ __/ __| '_ ` _ \| | __| '_ \ | |
| | | | | | (_| | (__\__ \ | | | | | | |_| | | | **|_________|
|_| |_| |_|\__,_|\___|___/_| |_| |_|_|\__|_| |_| * * **
* ** *
⚒ forge your Mac ⚒ * *
Forge a fresh Mac into a complete dev box — and keep it sharp.
One command installs Homebrew, Starship, language toolchains, and optional sysadmin profiles. A second command (update) keeps everything current.
Pin to a release (recommended):
curl -fsSL https://raw.githubusercontent.com/26zl/macsmith/<TAG>/bootstrap.sh \
| MACSMITH_REF=<TAG> zshOr clone and review:
git clone https://github.com/26zl/macsmith.git
cd macsmith
./install.sh
./dev-tools.sh # optional language toolchainsPick a tag from Releases.
update [target] # upgrade everything (default) or a single target: brew/node/python/ruby/rust/swift/go/dotnet/nix/mas (try: update help)
verify # health-check every installed tool
versions # print versions on one screen
doctor # diagnose common setup issues (read-only)
upgrade # pull the latest macsmith release (SHA-256 verified against the release checksum)
sys-install # re-run install.sh (add/remove sysadmin profiles, pick up core updates)
dev-tools # re-run dev-tools.sh (add/remove language toolchains)
uninstall-profile # brew-uninstall a sysadmin profile's packages (power-user/crypto/netsec/devops/databases)
uninstall-nix # bundled macOS Nix uninstaller (--dry-run / --yes)
uninstall-macsmith # remove macsmith itself (keeps Homebrew, language tools, your customizations)
reload # reload ~/.zprofile and ~/.zshrc after editing either
Everything optional is behind a y/n prompt with a sensible default (press Enter to accept). Defaults shown in brackets.
Installed automatically (core shell foundation):
- Xcode Command Line Tools, Homebrew, Starship prompt, zsh-syntax-highlighting, zsh-autosuggestions (both via Homebrew, no Oh My Zsh), FZF
- The
macsmithmaintenance binary at~/.local/bin/macsmith - A managed
~/.zshrc(your existing one is backed up with a timestamp)
Asked per tool during ./install.sh:
- macOS package sources:
mas[N],MacPorts[N],Nix[N] - Sysadmin profiles: power-user CLI [Y] (btop, ripgrep, bat, gh, lazygit, tmux, neovim, …), crypto/secrets [Y] (age, sops, gnupg, pinentry-mac), netsec [N] (nmap, masscan, iperf3, Wireshark), devops/SRE [N] (kubectl, Terraform via HashiCorp tap, ansible, awscli, orbstack, …), databases [N] (mysql, postgresql)
Asked per tool during ./dev-tools.sh:
- Languages [Y]: Python (pyenv + pipx + uv), Node (nvm + pnpm + bun), Ruby (chruby + ruby-install), Rust (rustup), Go
- Languages [N]: Swift (swiftly), Java (openjdk), .NET SDK, Conda/Miniforge, deno
- JVM extras batch [N]: Kotlin, Scala, Clojure, Gradle, Maven, Groovy
Maintenance: update keeps every formula, cask, and language runtime current; verify shows gaps. Project-local files (package.json, go.mod, .swift-version, …) are never touched.
Concrete footprint before you commit to curl | zsh. Everything destructive to existing files creates a timestamped backup first.
Always written (critical install, no prompt):
~/.zshrc— overwritten with macsmith's shell config. Previous file saved to~/.zshrc.backup.YYYYMMDD_HHMMSS. User-definedalias/exportlines are harvested into~/.zshrc.local(secret-shaped exports —*_TOKEN,*_SECRET,*_KEY— are deliberately skipped).~/.zprofile— managed block appended between# FINAL PATH CLEANUPand# End macsmith managed blockmarkers. Previous file saved to~/.zprofile.backup.YYYYMMDD_HHMMSS.~/.local/bin/— adds 3 binaries:macsmith,uninstall-nix-macos,uninstall-macsmith.~/.local/share/macsmith/— created. Stores install-state marker, version file, and mirror of all repo scripts (used byupgradeanduninstall-macsmith).~/.config/starship.toml— written only if missing. Existing configs are never overwritten.- Homebrew — installed at
/opt/homebrew(Apple Silicon) or/usr/local(Intel) if not already present. The Homebrew installer itself requestssudo.
Written only if you say yes (per-tool [Y]/[N] prompt):
- Homebrew packages, by profile:
power-user[Y]: 24 formulae (btop, ripgrep, bat, gh, lazygit, tmux, neovim, chezmoi, …)crypto/secrets[Y]: 4 formulae (age, sops, gnupg, pinentry-mac)netsec[N]: 3 formulae + 1 cask (nmap, masscan, iperf3, Wireshark app) — strictly network-layer tools; web-app / DB-exploit scanners are deliberately excludeddevops/SRE[N]: 17 formulae + 3 casks (kubectl, Terraform viahashicorp/tap, ansible, awscli, docker, orbstack, google-cloud-sdk, multipass, …)databases[N]: 2 formulae (mysql, postgresql@17)
- Language toolchains (via
./dev-tools.sh, each one its own[Y]/[N]prompt):- Python →
~/.pyenv/ - Node.js →
~/.nvm/ - Ruby →
~/.rubies/,~/.local/share/chruby/,~/.local/share/ruby-install/ - Rust →
~/.rustup/,~/.cargo/ - Swift →
~/.swiftly/ - .NET →
/usr/local/share/dotnet/(via brew cask;sudofor first install) - Java (OpenJDK), Go, Conda/Miniforge, uv, bun, pnpm, deno — individual prompts
- Python →
- MacPorts →
/opt/local/. Every install and every update needssudo. - Nix →
/nix/APFS volume +/etc/nix/+LaunchDaemons+_nixbld1..32users +nixbldgroup + edits to/etc/synthetic.confand/etc/fstab. System-wide, daemon-based,sudorequired, 10–20 min. Largest footprint of anything we offer.
Never touched:
- Existing Homebrew formulae/casks you installed yourself (
updateonly upgrades; never uninstalls). - Project-local files (
package.json,Gemfile,go.mod,.swift-version,.python-version,.nvmrc, …). - System Ruby at
/usr/bin/ruby, system Python, macOS defaults, login items. ~/.ssh/,~/.gnupg/,~/.aws/, and everything in~/.config/exceptstarship.tomlwhen it's missing./Applications/,/Library/,/System/.
Reversing it:
uninstall-macsmith— removes the 3 binaries,~/.local/share/macsmith/, the managed.zprofileblock, and offers to restore~/.zshrcfrom the oldest non-macsmith backup. Does NOT touch Homebrew or language toolchains.uninstall-profile <name>—brew uninstalla sysadmin profile's formulae + casks.uninstall-nix— full Nix removal including the APFS volume (the volume-delete step always requires typingyes—--yeson everything else, never there).- Language toolchains: removed by their own tools (
rm -rf ~/.pyenv,brew uninstall go,rustup self uninstall, …).
| Tool | macsmith adds |
|---|---|
brew bundle |
Language version managers, shell config, an update that understands every ecosystem |
chezmoi |
macsmith installs chezmoi itself for dotfile sync — they're orthogonal |
nix-darwin |
No Nix language to learn; imperative but idempotent |
| Your own dotfiles repo | A starting point + a maintenance loop. Fork it |
MACSMITH_REF=<tag>— pin the bootstrap to a specific release (reproducible installs)MACSMITH_UPDATE_CHECK=1— opt in to a daily update check on shell start (off by default)NONINTERACTIVE=1— auto-answer "yes" to every prompt (for CI / unattended re-runs)MACSMITH_FIX_RUBY_GEMS=1— auto-fix Ruby gem permissions duringupdate(on by default; set0to disable)
macsmith manages ~/.zshrc. Put your aliases and exports in ~/.zshrc.local — it's sourced last so your edits survive reinstalls. Fresh installs also harvest existing alias/export lines from your old ~/.zshrc into ~/.zshrc.local automatically; secret-shaped exports (*_TOKEN, *_SECRET, *_KEY, …) are deliberately skipped — grab those from the timestamped backup next to your new ~/.zshrc.
Prompt themes: starship preset --list to browse, starship preset <name> -o ~/.config/starship.toml to apply. Examples: tokyo-night, gruvbox-rainbow, pastel-powerline, catppuccin-powerline, pure-preset.
brew install --cask ghostty
mkdir -p ~/.config/ghostty
cp "Ghostty config.txt" ~/.config/ghostty/config
cp background/terminal-background.png ~/.config/ghostty/terminal-background.pngThe bundled config auto-installs macsmith's terminfo over SSH, so xterm-ghostty: unknown terminal type never appears on remote hosts.
macOS 13 Ventura or later. Apple Silicon or Intel. That's it.
Two bundled scripts, both defensive with --dry-run and --yes flags. Run --dry-run first to see exactly what will change.
uninstall-macsmith removes what macsmith installed (binaries in ~/.local/bin/, ~/.local/share/macsmith/, the managed PATH block in ~/.zprofile) and offers to restore ~/.zshrc from the oldest non-macsmith-managed backup (skips .zshrc.backup.* files that look like they were made by a prior macsmith run so you get your original pre-macsmith config, not a macsmith template). Also offers to remove ~/.config/starship.toml. It keeps Homebrew, any installed formulae/casks, language toolchains (pyenv/nvm/chruby/rustup/swiftly/go/…), ~/.zshrc.local, and every file you created.
uninstall-macsmith --dry-run # show what will change
uninstall-macsmith # interactive
uninstall-macsmith --yes # non-interactiveuninstall-nix cleanly removes a multi-user Nix install: launch daemons, _nixbld* users, /etc/nix, /etc/synthetic.conf, /etc/fstab, and the Nix Store APFS volume. Auto-detects the Determinate Systems installer and prefers sudo /nix/nix-installer uninstall when present.
uninstall-nix --dry-run
uninstall-nix
uninstall-nix --yesBoth scripts are installed to ~/.local/bin/ by ./install.sh. From a clone, you can also run ./scripts/uninstall-macsmith.sh or ./scripts/uninstall-nix-macos.sh directly. macOS-only. The Nix script re-execs under sudo; the APFS volume deletion always requires interactive confirmation typed as yes — --yes on uninstall-nix skips the other prompts but never that one. Read the scripts before running. A reboot is recommended after uninstalling Nix.
MIT.
If macsmith saved you an afternoon, a ⭐ is the tip jar.
