
Dev Environment Automation: Dotfiles, Shell Config, and Tool Setup
Setting up a new Mac took 2 days. With dotfiles and automation scripts, it now takes 30 minutes to get a fully configured dev environment.

Setting up a new Mac took 2 days. With dotfiles and automation scripts, it now takes 30 minutes to get a fully configured dev environment.
ChatGPT answers questions. AI Agents plan, use tools, and complete tasks autonomously. Understanding this difference changes how you build with AI.

Tired of ESLint and Prettier config conflicts? Biome combines linting and formatting in one blazing-fast Rust-based tool.

I actually used all three AI coding tools for real projects. Here's an honest comparison of Copilot, Claude Code, and Cursor.

Shell is not the core of OS. It's just a 'Messenger' passing user commands to Kernel. The real role of zsh and bash.

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.
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.vimrc or .config/nvim/init.vim: Vim/Neovim editor settingsThe 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:
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.
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 = "⬢ "
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)
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).
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
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.
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
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
It took me a weekend to create my dotfiles and automation scripts. But since then:
git checkout . to restoreLike 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:
dotfiles repository on GitHub.zshrc, .gitconfig and commitBrewfile (brew bundle dump)bootstrap.sh scriptDo it today, and your future self will thank you when you get that next MacBook.