Dotfiles on GitHub: Stop Losing Your Perfect Dev Setup Every Time You Get a New Machine šļø
Dotfiles on GitHub: Stop Losing Your Perfect Dev Setup Every Time You Get a New Machine šļø
True story: My first week at a new job, I got issued a fresh MacBook. Day one was basically a grief session ā mourning my perfectly tuned .zshrc, my custom git aliases, my beautiful prompt, my 47-entry ~/.ssh/config. All gone. š
Day two: Google. Stack Overflow. Brew install this. Configure that. Four hours later, my terminal looked like a fresh Windows install in 1997.
Three years later, I got another new machine. Setup time? 15 minutes. One script. Everything restored. Like it never left.
The difference? Dotfiles on GitHub.
As a full-time developer who contributes to open source, my dotfiles repo is genuinely one of the most valuable repos I own. Not because it's clever code ā it's mostly just config files. But because it saves me hours every time and lets me contribute meaningfully from any machine, anywhere.
What Even ARE Dotfiles? š¤
If you're new to this concept:
Files that start with a . on Unix systems are "hidden" files. They're typically configuration files. You've probably got hundreds of them and never noticed:
ls -la ~/ | grep "^\."
# You'll see things like:
.zshrc # Your shell config (aliases, PATH, etc.)
.gitconfig # Git name, email, aliases
.vimrc # Vim settings
.ssh/config # SSH host shortcuts
.tmux.conf # Tmux keybindings
.npmrc # npm defaults
.bashrc # Bash config
.config/ # Folder full of more configs
These files represent years of accumulated knowledge and preference. Every alias you've added. Every tool you've configured. Every shortcut you learned.
And most developers have zero backup of them. š±
Balancing work and open source taught me: your local environment IS part of your productivity infrastructure. Treat it with the same care you'd treat a production config!
The Case for Putting Them on GitHub š
"But they contain sensitive stuff!" ā I know, I'll cover that.
"Nobody else cares about my config!" ā GitHub disagrees. Dotfile repos regularly hit hundreds of stars.
"Isn't this overkill?" ā Said everyone who's wasted 4 hours re-configuring a machine.
Here's what dotfiles on GitHub gives you:
| Without dotfiles repo | With dotfiles repo |
|---|---|
| 4+ hours new machine setup | 15 minutes |
| Inconsistent config across machines | Identical everywhere |
| Lost aliases and shortcuts | Versioned history |
| "I had something for this..." | git log finds it |
| Fear of trying new tools | Test freely, revert anytime |
| Tribal knowledge in your head | Documented in code |
The open source bonus: other developers find your dotfiles and learn from them! You'll get issues like "how does your prompt show git branch status?" which turns into a whole conversation. Community through config! š
The Real Talk: What Shouldn't Go In There š
Before we build anything ā the scary part first:
Dotfiles CAN contain secrets. A lot of developers have accidentally committed credentials to their public dotfiles repos. Don't be that person.
Never put in a public dotfiles repo:
# ā API keys
export GITHUB_TOKEN="ghp_real_token_here"
export AWS_ACCESS_KEY_ID="AKIAIOSFODNN7EXAMPLE"
# ā Passwords
export DATABASE_PASSWORD="mysecretpass"
# ā Private SSH keys (the private key file itself!)
~/.ssh/id_rsa
# ā Personal tokens of any kind
What TO do instead:
# ā
Source a local-only secrets file
# In your .zshrc:
[[ -f ~/.secrets ]] && source ~/.secrets
# ~/.secrets (in your .gitignore, NEVER committed)
export GITHUB_TOKEN="real_token"
export AWS_ACCESS_KEY_ID="real_key"
# ā
Use environment variable placeholders
# .gitconfig example - no credentials hardcoded
[user]
name = Anuragh K P
email = [email protected]
# token handled by git credential manager
In the security community, we always assume public repos are... public. If you're not sure whether something is sensitive: it is. Keep it out!
Building Your Dotfiles Repo (The Fun Part) š»
Step 1: Create the repo
# On GitHub: create a new public repo named "dotfiles"
# Then locally:
mkdir ~/dotfiles
cd ~/dotfiles
git init
git remote add origin [email protected]:yourusername/dotfiles.git
Step 2: Copy your configs in
# Copy the files you actually care about
cp ~/.zshrc ~/dotfiles/zshrc
cp ~/.gitconfig ~/dotfiles/gitconfig
cp ~/.tmux.conf ~/dotfiles/tmux.conf
cp ~/.vimrc ~/dotfiles/vimrc
# Note: no dots in the repo! Dots get added by the install script.
Step 3: The install script (the magic)
This is what makes it all worth it. A single script that symlinks everything:
#!/bin/bash
# install.sh
DOTFILES_DIR="$HOME/dotfiles"
BACKUP_DIR="$HOME/.dotfiles_backup/$(date +%Y%m%d_%H%M%S)"
echo "š Installing dotfiles..."
# Files to symlink (source -> destination)
declare -A files=(
["zshrc"]=".zshrc"
["gitconfig"]=".gitconfig"
["tmux.conf"]=".tmux.conf"
["vimrc"]=".vimrc"
)
# Create backup dir
mkdir -p "$BACKUP_DIR"
for src in "${!files[@]}"; do
dest="${files[$src]}"
dest_path="$HOME/$dest"
src_path="$DOTFILES_DIR/$src"
# Back up existing file if it exists
if [[ -e "$dest_path" && ! -L "$dest_path" ]]; then
echo " Backing up $dest_path"
mv "$dest_path" "$BACKUP_DIR/"
fi
# Create symlink
ln -sf "$src_path" "$dest_path"
echo " ā
Linked $src -> $dest_path"
done
echo ""
echo "⨠Done! Old configs backed up to $BACKUP_DIR"
echo "š Restart your terminal to see the changes!"
The beauty: symlinks mean any edit to ~/dotfiles/zshrc is immediately live in ~/.zshrc. Edit once, works everywhere! š
Step 4: Structure that actually scales
dotfiles/
āāā install.sh # One command to rule them all
āāā README.md # What this is and how to use it
āāā zshrc # Shell config
āāā gitconfig # Git settings
āāā tmux.conf # Tmux
āāā vimrc # Vim
āāā config/
ā āāā starship.toml # Prompt config
ā āāā alacritty.yml # Terminal emulator
āāā scripts/
ā āāā macos.sh # macOS-specific defaults
ā āāā brew.sh # Homebrew packages to install
ā āāā node.sh # npm global packages
āāā .gitignore # Always include .secrets!
The Good Stuff: What Goes In My Dotfiles šÆ
Git aliases that feel like superpowers:
# .gitconfig
[alias]
# Shortcuts
st = status
co = checkout
br = branch
# One-line log (my daily driver)
lg = log --oneline --graph --decorate --all
# Undo last commit, keep changes staged
undo = reset --soft HEAD~1
# Squash last N commits: git squash 3
squash = "!f() { git rebase -i HEAD~$1; }; f"
# Find which commit introduced a string
find = "!f() { git log --all --grep=$1; }; f"
# Clean up merged branches
cleanup = "!git branch --merged | grep -v main | xargs git branch -d"
Shell aliases that save my wrists:
# zshrc
# Git shortcuts
alias g="git"
alias gs="git status"
alias gp="git push"
alias gl="git pull"
alias glog="git log --oneline --graph --all"
# Navigation
alias ..="cd .."
alias ...="cd ../.."
alias ll="ls -lahF"
# Dev shortcuts (Laravel heavy!)
alias art="php artisan"
alias tinker="php artisan tinker"
alias mfs="php artisan migrate:fresh --seed"
# Docker
alias dps="docker ps"
alias dcp="docker compose"
alias dcup="docker compose up -d"
# Editors
alias c="code ."
alias v="vim"
The prompt that tells me everything:
# Showing git branch, node version, and Python env
# I use Starship (starship.rs) - config in config/starship.toml
# Before dotfiles: $
# After dotfiles: ā” kpanuragh on main via v18.17.0
# āÆ
The "New Machine" Experience š
This is what it looks like after you've set up a dotfiles repo:
# You just got a new machine. Here's EVERYTHING you do:
# Step 1: Install Homebrew (macOS)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Step 2: Clone your dotfiles
git clone [email protected]:kpanuragh/dotfiles.git ~/dotfiles
# Step 3: Run the install script
cd ~/dotfiles && ./install.sh
# Step 4: Install your standard tools
./scripts/brew.sh
# Step 5: Create your local secrets file
touch ~/.secrets
# Add your tokens here, this file is NEVER committed
# DONE. š
# Open terminal. Everything works. Git aliases, prompt, vim config. All of it.
What this replaced: a 4-hour ordeal of Googling "how to set up zsh on mac again" while WhatsApp distracts me.
Balancing work and open source taught me: any manual process you do more than twice should be automated. New machine setup qualifies easily!
The Community Angle: Why Make it Public? š
Here's the open source magic I didn't expect:
When I first pushed my dotfiles publicly, I thought nobody would care. It's config files. Who reads those?
What actually happened:
- A stranger opened an issue: "Your
git findalias doesn't work on zsh, here's a fix" ā ā Merged. My alias works better now. - Someone submitted a PR with a function to auto-activate Python virtualenvs ā ā Now it's in my daily workflow.
- Three developers starred my repo specifically for the SSH config structure ā which made me write better comments in it.
In the security community, shared configs are how knowledge spreads. I've learned more about secure SSH configuration from reading 10 public dotfiles repos than from any documentation.
The best part: some of the most starred repos on GitHub are dotfiles repos. Real developers, real configs, genuinely useful code. Not flashy frameworks ā just well-organized quality-of-life improvements!
Real Projects to Learn From š
Some legendary dotfiles repos worth exploring:
- mathiasbynens/dotfiles ā The one that started the trend for many developers (macOS-focused, meticulous)
- holman/dotfiles ā Well-organized with a topic-based structure approach
- jessfraz/dotfiles ā Container and Linux-focused, security-minded structure
- webpro/awesome-dotfiles ā Curated list of excellent dotfile repos on GitHub
What to look for when reading others' dotfiles:
# 1. How do they handle secrets?
grep -i "token\|password\|key\|secret" .gitignore
# 2. What's their install approach?
cat install.sh # or bootstrap.sh, or setup.sh
# 3. Do they have interesting git aliases?
grep -A1 "\[alias\]" .gitconfig
# 4. What tools do they rely on daily?
cat Brewfile # or scripts/brew.sh
I've "borrowed" at least 12 aliases from other developers' public dotfiles. That's open source collaboration at its most informal and human! š¤
The "Too Scared to Share" Objection š
"My config is embarrassing / messy / newbie stuff"
You know what? That's exactly WHY you should share it.
The most valuable public dotfiles are often from developers who learned something recently and documented it clearly. An expert writes alias ..="cd .." and moves on. A developer who just learned this writes a comment explaining why it exists and what problem it solves.
Beginner-friendly comments are RARE in dotfiles repos. Yours might be exactly what someone needs!
When I started contributing to PHP/Laravel projects, I was terrified that my code was obviously amateur. Then a maintainer said: "Your explanation in the PR is the most detailed we've ever gotten. Merged immediately."
The same applies to dotfiles. Clear, well-commented config files are more valuable than terse "expert" ones. šŖ
The Maintenance Workflow š
The day-to-day when everything is set up:
# You discover a great new alias at a conference
# Add it to your zshrc:
echo 'alias mynewalias="some command"' >> ~/dotfiles/zshrc
# It's immediately live (symlink magic!) āØ
source ~/.zshrc
# Commit it so you never lose it:
cd ~/dotfiles
git add zshrc
git commit -m "feat: add mynewalias for productivity"
git push
# All your OTHER machines get it with:
git pull && source ~/.zshrc
Yearly review ritual (I actually do this):
# Review what I added this year
git log --oneline --since="1 year ago" ~/dotfiles
# Remove things I never used
git log --diff-filter=A --summary | grep "new file"
# Check if any aliases conflict with new tools
alias | sort
It's essentially version control for your brain's muscle memory. Each commit is a decision you made about your workflow. Valuable history!
Getting Started TODAY š
The minimum viable dotfiles repo:
- Create a
dotfilesrepo on GitHub (public!) - Copy in your
.zshrcor.bashrc - Copy in your
.gitconfig - Write a 10-line install script with symlinks
- Add a
.gitignorethat excludes.secrets - Push and share the link
That's it. You're in the dotfiles club. š
Resources that genuinely helped me:
- dotfiles.github.io ā The unofficial guide and community hub
- GitHub topic: #dotfiles ā Browse what real developers use
- Stow (
brew install stow) ā Tool to manage symlinks automatically if you prefer - Chezmoi ā More powerful dotfiles manager with built-in secret handling
TL;DR š”
Your perfectly tuned dev environment is hours of accumulated knowledge. Version control it like you would production code. Put it on GitHub where:
- You never lose it when machines die
- You can restore a new machine in minutes, not hours
- Other developers learn from your configs
- Community improvements flow back to you
One git repo. 15-minute machine setup. Years of configs preserved.
Got a dotfiles repo already? Connect on LinkedIn and share the link ā I'm always on the hunt for interesting aliases to steal! šµļø
Want to see mine in action? Check GitHub for the actual configs, and yes, the install script is tested on real machines.
Now go back up your .zshrc before you regret it. šļøāØ
P.S. The first thing I check on any developer's GitHub profile is whether they have a dotfiles repo. It tells you SO much about how they work. No judgment if it's a mess ā at least it exists! š
P.P.S. If you work across Linux servers frequently, look into chezmoi ā it handles the "some machines have different tools installed" problem elegantly. Future blog post incoming! š§