A practical guide for developers moving to a new machine or standardising their dev setup across a team.
- What are dotfiles?
- How it works
- Step-by-step setup
- Extracting installed apps from your current Mac
- Restoring on a new machine
- Pro tips & tools
Dotfiles are configuration files on Unix-based systems (macOS, Linux) whose names start with a . — like .zshrc, .gitconfig, .vimrc, or .bashrc. The dot prefix makes them hidden by default in Finder and most terminals.
They control how your shell, editor, Git, and other tools behave. A dotfiles repo collects all these config files into a single Git repository so you can:
- Version-control your environment
- Replicate your entire setup on a new machine with a single command
- Share a consistent setup across a team
| File | Purpose |
|---|---|
~/.zshrc |
Zsh shell config, aliases, PATH, functions |
~/.bashrc |
Bash shell config (if using bash) |
~/.gitconfig |
Git username, email, aliases, default branch |
~/.vimrc |
Vim editor config |
~/.config/nvim/ |
Neovim config |
~/.ssh/config |
SSH host shortcuts |
~/.config/starship.toml |
Starship prompt config |
~/.tmux.conf |
Tmux config |
⚠️ Never commit SSH private keys or API tokens. Only commit~/.ssh/config, not~/.ssh/id_rsa.
The core mechanism is symlinks. Instead of keeping config files in ~, you move them to ~/dotfiles and create a symlink at the original path pointing back to the repo.
~/.zshrc → ~/dotfiles/.zshrc (symlink)
This means:
- Your tools find the config where they expect it (
~/.zshrc) - The actual file lives inside your Git repo (
~/dotfiles/.zshrc) - Any edits are automatically tracked by Git
mkdir ~/dotfiles
cd ~/dotfiles
git initmv ~/.zshrc ~/dotfiles/.zshrc
mv ~/.gitconfig ~/dotfiles/.gitconfig
mv ~/.vimrc ~/dotfiles/.vimrc
# add any others you want to trackln -s ~/dotfiles/.zshrc ~/.zshrc
ln -s ~/dotfiles/.gitconfig ~/.gitconfig
ln -s ~/dotfiles/.vimrc ~/.vimrcThis script is what makes setting up a new machine a one-liner. Create ~/dotfiles/install.sh:
#!/bin/bash
# Install Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Install all tools and apps from Brewfile
brew bundle install --file=~/dotfiles/Brewfile
# Create symlinks
ln -sf ~/dotfiles/.zshrc ~/.zshrc
ln -sf ~/dotfiles/.gitconfig ~/.gitconfig
ln -sf ~/dotfiles/.vimrc ~/.vimrc
# add more symlinks as needed
echo "✅ Done! Restart your terminal."Make it executable:
chmod +x ~/dotfiles/install.shcd ~/dotfiles
git add .
git commit -m "Initial dotfiles"
git remote add origin https://github.com/yourusername/dotfiles.git
git push -u origin mainRun these commands on your current machine to capture everything before you switch.
# Dump all installed formulae, casks, and MAS apps into a Brewfile (recommended)
brew bundle dump --mas --file=~/dotfiles/Brewfile --force
# Or separately:
brew list --formula > ~/dotfiles/brew-packages.txt
brew list --cask > ~/dotfiles/brew-casks.txtThe Brewfile is the most important file here — it is directly replayable on a new machine.
# Requires mas-cli
brew install mas
mas list > ~/dotfiles/mas-apps.txt# Simple list
ls /Applications > ~/dotfiles/applications-list.txt
# Detailed with version info (takes ~60 seconds)
system_profiler SPApplicationsDataType > ~/dotfiles/all-apps-detailed.txt
# Just names and versions (cleaner)
system_profiler SPApplicationsDataType | grep -E "^\s+(.*:|Location:)" > ~/dotfiles/all-apps-summary.txt# Global npm packages
npm list -g --depth=0 > ~/dotfiles/npm-globals.txt
# Python packages
pip list > ~/dotfiles/pip-packages.txt
# Ruby gems
gem list > ~/dotfiles/ruby-gems.txtCreate ~/dotfiles/dump.sh and run it periodically to refresh your lists:
#!/bin/bash
# dump.sh — refresh all dotfiles snapshots
echo "📦 Dumping Homebrew Brewfile..."
brew bundle dump --mas --file=~/dotfiles/Brewfile --force
echo "🛍 Dumping Mac App Store apps..."
mas list > ~/dotfiles/mas-apps.txt
echo "📂 Dumping /Applications list..."
ls /Applications > ~/dotfiles/applications-list.txt
echo "📦 Dumping npm globals..."
npm list -g --depth=0 > ~/dotfiles/npm-globals.txt
echo "✅ Done! Don't forget to: git add . && git commit -m 'Update snapshots' && git push"Make it executable:
chmod +x ~/dotfiles/dump.shOnce your dotfiles are on GitHub, setting up a fresh Mac takes only a few commands:
# 1. Clone your dotfiles
git clone https://github.com/yourusername/dotfiles.git ~/dotfiles
# 2. Run the install script
cd ~/dotfiles
./install.shThat's it. Homebrew installs, all your tools come back, and symlinks are created automatically.
Instead of writing ln -s for every file, GNU Stow manages symlinks automatically based on your folder structure.
brew install stow
cd ~/dotfiles
stow . # creates symlinks for everything in ~/dotfileschezmoi is a more powerful tool that handles secrets, templates, and per-machine differences.
brew install chezmoi
chezmoi init
chezmoi add ~/.zshrc
chezmoi cd # opens your dotfiles dir~/dotfiles/
├── .zshrc
├── .gitconfig
├── .vimrc
├── .ssh/
│ └── config
├── .config/
│ └── starship.toml
├── Brewfile
├── mas-apps.txt
├── applications-list.txt
├── npm-globals.txt
├── install.sh ← run on a new machine
└── dump.sh ← run periodically to update snapshots
- dotfiles.github.io — curated list of community dotfiles repos
- awesome-dotfiles — tools, articles, and examples
Keep your dotfiles updated whenever you install new tools — run dump.sh and push regularly so your repo always reflects your current setup.