I've been refining these dotfiles since 2010. They do 80% of the work of setting up a Mac the way I like it:
xcode-select --install
git clone https://github.com/notahat/dotfiles.git ~/.dotfiles
cd ~/.dotfiles
DOTFILES_ENV=home ./installI keep them lean. Anything I stop using I delete, so what's left is what I run every day.
- A tiny install you can read.
./installruns plain-bash steps fromsteps/. It symlinks config into place, and it's idempotent, so I re-run it any time I add a step. If a config file already exists, it warns and skips rather than clobbering it. - A clear rule for Homebrew vs. Mise. Homebrew installs anything I always want at the latest version (apps, CLI tools, even Mac App Store apps). Mise manages anything I need pinned to a particular version, like language runtimes.
- Zsh that starts in under 100ms. A Starship prompt,
fzf-tab completion, and syntax highlighting, wired up by hand in
config/zsh. - Neovim, under 100ms too. LSP, Treesitter, and fuzzy finding, with the UI stripped back so the code is the only thing on screen. It's commented throughout and has its own README.
- One command to update everything.
./upgradebumps Homebrew packages, Mise tools, and Neovim plugins. - Claude Code skills, homegrown and borrowed. Mine live in
config/claude, symlinked into~/.claudealongside my settings and statusline. Other people's I pull from their source repos at install time, so I'm not redistributing anyone's work.
It's all MIT licensed, so take what's useful.
./install runs the steps in steps/, each a small bash script that
installs a tool and symlinks its config. Run them all, or one at a time:
./install # everything
./install zsh # just the zsh step
./install -h # usage, and the list of stepsThe pieces:
config/: every config file, symlinked into~and~/.configby the steps.environments/: theBrewfileandmise.tomlfor my home machine. Work machines use a different pair. See below.project-templates/: drop-in editor and tooling config for new Rails and Vite projects.
I use these dotfiles at work too, where I need a few extra tools and some config
I'd rather not publish. Rather than fork, I keep the work-only bits in a second,
private repo and set DOTFILES_ENV=ferocia (my employer) on those machines.
steps/ferocia.bash clones that repo to ~/.dotfiles-ferocia, and the other
steps pull config out of it with link_ferocia_file. So I run the same dotfiles
on both machines, and no work config lands in a public repo.