Open-source project
atomantic/dotfiles avatar
atomantic/dotfiles

atomantic/dotfiles: an interactive macOS bootstrap script for shell config and app installs

🖥️ Automated Configuration, Preferences and Software Installation for macOS

1,364 stars426 forksShellISC

At a glance

What is it?
A shell-based macOS configuration repo that symlinks dotfiles into $HOME, applies system defaults, and prompts per category to install software. It suits people who rebuild Macs often and are comfortable reviewing a script before running it with sudo.
Who is it for?
Adopt it if you rebuild macOS machines regularly, want your shell, git and macOS defaults applied from one interactive script, and are willing to read install.sh before granting it sudo. Do not adopt it if you need a non-macOS target, a declarative rollback model, or a tool that treats your machine as reproducible rather than disposable.
Can I use it commercially?
Yes. ISC is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 19 days ago.
What is it written in?
Mainly Shell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem it targets: a new Mac and a lost day

The README opens with the complaint directly: getting a new laptop or joining a new team means spending a day on system preferences and tools. The project's answer is to do that work once and encode it. Its own framing is that it started as Adam Eivy's personal macOS shell configuration and grew into what the README calls a multi-developer platform for machine configuration. The audience is narrow and stated: developers on macOS who want a command line configured a particular way, with powerlevel10k as the prompt, vim set up as a full IDE, and a set of Homebrew, npm, Mac App Store and Ruby packages installed. There is no Linux or WSL path described, and no Windows path. If your machines are not Macs, the system tweaks section does not apply to you and the value drops to the dotfile symlinking.

What install.sh actually does, step by step

install.sh is the single entry point. The README describes it as interactive, asking before each major step, and idempotent, meaning re-running it is safe and is the intended way to pick up new configuration or software. The data flow is straightforward: files in homedir/ are symlinked into $HOME, covering .zshrc, .vimrc, .gitconfig, .shellaliases and .shellfn. Before replacing anything, the script backs up existing dotfiles into ~/.dotfiles_backup/<timestamp>/, and ./restore.sh is the documented way back. It then prompts for git identity (name, email, github username) and writes that to ~/.gitconfig.local, which is untracked and pulled into ~/.gitconfig through an [include] directive, so personal details never enter the repository. It seeds machine-local override files, optionally overwrites /etc/hosts using StevenBlack/hosts with local additions expected in configs/hosts.local, applies macOS system tweaks across Finder, Dock and security, and then prompts per category to install software. Every prompt can be declined, which is what makes partial adoption practical.

The three override files and why they are the real design decision

The most considered part of this repo is the split between tracked and untracked configuration. Three files carry per-machine state: ~/.gitconfig.local, loaded via [include] in ~/.gitconfig; ~/.gitignore.local, wired through git's core.excludesfile and seeded from the shared homedir/.gitignore baseline; and ~/.zshrc.local, sourced at the end of ~/.zshrc. The README states that install.sh seeds them and then never touches them again, and that they are git-ignored. That is the mechanism that makes ./update.sh safe: tracked files in homedir/ stay clean, so pulling the latest code does not collide with your local edits. The trade-off is visible in the README's own caveat. ~/.gitignore.local is a one-time copy of the shared baseline plus your additions, so if the upstream baseline later changes, your copy does not follow it and you have to re-copy the top section by hand. That is a manual reconciliation step the project does not automate.

Getting it running: the documented commands

The README gives a three-line install. Clone with submodules, since the repo uses them, into a dotfiles directory in your home folder: git clone --recurse-submodules https://github.com/atomantic/dotfiles ~/.dotfiles, then cd ~/.dotfiles, then ./install.sh. The README adds a specific instruction about where to run it: use Terminal, not iTerm, because iTerm settings can otherwise be discarded on exit. That is a real constraint, not a stylistic preference, and it is easy to miss. For later upgrades the documented path is ./update.sh, which pulls the latest code and then runs install.sh. Restoring from a backup is ./restore.sh. After the run finishes, the README says to open iTerm preferences with Command + , and under Profiles > Colors load the Solarized Dark Patch preset, importing it from ~/.dotfiles/configs if it is not listed. It also notes you may need to select the Hack font and set the non-ASCII font to Roboto Mono For Powerline. The README recommends forking the repo rather than consuming it directly, and carries an explicit warning to review the script before running it, since it operates with sudo. The v7.0.0 release is titled Complete architectural overhaul - Zero Dependencies, which suggests the current tree does not rely on external installers to bootstrap itself, though the README still points at Homebrew for CLI tools and desktop apps.

