0x55aa
← Back to Blog

Dotfiles on GitHub: Stop Losing Your Perfect Dev Setup Every Time You Get a New Machine šŸ—‚ļø

•12 min read

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 find alias 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:

  1. Create a dotfiles repo on GitHub (public!)
  2. Copy in your .zshrc or .bashrc
  3. Copy in your .gitconfig
  4. Write a 10-line install script with symlinks
  5. Add a .gitignore that excludes .secrets
  6. 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! šŸ”§