Dev Environment Automation: Dotfiles, Shell Config, and Tool Setup
When I got a new MacBook last year, I spent two full days just setting it up. Installing Homebrew, configuring Git, hunting down VS Code extensions one by one, setting up terminal themes, installing Node version managers... It was exhausting. And I didn't even remember everything I had installed. I kept turning on my old laptop, comparing settings, and thinking "oh right, I had that tool too."
That's when I thought: "Is this really how it should be? A developer spending two days just to set up their environment?"
The funny part? I watched my coworkers go through the same pain and just shrugged it off as "that's just how it is." Then I discovered dotfiles. At first, I thought "files that start with a dot? Just hidden files?" But the deeper I dug, I realized this wasn't just a collection of config files. It was a way to codify a developer's muscle memory.
I eventually created my own dotfiles repository and wrote automation scripts. Now, setting up a new MacBook takes 30 minutes. One command, one cup of coffee, and I'm done.
What Are Dotfiles?
In Unix-like systems, files starting with . are hidden. Open your home directory (~) and you'll find files like .zshrc, .gitconfig, .vimrc. These files define your development environment.
.zshrc: Terminal (zsh) configuration. Aliases, environment variables, prompt themes.gitconfig: Git configuration. User info, aliases, default branch, commit signing.vimrcor.config/nvim/init.vim: Vim/Neovim editor settings
The problem? These files only exist locally. When you switch machines or work on your company computer, you start from scratch. The core of dotfiles management is version-controlling these config files with Git and storing them on GitHub.
Think of it like sharing cooking recipes. Instead of wondering "how did I make that delicious dish?" every time, you write it down in a recipe notebook. Next time, just follow the recipe. Dotfiles work the same way. Once you set them up:
- Set up a new MacBook in 30 minutes with identical configuration
- Share settings with teammates (consistent dev environment)
- Accidentally mess up your config? Revert with Git
Homebrew Bundle: The Ultimate Package Manager
On macOS, we use Homebrew to install dev tools. The problem is forgetting what you installed. That's where Brewfile comes in.
A Brewfile is a file that lists packages as code:
# Brewfile
# CLI tools
brew "git"
brew "node"
brew "fnm" # Fast Node Manager
brew "ripgrep"
brew "fzf"
brew "tmux"
brew "starship"
# GUI apps
cask "visual-studio-code"
cask "docker"
cask "iterm2"
cask "notion"
# App Store apps (requires mas)
mas "Xcode", id: 497799835
Installation is simple:
# In the directory with Brewfile
brew bundle install
# Save currently installed packages to Brewfile
brew bundle dump
Now when you get a new MacBook, just run brew bundle install and you're done. Just like adding dependencies to package.json and running npm install.
Terminal Setup: Oh My Zsh and Starship
macOS uses zsh by default. Oh My Zsh is a framework that makes zsh configuration easy:
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
After installation, open .zshrc to add plugins and themes:
# ~/.zshrc
ZSH_THEME="robbyrussell"
plugins=(
git
zsh-autosuggestions
zsh-syntax-highlighting
docker
node
)
# Useful aliases
alias gs="git status"
alias gp="git push"
alias dc="docker compose"
alias ll="ls -lah"
# Environment variables
export EDITOR="code"
export PATH="$HOME/.local/bin:$PATH"
Starship is a fast, customizable prompt that automatically shows Git branch, Node version, execution time, etc:
brew install starship
# Add to end of ~/.zshrc
eval "$(starship init zsh)"
Configure in ~/.config/starship.toml:
[character]
success_symbol = "[➜](bold green)"
error_symbol = "[✗](bold red)"
[git_branch]
symbol = "🌱 "
[nodejs]
symbol = "⬢ "
Git Configuration as Code
Put Git global settings in .gitconfig:
[user]
name = Your Name
email = your.email@example.com
[core]
editor = code --wait
autocrlf = input
[init]
defaultBranch = main
[alias]
co = checkout
br = branch
ci = commit
st = status
unstage = reset HEAD --
last = log -1 HEAD
visual = log --graph --oneline --all
[pull]
rebase = true
[commit]
gpgsign = true # Commit signing (requires GPG key)
Node Version Management
Different projects need different Node versions. fnm (Fast Node Manager) automatically switches versions per project:
brew install fnm
# Add to ~/.zshrc
eval "$(fnm env --use-on-cd)"
# Usage
fnm install 18
fnm install 20
fnm use 18
# Create .node-version or .nvmrc in project
echo "18.20.0" > .node-version
# cd to this directory and it automatically uses Node 18
Alternatives include nvm (more popular but slower) and volta (Rust-based, fast).
SSH Key Management and GitHub
To connect to GitHub via SSH, generate and register a key:
# ED25519 algorithm (safer and faster than RSA)
ssh-keygen -t ed25519 -C "your.email@example.com"
# Add key to SSH agent
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
# Copy public key to clipboard
pbcopy < ~/.ssh/id_ed25519.pub
# Paste in GitHub Settings → SSH and GPG keys → New SSH key
# Test
ssh -T git@github.com
Manage multiple accounts with .ssh/config:
# ~/.ssh/config
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_work
Bootstrap Script: One-Command Setup
Create a dotfiles repository structure:
dotfiles/
├── README.md
├── bootstrap.sh
├── Brewfile
├── .zshrc
├── .gitconfig
├── .config/
│ └── starship.toml
├── vscode/
│ └── settings.json
└── scripts/
└── symlink.sh
The bootstrap.sh script automates everything:
#!/bin/bash
set -e
echo "🚀 Starting dotfiles setup..."
# Install Homebrew
if ! command -v brew &> /dev/null; then
echo "📦 Installing Homebrew..."
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
fi
# Install packages from Brewfile
echo "📦 Installing packages from Brewfile..."
brew bundle install
# Install Oh My Zsh
if [ ! -d "$HOME/.oh-my-zsh" ]; then
echo "🐚 Installing Oh My Zsh..."
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended
fi
# Create symlinks
echo "🔗 Creating symlinks..."
./scripts/symlink.sh
echo "✅ Setup complete! Please restart your terminal."
Usage on a new MacBook:
git clone https://github.com/yourusername/dotfiles.git ~/dotfiles
cd ~/dotfiles
chmod +x bootstrap.sh
./bootstrap.sh
30 minutes later, you have a perfectly configured dev environment.
Advanced Tools: chezmoi and tmux
If manually creating symlinks feels tedious, use chezmoi. It syncs dotfiles across multiple machines and manages machine-specific differences:
brew install chezmoi
# Initialize from existing repo
chezmoi init https://github.com/yourusername/dotfiles.git
# Check changes
chezmoi diff
# Apply
chezmoi apply
# Add file
chezmoi add ~/.zshrc
tmux is a terminal multiplexer that manages multiple terminal windows in one and keeps sessions alive even if SSH disconnects:
brew install tmux
# ~/.config/tmux/tmux.conf
set -g prefix C-a
unbind C-b
set -g mouse on
set -g base-index 1
Recommended CLI Tools
Useful tools to add to your Brewfile:
brew "fzf" # Fuzzy finder
brew "ripgrep" # Fast grep
brew "bat" # Better cat
brew "exa" # Better ls
brew "git-delta" # Pretty diffs
brew "lazygit" # Git TUI
brew "jq" # JSON parser
brew "gh" # GitHub CLI
The Bottom Line
It took me a weekend to create my dotfiles and automation scripts. But since then:
- New MacBook setup: 30 minutes → One command, one coffee
- Share with teammates → Just send them a link
- Accidentally break something →
git checkout .to restore
Like organizing your belongings makes the next move easier, setting up dotfiles once pays off forever. I can never go back to manually copying config files one by one.
Spending two days on dev environment setup is a thing of the past. Automate it with code and it takes 30 minutes. And most of that is just waiting for installations.
Start simple:
- Create a
dotfilesrepository on GitHub - Copy
.zshrc,.gitconfigand commit - Create
Brewfile(brew bundle dump) - Write
bootstrap.shscript
Do it today, and your future self will thank you when you get that next MacBook.