Where it stops being the right tool

The README is unusually candid about the failure mode: the author has a high tolerance for nuking his machine and starting over, and warns that if you have a low tolerance, proceed with caution. That sentence should govern your decision. There is no dry-run mode described, no rollback beyond restoring backed-up dotfiles from ~/.dotfiles_backup/<timestamp>/, and no record of which macOS defaults were flipped, so undoing a system tweak means knowing the original value yourself. The /etc/hosts overwrite is the sharpest edge: it replaces a system file that other software may also write to, and the documented escape hatch is putting your entries in configs/hosts.local, which assumes you read that part before accepting the prompt. The project is also single-platform by construction. And because install.sh is interactive by design, it does not drop cleanly into unattended provisioning; there is no documented flag set for non-interactive execution. If you want a machine described as declarative state that can be diffed and reverted, this is not that.

How it differs from Nix-based machine configuration

The natural comparison is Nix with home-manager or nix-darwin, which models the machine as a declarative expression and builds a generation you can roll back to. The difference in approach is not cosmetic. Here, state is applied imperatively by a shell script that mutates the running system: it symlinks into $HOME, calls macOS defaults, and overwrites /etc/hosts. The backup directory is a copy, not a generation, and there is no closure describing what the machine should look like. In exchange you get something you can read in one sitting without learning a language, and it works on a factory-new Mac with nothing installed upfront, which the README states explicitly. Nix asks you to learn the expression language and often to accept a separate store; this asks you to trust a shell script and keep your own notes. Neither is strictly better. If your team already runs nix-darwin, adding this repo on top means two systems writing to the same macOS defaults, which is a conflict you would have to sequence deliberately.

Maintenance cost and the ISC licence

The maintenance surface is small but not zero. Three things need attention over time. First, the override files are yours to keep in sync manually, and the README concedes the .gitignore.local baseline does not update itself. Second, the repo depends on external moving parts it does not control: StevenBlack/hosts for the hosts file, Homebrew for CLI tools and desktop apps, npm for globals, the Mac App Store for app installs, and RubyGems. When any of those change their interface, the corresponding install step is where breakage shows up. Third, macOS itself moves; two of the three recent releases are named for Sequoia, which tells you the project tracks OS versions rather than treating them as fixed. Version numbering is worth noting: 6.0.1, then 6.1.0, then a jump to v7.0.0 described as a complete architectural overhaul, so upgrade notes matter more than usual between major versions, and the README carries a dedicated 3.x.x+ upgrade section for older installs. The licence is ISC, a permissive licence functionally similar to MIT, which permits use, modification and redistribution provided the copyright notice and permission notice are retained. That is a description of the licence text, not legal advice; if you plan to redistribute a modified fork internally, read the LICENSE file in the repo and get your own counsel.

Who should take it, and what to check first

This fits a developer who rebuilds Macs often, likes the specific toolchain the README describes (powerlevel10k, vim as an IDE, Homebrew tooling), and is comfortable reading shell before running it with sudo. It also fits a team that wants a shared baseline for git identity handling and shell config, given the .gitconfig.local pattern keeps personal data out of the repo. It does not fit anyone provisioning non-Mac hardware, anyone who needs unattended installs, or anyone who wants a reversible model of machine state. Before running ./install.sh, read it. Confirm what it writes outside $HOME, particularly the /etc/hosts replacement, and decide in advance whether you will decline that prompt. Run it from Terminal rather than iTerm as the README instructs, and check ~/.dotfiles_backup/<timestamp>/ afterwards to confirm your previous dotfiles are actually there before you rely on ./restore.sh. If you want to keep your own preferences, fork first, as the README suggests, rather than editing a clone you intend to pull from.

Editorial conclusion

Adopt it if you rebuild macOS machines regularly, want your shell, git and macOS defaults applied from one interactive script, and are willing to read install.sh before granting it sudo. Do not adopt it if you need a non-macOS target, a declarative rollback model, or a tool that treats your machine as reproducible rather than disposable. Verify first: read install.sh end to end, run it in a terminal rather than iTerm (the README warns iTerm settings can be discarded on exit), and confirm what lands in ~/.dotfiles_backup/<timestamp>/ before you accept the /etc/hosts overwrite prompt.

Official sources

  1. atomantic/dotfiles on GitHub
  2. Issues
  3. License: ISC
  4. README
  5. Releases
Community notes

Community notes