← Back to all projects

LEARN DOTFILES PRODUCTIVITY

Learn Dotfiles: From Zero to Productivity Master

Goal: Deeply understand dotfiles customization—from basic shell configuration to building a portable, version-controlled development environment that makes you significantly more productive.


Why Dotfiles Matter

Every power user you admire—the one who navigates code at lightning speed, whose terminal looks like a cockpit, who sets up a new machine in minutes—has spent time crafting their dotfiles. These hidden files (prefixed with .) control everything: your shell behavior, editor keybindings, git workflows, and terminal aesthetics.

After completing these projects, you will:

  • Have a shell environment tailored exactly to your workflow
  • Navigate and edit code faster than you thought possible
  • Set up any new machine with your complete environment in minutes
  • Understand the Unix philosophy of composable, configurable tools
  • Build automation that saves you hours every week

Core Concept Analysis

The Dotfiles Ecosystem

~/ (Home Directory)
├── .bashrc / .zshrc       # Shell configuration
├── .bash_profile          # Login shell config
├── .profile               # POSIX shell config
├── .zprofile              # Zsh login config
├── .vimrc / .config/nvim  # Editor configuration
├── .tmux.conf             # Terminal multiplexer
├── .gitconfig             # Git settings
├── .ssh/config            # SSH shortcuts
├── .config/               # XDG config directory
│   ├── alacritty/         # Terminal emulator
│   ├── starship.toml      # Prompt customization
│   └── ...                # Many more tools
└── .local/bin/            # Personal scripts

Fundamental Concepts

  1. Shell Initialization Order
    • Login vs Non-login shells
    • Interactive vs Non-interactive shells
    • Which files get sourced when and why
    • The .bashrc vs .bash_profile confusion
  2. Environment Variables
    • $PATH: Where the shell looks for commands
    • $EDITOR, $VISUAL: Default editor
    • $XDG_CONFIG_HOME: Modern config location
    • Export vs local variables
  3. Shell Features
    • Aliases: Command shortcuts
    • Functions: Mini-programs in your shell
    • Completion: Tab-completion customization
    • Prompt: The PS1 variable and beyond
  4. Dotfile Management
    • Symlink strategies
    • Git bare repository method
    • Tools: stow, chezmoi, yadm
    • Machine-specific configurations
  5. The Unix Philosophy Applied
    • Small, composable tools
    • Text as universal interface
    • Configuration as code
    • Pipelines and composition

Project 1: Shell Alias System (Your First Productivity Win)

  • File: LEARN_DOTFILES_PRODUCTIVITY.md
  • Main Programming Language: Bash/Zsh
  • Alternative Programming Languages: Fish, POSIX sh
  • Coolness Level: Level 2: Practical but Forgettable
  • Business Potential: 1. The “Resume Gold”
  • Difficulty: Level 1: Beginner
  • Knowledge Area: Shell Configuration
  • Software or Tool: Zsh/Bash
  • Main Book: “The Linux Command Line, 2nd Edition” by William E. Shotts

What you’ll build: A organized system of shell aliases that reduces your most common multi-character commands to 2-3 keystrokes, with categories, documentation, and easy discoverability.

Why it teaches dotfiles: Aliases are the “Hello World” of dotfiles—simple enough to understand immediately, but they introduce the core concepts: configuration files, shell initialization, and the idea that you can reshape your CLI experience.

Core challenges you’ll face:

  • Understanding where to put aliases → maps to shell initialization order
  • Avoiding alias conflicts with existing commands → maps to command precedence
  • Making aliases discoverable → maps to self-documenting configuration
  • Handling aliases that need arguments → maps to when to use functions instead

Key Concepts:

  • Shell Initialization: “The Linux Command Line” Chapter 11 - William Shotts
  • Alias Syntax: “Effective Shell” Chapter 19 - Dave Kerr
  • Zsh Configuration: “Learning the Zsh Shell” Chapter 2 - O’Reilly

Difficulty: Beginner Time estimate: Weekend Prerequisites: Basic command line usage, ability to edit text files

Real world outcome:

$ aliases  # Your custom command to list all aliases

📁 Navigation
  ..     → cd ..
  ...    → cd ../..
  ~      → cd ~
  dev    → cd ~/Developer

🔧 Git Shortcuts
  g      → git
  gs     → git status
  gco    → git checkout
  gcm    → git commit -m
  gp     → git push
  gl     → git log --oneline -20

📦 Package Management
  bi     → brew install
  bu     → brew update && brew upgrade

🔍 Search & Find
  f      → find . -name
  rg     → rg --smart-case

💻 Development
  py     → python3
  serve  → python3 -m http.server

Found 47 aliases across 8 categories

Implementation Hints:

Start by auditing your command history to find what you type most:

history | awk '{print $2}' | sort | uniq -c | sort -rn | head -20

Organize your aliases in a dedicated file (e.g., ~/.aliases or ~/.config/shell/aliases.zsh) and source it from your main shell config:

# In .zshrc
source ~/.config/shell/aliases.zsh

Structure your alias file with categories using comments. Consider creating a shell function that parses these comments to generate a help display.

Questions to guide you:

  • What commands do you type more than 10 times a day?
  • Which commands are hard to remember but useful?
  • What dangerous commands need a safety wrapper (like rm -i)?
  • How will you remember your aliases exist?

Learning milestones:

  1. You have 10+ working aliases → You understand alias syntax and sourcing
  2. You created a help command → You understand self-documenting configuration
  3. You organized by category → You understand maintainable dotfiles
  4. You hit conflicts and resolved them → You understand command precedence

Project 2: Git Configuration Powerhouse

  • File: LEARN_DOTFILES_PRODUCTIVITY.md
  • Main Programming Language: Git config / Bash
  • Alternative Programming Languages: N/A (Git-specific)
  • Coolness Level: Level 3: Genuinely Clever
  • Business Potential: 1. The “Resume Gold”
  • Difficulty: Level 1: Beginner
  • Knowledge Area: Version Control Configuration
  • Software or Tool: Git
  • Main Book: “Pro Git” by Scott Chacon (free online)

What you’ll build: A comprehensive .gitconfig with custom aliases, useful defaults, delta/diff-so-fancy integration, global gitignore, commit templates, and conditional includes for work vs personal projects.

Why it teaches dotfiles: Git configuration demonstrates the power of tool-specific dotfiles. You’ll learn about git’s hierarchical config system (system → global → local), conditional includes, and how proper defaults can prevent common mistakes.

Core challenges you’ll face:

  • Setting up sensible defaults → maps to understanding git behaviors
  • Creating useful git aliases → maps to git alias syntax
  • Conditional config for work/personal → maps to includeIf directive
  • Integrating better diff tools → maps to external tool configuration

Key Concepts:

  • Git Configuration Levels: “Pro Git” Chapter 8.1 - Scott Chacon
  • Git Aliases: “Pro Git” Chapter 2.7 - Scott Chacon
  • Conditional Includes: Git documentation git-config(1)

Difficulty: Beginner Time estimate: Weekend Prerequisites: Basic git usage

Real world outcome:

$ git lg
* a1b2c3d (HEAD -> feature/auth) Add OAuth support
* e4f5g6h Refactor user model
* i7j8k9l (origin/main, main) Initial commit

$ git undo  # Your custom alias
Unstaged changes after reset

$ git please  # Force push with lease (safer)
Everything up-to-date

$ git standup  # What did I do yesterday?
a1b2c3d - Add OAuth support (23 hours ago)
e4f5g6h - Refactor user model (yesterday)

$ cat ~/.gitconfig
[user]
    name = Your Name
    email = personal@email.com

[includeIf "gitdir:~/work/"]
    path = ~/.gitconfig-work  # Uses work email automatically!

Implementation Hints:

Your .gitconfig should have these sections:

  1. [user]: Name, email, signing key
  2. [core]: Editor, pager, excludesfile
  3. [alias]: Your custom shortcuts
  4. [diff]: External diff tool (delta is excellent)
  5. [merge]: Merge tool configuration
  6. [pull]: Default pull behavior (rebase vs merge)
  7. [init]: Default branch name
  8. [includeIf]: Conditional configuration

Useful aliases to consider:

  • lg: Pretty log with graph
  • undo: Reset last commit but keep changes
  • amend: Quick amend without editing message
  • standup: Show your commits from last day
  • please: Force push with lease (safer than --force)
  • stash-all: Stash including untracked files

Create a global .gitignore for things you never want to commit:

  • .DS_Store
  • *.swp
  • .env
  • node_modules/ (controversial - some prefer local)
  • IDE folders (.idea/, .vscode/)

Learning milestones:

  1. You have working aliases → You understand git alias syntax
  2. Work projects use work email automatically → You understand conditional includes
  3. Your diffs are colorful and readable → You understand external tool integration
  4. You have sensible defaults → You understand git configuration options

Project 3: Custom Shell Prompt (Starship or Pure Prompt)

  • File: LEARN_DOTFILES_PRODUCTIVITY.md
  • Main Programming Language: TOML (Starship) / Zsh
  • Alternative Programming Languages: Bash, Fish
  • Coolness Level: Level 3: Genuinely Clever
  • Business Potential: 1. The “Resume Gold”
  • Difficulty: Level 2: Intermediate
  • Knowledge Area: Shell Customization / Terminal UI
  • Software or Tool: Starship / Oh-My-Zsh / Pure
  • Main Book: “Effective Shell” by Dave Kerr

What you’ll build: A custom shell prompt that shows contextual information: git branch/status, current directory, language versions (node, python, rust), exit codes, execution time, and possibly kubernetes context—all without slowing down your shell.

Why it teaches dotfiles: The prompt is the most visible part of your shell. Building it teaches you about shell escaping, ANSI colors, performance optimization (async prompts), and how different tools read environment state.

Core challenges you’ll face:

  • Understanding prompt escape sequences → maps to terminal control codes
  • Keeping the prompt fast → maps to async rendering and caching
  • Showing relevant info without clutter → maps to contextual awareness
  • Making it work across shells → maps to cross-shell compatibility

Key Concepts:

  • PS1 and Prompt Escapes: “The Linux Command Line” Chapter 13 - William Shotts
  • ANSI Escape Codes: Wikipedia “ANSI escape code” article
  • Starship Configuration: starship.rs documentation

Difficulty: Intermediate Time estimate: Weekend Prerequisites: Project 1 (Shell Alias System), basic understanding of shell config

Real world outcome:

~/Developer/myproject on  main [!?] via  v18.17.0 via 🐍 v3.11.0 took 2s
❯

# After a failed command:
~/Developer/myproject on  main [!?]
❯ exit 1
~/Developer/myproject on  main [!?] ✖
❯

# In a Python virtualenv:
~/Developer/api on  feature/auth via 🐍 v3.11.0 (venv)# Long-running command finished:
~/Developer/myproject on  main took 45s
❯

Implementation Hints:

Option A: Use Starship (Recommended for beginners)

Starship is a cross-shell prompt written in Rust. It’s fast and highly configurable via TOML.

  1. Install: brew install starship
  2. Add to your .zshrc: eval "$(starship init zsh)"
  3. Create ~/.config/starship.toml

Think about what information you actually need:

  • Current directory (abbreviated or full?)
  • Git status (which symbols for staged, unstaged, untracked?)
  • Language versions (only when relevant to current directory)
  • Command duration (threshold before showing?)
  • Exit status (only on failure?)

Option B: Build your own prompt (Deep learning)

If you want to understand prompts deeply, build one from scratch:

  1. Understand the PS1/PROMPT variable
  2. Learn prompt escape sequences (%~ for directory in zsh, \w in bash)
  3. Add color with ANSI codes or zsh’s %F{color}
  4. Call external commands for git info (but watch performance!)

Questions to explore:

  • Why do some prompts feel slow? How do you diagnose?
  • What’s the difference between PS1 and PROMPT?
  • How do you handle multi-line prompts?
  • How do async prompts work?

Learning milestones:

  1. Your prompt shows git status → You understand external command integration
  2. Prompt only shows python version in Python projects → You understand contextual display
  3. Prompt stays fast even in large repos → You understand performance optimization
  4. You customized colors and symbols → You understand terminal styling

Project 4: SSH Config Mastery

  • File: LEARN_DOTFILES_PRODUCTIVITY.md
  • Main Programming Language: SSH config syntax
  • Alternative Programming Languages: N/A
  • Coolness Level: Level 3: Genuinely Clever
  • Business Potential: 2. The “Micro-SaaS / Pro Tool”
  • Difficulty: Level 2: Intermediate
  • Knowledge Area: Networking / Remote Access
  • Software or Tool: OpenSSH
  • Main Book: “SSH Mastery” by Michael W. Lucas

What you’ll build: A comprehensive SSH configuration with host aliases, jump hosts (bastion), connection sharing, identity file management, and proxy configurations—allowing you to connect to any server with simple commands like ssh prod-api-1.

Why it teaches dotfiles: SSH config is one of the most underutilized dotfiles. Mastering it teaches you about connection management, security practices, and how a single config file can eliminate complex command-line arguments.

Core challenges you’ll face:

  • Organizing multiple hosts → maps to Host patterns and wildcards
  • Setting up jump hosts → maps to ProxyJump configuration
  • Managing multiple SSH keys → maps to IdentityFile and IdentitiesOnly
  • Keeping connections alive → maps to ServerAliveInterval and ControlMaster

Key Concepts:

  • SSH Config Syntax: man ssh_config
  • ProxyJump and Bastion Hosts: “SSH Mastery” Chapter 8 - Michael W. Lucas
  • Connection Multiplexing: “SSH Mastery” Chapter 10 - Michael W. Lucas

Difficulty: Intermediate Time estimate: Weekend Prerequisites: Basic SSH usage, understanding of key-based authentication

Real world outcome:

# Instead of this nightmare:
$ ssh -i ~/.ssh/work_key -o ProxyJump=bastion.company.com -p 2222 deploy@10.0.1.50

# You type this:
$ ssh prod-api

# Connect to any server in a pattern:
$ ssh staging-web-3
$ ssh dev-db

# Your config handles:
# - Correct SSH key per host
# - Jump through bastion automatically
# - Keep connections alive
# - Reuse connections for speed

$ cat ~/.ssh/config
Host bastion
    HostName bastion.company.com
    User admin
    IdentityFile ~/.ssh/work_key

Host prod-*
    ProxyJump bastion
    User deploy
    IdentityFile ~/.ssh/work_key

Host dev-*
    HostName %h.dev.internal
    User developer

Host *
    ServerAliveInterval 60
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h-%p
    ControlPersist 600

Implementation Hints:

Structure your SSH config from specific to general (first match wins):

  1. Specific hosts: Individual servers with unique settings
  2. Pattern hosts: Groups like Host prod-*, Host *.company.com
  3. Wildcard defaults: Host * for settings that apply to everything

Key directives to learn:

  • HostName: The real hostname/IP (when Host is an alias)
  • User: Default username
  • IdentityFile: Which SSH key to use
  • IdentitiesOnly: Don’t try other keys
  • ProxyJump: Connect through a jump host
  • LocalForward: Port forwarding
  • ControlMaster/ControlPath/ControlPersist: Connection reuse

Create the sockets directory:

mkdir -p ~/.ssh/sockets

Security considerations:

  • Keep your config file permissions at 600
  • Use IdentitiesOnly yes to prevent key enumeration
  • Consider HashKnownHosts yes for privacy

Learning milestones:

  1. You connect with short aliases → You understand Host directives
  2. Connections go through bastion automatically → You understand ProxyJump
  3. Second SSH to same host is instant → You understand ControlMaster
  4. Each service uses correct key → You understand identity management

Project 5: Vim/Neovim Configuration from Scratch

  • File: LEARN_DOTFILES_PRODUCTIVITY.md
  • Main Programming Language: Vimscript / Lua (Neovim)
  • Alternative Programming Languages: N/A (Editor-specific)
  • Coolness Level: Level 4: Hardcore Tech Flex
  • Business Potential: 1. The “Resume Gold”
  • Difficulty: Level 3: Advanced
  • Knowledge Area: Text Editor Configuration
  • Software or Tool: Neovim
  • Main Book: “Practical Vim, 2nd Edition” by Drew Neil

What you’ll build: A complete Neovim configuration with sensible defaults, plugin management (lazy.nvim), LSP integration for code intelligence, treesitter for syntax highlighting, telescope for fuzzy finding, and custom keymaps that match your workflow.

Why it teaches dotfiles: Vim configuration is the deep end of dotfiles. You’ll learn about plugin management, Lua scripting, language servers, and building a tool that’s truly yours. The skills transfer to configuring any complex tool.

Core challenges you’ll face:

  • Understanding Vim’s options system → maps to set commands and defaults
  • Managing plugins without bloat → maps to lazy loading and plugin management
  • Setting up LSP for code intelligence → maps to nvim-lspconfig and mason
  • Creating intuitive keymaps → maps to keymap design and which-key

Key Concepts:

  • Vim Options: “Practical Vim” Chapter 1 - Drew Neil
  • Lua in Neovim: Neovim documentation :help lua-guide
  • Plugin Management: lazy.nvim documentation
  • LSP Configuration: nvim-lspconfig wiki

Difficulty: Advanced Time estimate: 1-2 weeks (ongoing refinement) Prerequisites: Basic Vim usage (hjkl navigation, modes, basic editing), Project 1 completed

Real world outcome:

┌─────────────────────────────────────────────────────────────┐
│  NORMAL │ src/auth/login.ts                      │ ts │ ln:45 │
├─────────────────────────────────────────────────────────────┤
│  1 │ import { User } from '../models/user';                 │
│  2 │                                                         │
│  3 │ export async function login(email: string, password: s │
│ E│4 │   const user = await User.findByEmail(email);         │◀── Error
│  5 │   if (!user) {                                         │    indicator
│  6 │     throw new AuthError('User not found');             │
│  7 │   }                                                     │
│  8 │                                                         │
│  9 │   const valid = await user.checkPassword(password);    │
│ 10 │   return { token: generateToken(user) };               │
├─────────────────────────────────────────────────────────────┤
│ 󰌌 Space → Leader │ 󰈞 Find files │ 󰈬 Live grep │  Git │
└─────────────────────────────────────────────────────────────┘

Press <Space>ff: Fuzzy find files
Press <Space>fg: Live grep across project
Press <Space>ca: Code actions (LSP)
Press gd: Go to definition
Press K: Hover documentation

Implementation Hints:

Start with a clean structure (for Neovim with Lua):

~/.config/nvim/
├── init.lua              # Entry point
├── lua/
│   ├── config/
│   │   ├── options.lua   # Vim options (tabwidth, numbers, etc.)
│   │   ├── keymaps.lua   # Custom keybindings
│   │   └── autocmds.lua  # Automatic commands
│   └── plugins/
│       ├── init.lua      # Plugin list for lazy.nvim
│       ├── lsp.lua       # LSP configuration
│       ├── telescope.lua # Fuzzy finder config
│       └── treesitter.lua # Syntax highlighting

Phase 1: Sensible Defaults (Day 1)

  • Line numbers (relative for Vim motions)
  • Proper tabs/spaces
  • Search settings (case insensitive, incremental)
  • Split behavior
  • Mouse support (for scrolling)
  • Clipboard integration

Phase 2: Plugin Manager (Day 1-2)

  • Install lazy.nvim
  • Add essential plugins one at a time
  • Understand lazy loading

Phase 3: Core Plugins (Days 3-5)

  • telescope.nvim: Fuzzy finder
  • nvim-treesitter: Better syntax highlighting
  • which-key.nvim: Keymap discoverability
  • Comment.nvim: Easy commenting

Phase 4: LSP Setup (Days 6-7)

  • mason.nvim: LSP installer
  • nvim-lspconfig: LSP configuration
  • nvim-cmp: Autocompletion

Questions to guide you:

  • What keybindings feel natural to you?
  • Which plugins do you actually need vs “look cool”?
  • How do you keep startup time fast?
  • How do you make changes discoverable?

Learning milestones:

  1. Basic config with sensible defaults → You understand Vim options
  2. Plugins load and work → You understand plugin management
  3. LSP provides completions and diagnostics → You understand language server integration
  4. Your keymaps feel natural → You’ve internalized modal editing and customization

Project 6: Terminal Multiplexer Setup (tmux)

  • File: LEARN_DOTFILES_PRODUCTIVITY.md
  • Main Programming Language: tmux config
  • Alternative Programming Languages: N/A (use Zellij for modern alternative)
  • Coolness Level: Level 3: Genuinely Clever
  • Business Potential: 1. The “Resume Gold”
  • Difficulty: Level 2: Intermediate
  • Knowledge Area: Terminal Management / Session Persistence
  • Software or Tool: tmux
  • Main Book: “tmux 3: Productive Mouse-Free Development” by Brian P. Hogan

What you’ll build: A complete tmux configuration with intuitive keybindings, session management, a useful status bar, vim-like navigation, and integration with your shell and editor for seamless workflows.

Why it teaches dotfiles: tmux configuration teaches you about persistent sessions, pane/window management, and how to build a workflow that survives SSH disconnections. It’s essential for remote work and multi-project contexts.

Core challenges you’ll face:

  • Choosing a prefix key → maps to ergonomics and muscle memory
  • Setting up intuitive pane navigation → maps to keybinding design
  • Configuring a useful status bar → maps to tmux status-line format
  • Session management workflows → maps to named sessions and scripts

Key Concepts:

  • tmux Fundamentals: “tmux 3” Chapter 1-2 - Brian P. Hogan
  • Configuration: “tmux 3” Chapter 3 - Brian P. Hogan
  • Pair Programming with tmux: “tmux 3” Chapter 4 - Brian P. Hogan

Difficulty: Intermediate Time estimate: Weekend Prerequisites: Basic terminal usage, Project 1 (Shell Alias System)

Real world outcome:

┌─────────────────────────────────────────────────────────────┐
│ 0:nvim │ 1:shell │ 2:server │ 3:logs                   │ API │
├───────────────────────────────┬─────────────────────────────┤
│                               │                             │
│     [Neovim - editing        │   $ npm run dev             │
│      your code]              │   Server running on :3000   │
│                               │                             │
│                               │                             │
├───────────────────────────────┴─────────────────────────────┤
│ $ docker logs -f api                                        │
│ [2024-01-15 10:30:22] Request: GET /users                   │
│ [2024-01-15 10:30:22] Response: 200 OK                      │
│                                                              │
└─────────────────────────────────────────────────────────────┘
  Session: api-project │ Window 0 │ Pane 0 │ 10:30 AM

# Quick commands:
Ctrl-a c     → New window
Ctrl-a |     → Split vertical
Ctrl-a -     → Split horizontal
Ctrl-a h/j/k/l → Navigate panes (vim-style)
Ctrl-a d     → Detach (session persists!)
tmux attach  → Reattach to session

Implementation Hints:

Your ~/.tmux.conf should address these areas:

1. Prefix Key The default Ctrl-b is awkward. Common alternatives:

  • Ctrl-a (popular, but conflicts with readline)
  • Ctrl-Space (ergonomic)
  • Backtick ` (easy to reach)

2. Intuitive Splits Map | for vertical and - for horizontal splits (visually logical).

3. Vim-style Navigation Use h/j/k/l for pane navigation to match Vim muscle memory.

4. Mouse Support Enable mouse for scrolling and pane resizing (you can still be a keyboard person).

5. Status Bar Show useful info: session name, window list, time, perhaps system load.

6. Copy Mode Configure vi-style copy mode for selecting and copying text.

Consider these plugins (via tpm - tmux plugin manager):

  • tmux-resurrect: Save/restore sessions across restarts
  • tmux-continuum: Auto-save sessions
  • tmux-yank: Better clipboard integration

Session management strategy:

  • One session per project
  • Consistent window layout per project type
  • Scripts to create project-specific layouts

Learning milestones:

  1. You use tmux daily → You understand the value of persistent sessions
  2. Navigation is second nature → You’ve built muscle memory for your keybindings
  3. You have project-specific sessions → You understand session management
  4. You recovered from a dropped SSH connection → You truly appreciate tmux

Project 7: Shell Functions Library

  • File: LEARN_DOTFILES_PRODUCTIVITY.md
  • Main Programming Language: Bash/Zsh
  • Alternative Programming Languages: Fish
  • Coolness Level: Level 3: Genuinely Clever
  • Business Potential: 1. The “Resume Gold”
  • Difficulty: Level 2: Intermediate
  • Knowledge Area: Shell Scripting
  • Software or Tool: Zsh/Bash
  • Main Book: “Shell Script Professional” by Aurelio Marinho Jargas

What you’ll build: A library of shell functions that automate your common workflows: quick directory jumping, git worktree management, docker shortcuts, project scaffolding, and smart utilities that do complex tasks with simple commands.

Why it teaches dotfiles: Functions are aliases on steroids. They teach you shell scripting in the context of your daily work, creating utilities that feel like native commands. This is where dotfiles become truly personal.

Core challenges you’ll face:

  • Writing robust functions → maps to argument parsing and error handling
  • Organizing multiple functions → maps to modular configuration
  • Making functions discoverable → maps to help systems and naming conventions
  • Handling edge cases → maps to defensive scripting

Key Concepts:

  • Shell Functions: “Shell Script Professional” Chapter 4 - Aurelio Marinho Jargas
  • Parameter Handling: “The Linux Command Line” Chapter 32 - William Shotts
  • Shell Scripting Best Practices: “Effective Shell” Chapter 26 - Dave Kerr

Difficulty: Intermediate Time estimate: 1-2 weeks (ongoing) Prerequisites: Project 1 (Shell Alias System), basic shell scripting

Real world outcome:

# Smart directory jumping
$ z api         # Jumps to ~/Developer/company/api (frecency-based)

# Create a new project with your preferred structure
$ mkproject my-new-api --template node-api
Creating project: my-new-api
✓ Initialized git repository
✓ Created directory structure
✓ Installed dependencies
✓ Set up pre-commit hooks
cd ~/Developer/my-new-api

# Quick git worktree for feature
$ gwt feature/auth
Created worktree at ~/Developer/project-feature-auth
Switched to ~/Developer/project-feature-auth

# Docker helpers
$ dsh api       # docker exec -it api sh
$ dlogs api     # docker logs -f api
$ dstop         # Stop all containers

# Find and open
$ fvo login     # Find files matching 'login', open in $EDITOR
? Select file:
  > src/auth/login.ts
    src/components/LoginForm.tsx
    tests/login.test.ts

# Extract anything
$ extract archive.tar.gz    # Works with .tar.gz, .zip, .7z, .rar, etc.

# Get help on your functions
$ funcs
📂 Navigation
  z         Smart directory jump (frecency)
  mkcd      Create directory and cd into it

🔧 Git
  gwt       Create/switch git worktree
  gclean    Remove merged branches

🐳 Docker
  dsh       Interactive shell in container
  dlogs     Follow container logs

📁 Files
  extract   Extract any archive
  fvo       Find and open file in editor

Implementation Hints:

Structure your functions in category files:

~/.config/shell/
├── functions/
│   ├── navigation.zsh
│   ├── git.zsh
│   ├── docker.zsh
│   ├── files.zsh
│   └── projects.zsh
└── functions.zsh  # Sources all function files

Essential function patterns:

  1. Smart directory jumping (integrate with zoxide or autojump):
    z() - Jump to frecent directories
    mkcd() - Create and enter directory
    
  2. Git workflow helpers:
    gwt() - Git worktree shortcuts
    gclean() - Clean merged branches
    groot() - cd to git root
    
  3. Docker shortcuts:
    dsh() - Interactive shell in container
    dlogs() - Follow logs
    dstop() - Stop all running containers
    
  4. File operations:
    extract() - Universal extraction
    fvo() - Fuzzy find and open
    backup() - Quick timestamped backup
    
  5. Project scaffolding:
    mkproject() - Create new project from template
    

Function design principles:

  • Accept arguments like real commands
  • Provide --help output
  • Handle errors gracefully
  • Use meaningful return codes
  • Don’t pollute the global namespace

Learning milestones:

  1. You have 5+ daily-use functions → You understand function syntax
  2. Functions handle arguments properly → You understand parameter expansion
  3. You have a help system → You understand self-documenting code
  4. Functions are organized in modules → You understand maintainable dotfiles

Project 8: FZF Power User Setup

  • File: LEARN_DOTFILES_PRODUCTIVITY.md
  • Main Programming Language: Bash/Zsh + FZF configuration
  • Alternative Programming Languages: Fish
  • Coolness Level: Level 3: Genuinely Clever
  • Business Potential: 1. The “Resume Gold”
  • Difficulty: Level 2: Intermediate
  • Knowledge Area: Fuzzy Finding / CLI UX
  • Software or Tool: fzf, ripgrep, bat, fd
  • Main Book: “Effective Shell” by Dave Kerr

What you’ll build: A comprehensive FZF setup with custom keybindings, preview windows, integration with git, docker, and kubernetes, and custom fuzzy finders for your specific workflows.

Why it teaches dotfiles: FZF transforms how you interact with the command line. Configuring it teaches you about Unix pipes, preview rendering, and building interactive CLI tools. It’s the glue that makes your other dotfiles more powerful.

Core challenges you’ll face:

  • Setting up default commands → maps to FZF_DEFAULT_COMMAND and fd
  • Creating useful previews → maps to bat, tree, and preview scripts
  • Building custom finders → maps to composing Unix tools with fzf
  • Integrating with other tools → maps to git, docker, kubectl fzf functions

Key Concepts:

  • FZF Basics: fzf wiki on GitHub
  • Unix Pipelines: “The Linux Command Line” Chapter 6 - William Shotts
  • fd and ripgrep: Tool documentation

Difficulty: Intermediate Time estimate: Weekend Prerequisites: Project 1, Project 7, basic understanding of Unix pipes

Real world outcome:

# Ctrl-T: Fuzzy find files with preview
$ vim <Ctrl-T>
┌──────────────────────────────────────────────────────────────┐
│ > src/                                                       │
├────────────────────────────────┬─────────────────────────────┤
│   src/auth/login.ts           │ 1 │ import { User } from     │
│   src/auth/logout.ts          │ 2 │   '../models/user';      │
│ > src/auth/oauth.ts           │ 3 │                          │
│   src/components/Button.tsx   │ 4 │ export async function    │
│   src/components/Form.tsx     │ 5 │   oauth(provider: str... │
│   src/index.ts                │   │                          │
│                               │   │ [Preview with syntax     │
│                               │   │  highlighting via bat]   │
└────────────────────────────────┴─────────────────────────────┘
  33/156

# Alt-C: Fuzzy cd with directory preview
$ <Alt-C>
┌──────────────────────────────────────────────────────────────┐
│ > proj                                                       │
├────────────────────────────────┬─────────────────────────────┤
│   ~/Developer/project-a       │ .                            │
│ > ~/Developer/project-b       │ ├── src/                     │
│   ~/Developer/project-c       │ ├── tests/                   │
│                               │ ├── package.json             │
│                               │ └── README.md                │
└────────────────────────────────┴─────────────────────────────┘

# Custom: Fuzzy git branch checkout
$ gco<Enter>  # Your function using fzf
┌──────────────────────────────────────────────────────────────┐
│ > auth                                                       │
├────────────────────────────────┬─────────────────────────────┤
│   main                        │ commit abc123                │
│   develop                     │ Author: You                  │
│ > feature/auth                │ Date: 2024-01-15             │
│   feature/payments            │                              │
│   bugfix/login-error          │ Add OAuth login support      │
└────────────────────────────────┴─────────────────────────────┘

# Custom: Fuzzy docker container shell
$ dsh<Enter>
? Select container:
  > api_container (Up 2 hours)
    db_container (Up 2 hours)
    redis_container (Up 2 hours)

Implementation Hints:

1. Install the ecosystem:

brew install fzf fd bat ripgrep
$(brew --prefix)/opt/fzf/install  # Keybinding setup

2. Configure defaults in your shell config:

Use fd instead of find (respects .gitignore, faster):

export FZF_DEFAULT_COMMAND='fd --type f --hidden --exclude .git'

Use bat for previews (syntax highlighting):

export FZF_CTRL_T_OPTS="--preview 'bat --color=always --style=numbers {}'"

3. Build custom fzf functions:

Pattern for fuzzy functions:

data_source | fzf [options] | process_selection

Ideas for custom finders:

  • gco: Fuzzy git checkout (branches)
  • gcoo: Fuzzy git checkout (commits)
  • ghpr: Fuzzy switch GitHub PRs
  • dsh: Fuzzy docker shell
  • kpod: Fuzzy kubectl exec into pod
  • ports: Fuzzy kill process by port
  • envs: Fuzzy view/edit dotenv files

4. Enable key bindings:

  • Ctrl-T: Paste file path
  • Ctrl-R: Search command history
  • Alt-C: cd to directory

5. Advanced: Multi-select mode (--multi or -m):

  • Select multiple files to edit
  • Select multiple branches to delete

Learning milestones:

  1. You use Ctrl-R for history → You understand basic fzf integration
  2. Previews show syntax highlighting → You understand fzf preview options
  3. You built 3+ custom fzf functions → You understand composing tools
  4. fzf is faster than file browsing → You’ve internalized fuzzy finding

Project 9: Dotfiles Bootstrap Script

  • File: LEARN_DOTFILES_PRODUCTIVITY.md
  • Main Programming Language: Bash
  • Alternative Programming Languages: Python, Ansible
  • Coolness Level: Level 3: Genuinely Clever
  • Business Potential: 2. The “Micro-SaaS / Pro Tool”
  • Difficulty: Level 2: Intermediate
  • Knowledge Area: Automation / System Administration
  • Software or Tool: Bash, homebrew
  • Main Book: “Wicked Cool Shell Scripts, 2nd Edition” by Dave Taylor and Brandon Perry

What you’ll build: A single-command bootstrap script that installs your complete development environment on a new machine: package manager, CLI tools, GUI applications, dotfiles symlinks, shell configuration, and verification that everything works.

Why it teaches dotfiles: This is where dotfiles become truly portable. You’ll learn about idempotent scripts, cross-platform considerations, symlink management, and the satisfaction of setting up a new machine in minutes instead of hours.

Core challenges you’ll face:

  • Making the script idempotent → maps to check before doing
  • Handling cross-platform differences → maps to macOS vs Linux
  • Managing symlinks properly → maps to ln -s strategies or stow
  • Dependency ordering → maps to installing in the right order

Key Concepts:

  • Shell Scripting Best Practices: “Wicked Cool Shell Scripts” - Dave Taylor
  • Idempotent Scripts: Configuration management concepts
  • GNU Stow: Stow documentation

Difficulty: Intermediate Time estimate: Weekend Prerequisites: Project 1, 7, understanding of shell scripting basics

Real world outcome:

# On a brand new Mac:
$ curl -fsSL https://raw.githubusercontent.com/yourusername/dotfiles/main/bootstrap.sh | bash

🚀 Dotfiles Bootstrap Starting...

[1/8] Installing Homebrew...
✓ Homebrew already installed, updating...

[2/8] Installing packages from Brewfile...
✓ Installing git
✓ Installing neovim
✓ Installing tmux
✓ Installing fzf
✓ Installing ripgrep
... (45 packages total)

[3/8] Installing cask applications...
✓ Installing alacritty
✓ Installing raycast
✓ Installing docker
... (12 applications)

[4/8] Setting up dotfiles symlinks...
✓ Linked .zshrc
✓ Linked .gitconfig
✓ Linked .config/nvim
✓ Linked .config/alacritty
✓ Linked .tmux.conf
... (23 symlinks)

[5/8] Configuring macOS defaults...
✓ Dock: auto-hide enabled
✓ Finder: show hidden files
✓ Screenshots: location set to ~/Screenshots

[6/8] Setting up shell...
✓ Zsh is default shell
✓ Installing oh-my-zsh
✓ Installing starship

[7/8] Installing language toolchains...
✓ Installing nvm + Node LTS
✓ Installing pyenv + Python 3.11
✓ Installing rustup + stable

[8/8] Verification...
✓ Git configured correctly
✓ Neovim plugins installed
✓ All symlinks valid

🎉 Setup Complete! Please restart your terminal.
   Time elapsed: 4m 32s

Implementation Hints:

Repository structure:

~/dotfiles/
├── bootstrap.sh          # Main entry point
├── scripts/
│   ├── brew.sh          # Package installation
│   ├── symlinks.sh      # Symlink management
│   ├── macos.sh         # macOS settings
│   └── verify.sh        # Verification tests
├── Brewfile             # Homebrew packages/casks
├── shell/
│   ├── zshrc
│   ├── aliases.zsh
│   └── functions/
├── git/
│   ├── gitconfig
│   └── gitignore_global
├── nvim/
│   └── init.lua
├── tmux/
│   └── tmux.conf
└── config/
    ├── alacritty/
    └── starship.toml

Key principles:

  1. Idempotence: Script should be safe to run multiple times ```bash

    Good: Check before installing

    command -v brew >/dev/null 2>&1 || install_homebrew

Good: Use –quiet or equivalent

brew bundle –quiet


2. **Symlink strategy** (choose one):
   - **Manual**: Use `ln -sf` with source and target
   - **Stow**: `stow shell` symlinks shell/* to ~
   - **Dotbot**: YAML-based symlink configuration

3. **Logging and colors**: Show progress clearly

4. **Error handling**: `set -euo pipefail` and trap

5. **Dry run option**: `--dry-run` to preview changes

**Brewfile format**:

Taps

tap “homebrew/cask-fonts”

CLI Tools

brew “git” brew “neovim” brew “tmux” brew “fzf” brew “ripgrep”

Applications

cask “alacritty” cask “docker” cask “raycast”

Fonts

cask “font-jetbrains-mono-nerd-font”


**Learning milestones**:
1. **Script installs packages** → You understand package management automation
2. **Symlinks are created correctly** → You understand dotfile organization
3. **Script is idempotent** → You understand robust scripting
4. **New machine takes <10 minutes** → You've achieved dotfile portability

---

## Project 10: Terminal Emulator Configuration (Alacritty/Kitty)

- **File**: LEARN_DOTFILES_PRODUCTIVITY.md
- **Main Programming Language**: YAML (Alacritty) / Conf (Kitty)
- **Alternative Programming Languages**: TOML (WezTerm)
- **Coolness Level**: Level 2: Practical but Forgettable
- **Business Potential**: 1. The "Resume Gold"
- **Difficulty**: Level 1: Beginner
- **Knowledge Area**: Terminal Configuration
- **Software or Tool**: Alacritty/Kitty/WezTerm
- **Main Book**: N/A (Tool documentation)

**What you'll build**: A fully configured modern terminal emulator with custom fonts (Nerd Fonts), color schemes, key bindings, and performance tuning that makes your terminal fast and visually pleasing.

**Why it teaches dotfiles**: The terminal emulator is your window into the CLI world. Configuring it teaches you about fonts, color theory, keybindings at the terminal level (vs shell level), and introduces you to GPU-accelerated terminals.

**Core challenges you'll face**:
- **Installing and configuring Nerd Fonts** → maps to *font rendering and glyphs*
- **Choosing/customizing color schemes** → maps to *ANSI colors and themes*
- **Setting up key bindings** → maps to *terminal vs shell key handling*
- **Performance tuning** → maps to *GPU acceleration options*

**Key Concepts**:
- **Terminal Emulation**: How terminals render text
- **ANSI Color Codes**: The 16 color system
- **Nerd Fonts**: Icon glyphs for development

**Difficulty**: Beginner
**Time estimate**: Half-day
**Prerequisites**: None, good first project

**Real world outcome**:

┌─────────────────────────────────────────────────────────────┐ │ │ │ ~/Developer/project on main via v18.17.0 │ │ ❯ ls │ │ │ │ .git/ README.md package.json │ │ .gitignore src/ tsconfig.json │ │ node_modules/ tests/ yarn.lock │ │ │ │ ~/Developer/project on main via v18.17.0 │ │ ❯ █ │ │ │ │ [Beautiful syntax highlighting, icons, fast scrolling] │ │ [GPU-accelerated rendering, no lag even with heavy output] │ │ │ └─────────────────────────────────────────────────────────────┘


**Implementation Hints**:

**1. Choose your terminal** (all are excellent):
- **Alacritty**: Simple, fast, YAML config
- **Kitty**: Feature-rich, conf file config
- **WezTerm**: Lua config, tabs built-in

**2. Install a Nerd Font**:
```bash
brew tap homebrew/cask-fonts
brew install --cask font-jetbrains-mono-nerd-font
# or: font-fira-code-nerd-font, font-hack-nerd-font

3. Configuration file location:

  • Alacritty: ~/.config/alacritty/alacritty.toml
  • Kitty: ~/.config/kitty/kitty.conf
  • WezTerm: ~/.wezterm.lua

4. Key configuration areas:

Font:

  • Font family (use your Nerd Font)
  • Font size (12-14 typical)
  • Font styles (bold, italic)

Colors:

  • Use a well-known scheme (Catppuccin, Dracula, Nord, Gruvbox)
  • Match your editor theme for consistency
  • Customize the 16 ANSI colors

Window:

  • Padding (some space around edges looks nice)
  • Opacity (slight transparency can be nice)
  • Decorations (title bar options)

Keybindings:

  • Copy/paste
  • Font size adjustments
  • New window/tab (if supported)

5. Popular color schemes:

  • Catppuccin (modern, soft)
  • Dracula (purple, popular)
  • Nord (cool, muted)
  • Gruvbox (warm, retro)
  • Tokyo Night (dark, vibrant)

Learning milestones:

  1. Nerd Font renders correctly → You understand font configuration
  2. Colors match your preference → You understand color schemes
  3. Terminal is noticeably faster → You understand GPU acceleration
  4. Config is version controlled → You understand dotfile portability

Project 11: ZSH Plugin System (Without Oh-My-Zsh Bloat)

  • File: LEARN_DOTFILES_PRODUCTIVITY.md
  • Main Programming Language: Zsh
  • Alternative Programming Languages: N/A
  • Coolness Level: Level 3: Genuinely Clever
  • Business Potential: 1. The “Resume Gold”
  • Difficulty: Level 3: Advanced
  • Knowledge Area: Shell Internals / Plugin Architecture
  • Software or Tool: Zsh, zinit/antibody/zplug
  • Main Book: “Learning the Zsh Shell” by O’Reilly (Peter Stephenson)

What you’ll build: A minimal, fast Zsh configuration using a modern plugin manager (zinit or similar), with lazy loading, turbo mode, and only the plugins you actually need—achieving sub-100ms shell startup times.

Why it teaches dotfiles: Moving beyond Oh-My-Zsh teaches you what plugins actually do under the hood, how to measure and optimize startup time, and how to build a lean configuration that’s fast and understandable.

Core challenges you’ll face:

  • Understanding Zsh initialization → maps to startup file order
  • Measuring and optimizing startup time → maps to profiling and lazy loading
  • Selecting essential plugins → maps to understanding what plugins do
  • Configuring completions properly → maps to compsys (Zsh completion system)

Key Concepts:

  • Zsh Startup Files: zsh.sourceforge.net documentation
  • Zinit: zinit wiki on GitHub
  • Zsh Completion System: “From Bash to Z Shell” Chapter 12

Difficulty: Advanced Time estimate: 1-2 weeks Prerequisites: Project 1, 7, comfortable with Zsh basics

Real world outcome:

# Shell startup in under 100ms (vs 500ms+ with Oh-My-Zsh)
$ time zsh -i -c exit
zsh -i -c exit  0.05s user 0.04s system 93% cpu 0.096 total

# Plugins loaded on demand
$ zsh-bench
=== Shell Startup Analysis ===
Total startup: 87ms
├── zinit core: 12ms
├── Plugins (turbo):
│   ├── zsh-syntax-highlighting: 8ms
│   ├── zsh-autosuggestions: 5ms
│   └── zsh-completions: 15ms
├── User config: 22ms
└── Compinit: 25ms

# Still have all the features:
✓ Syntax highlighting
✓ Autosuggestions
✓ Git info in prompt
✓ Advanced completions
✓ History substring search

# But understand exactly what each piece does!

Implementation Hints:

1. Understand Zsh startup files:

/etc/zshenv → ~/.zshenv         # Always
/etc/zprofile → ~/.zprofile     # Login shells
/etc/zshrc → ~/.zshrc           # Interactive shells
/etc/zlogin → ~/.zlogin         # Login shells

2. Choose a plugin manager:

  • zinit: Fastest, most features, steeper learning curve
  • antibody: Simple, fast
  • zplug: Feature-rich, slower
  • sheldon: Rust-based, very fast

3. Essential plugins (start minimal):

  • zsh-syntax-highlighting: Colors commands as you type
  • zsh-autosuggestions: Fish-like suggestions
  • zsh-completions: Additional completion definitions
  • (Maybe) zsh-history-substring-search: Better history navigation

4. Structure your config:

~/.config/zsh/
├── .zshenv           # Minimal, runs always
├── .zshrc            # Main config
├── plugins.zsh       # Plugin loading
├── options.zsh       # Zsh options (setopt)
├── completion.zsh    # Completion config
├── aliases.zsh       # Aliases
└── functions/        # Your functions

5. Measure startup time:

# Quick timing
time zsh -i -c exit

# Detailed profiling
zmodload zsh/zprof
# ... in .zshrc, at the end:
zprof

6. Optimization techniques:

  • Lazy load heavy things (nvm is notorious)
  • Use zinit turbo mode (load after prompt)
  • Compile completion cache
  • Don’t load plugins you don’t use

7. Understand what you’re loading: For each plugin, ask: What does it do? Can I write a simpler version?

Learning milestones:

  1. Startup time < 150ms → You understand lazy loading
  2. You can explain each plugin → You understand what they do
  3. Completions work correctly → You understand compsys
  4. You removed a plugin by writing your own → You’ve mastered Zsh internals

Project 12: XDG Base Directory Compliance

  • File: LEARN_DOTFILES_PRODUCTIVITY.md
  • Main Programming Language: Shell + various configs
  • Alternative Programming Languages: N/A
  • Coolness Level: Level 2: Practical but Forgettable
  • Business Potential: 1. The “Resume Gold”
  • Difficulty: Level 2: Intermediate
  • Knowledge Area: System Organization / Standards
  • Software or Tool: Various
  • Main Book: XDG Base Directory Specification

What you’ll build: A clean home directory by moving all dotfiles into XDG-compliant locations (~/.config, ~/.local/share, ~/.cache), with environment variables and symlinks to make non-compliant tools cooperate.

Why it teaches dotfiles: The XDG spec teaches you about proper dotfile organization, environment variables, and how to wrangle stubborn tools into compliance. The result is a clean, organized home directory.

Core challenges you’ll face:

  • Understanding XDG variables → maps to CONFIG, DATA, CACHE, STATE
  • Making stubborn tools comply → maps to environment variables and symlinks
  • Organizing different types of data → maps to config vs data vs cache
  • Testing that nothing breaks → maps to systematic migration

Key Concepts:

  • XDG Base Directory Spec: freedesktop.org specification
  • Environment Variables: How tools find their config
  • ArchWiki XDG page: Best practical reference

Difficulty: Intermediate Time estimate: Weekend Prerequisites: Project 1, understanding of environment variables

Real world outcome:

# BEFORE: Home directory chaos
$ ls -la ~ | head -20
.bash_history
.bash_profile
.bashrc
.cache
.cargo
.config
.docker
.gitconfig
.gnupg
.local
.node_repl_history
.npm
.npmrc
.profile
.python_history
.ssh
.vim
.viminfo
.zsh_history
.zshrc
... (50+ dotfiles)

# AFTER: Clean XDG-compliant home
$ ls -la ~
.cache    → Caches (safe to delete)
.config   → All configuration files
.local    → Data, state, and binaries
.ssh      → SSH (can't move, security)

$ ls ~/.config
alacritty/
git/
npm/
nvim/
shell/
starship.toml
tmux/
zsh/

$ ls ~/.local/share
cargo/
node/
nvim/
zsh/

$ echo $HOME
/Users/douglas
$ ls -la | wc -l
7  # Down from 50+!

Implementation Hints:

1. Understand the XDG variables:

export XDG_CONFIG_HOME="$HOME/.config"   # Config files
export XDG_DATA_HOME="$HOME/.local/share" # Persistent data
export XDG_STATE_HOME="$HOME/.local/state" # State (logs, history)
export XDG_CACHE_HOME="$HOME/.cache"      # Cache (deletable)

2. Move config files by tool:

Git (natively supports XDG):

# Just set the environment variable
export GIT_CONFIG_GLOBAL="$XDG_CONFIG_HOME/git/config"
# Move gitignore
mv ~/.gitignore_global ~/.config/git/ignore

Zsh:

export ZDOTDIR="$XDG_CONFIG_HOME/zsh"
# Move .zshrc to $ZDOTDIR/.zshrc
export HISTFILE="$XDG_STATE_HOME/zsh/history"

Node/npm:

export NPM_CONFIG_USERCONFIG="$XDG_CONFIG_HOME/npm/npmrc"
export NODE_REPL_HISTORY="$XDG_STATE_HOME/node_repl_history"

Cargo/Rust:

export CARGO_HOME="$XDG_DATA_HOME/cargo"
export RUSTUP_HOME="$XDG_DATA_HOME/rustup"

3. For tools that don’t support XDG:

  • Check the ArchWiki XDG page for workarounds
  • Some need symlinks
  • Some need wrapper aliases
  • Some are hopeless (.ssh for security reasons)

4. Create a migration checklist: Track each tool: current location, target location, how to move, verified working.

Learning milestones:

  1. Home directory has <10 visible files → You’ve migrated most tools
  2. All tools still work → You understand environment variables
  3. You documented the exceptions → You understand tool limitations
  4. Bootstrap script sets XDG vars → You’ve integrated with your setup

Project 13: Machine-Specific Configuration

  • File: LEARN_DOTFILES_PRODUCTIVITY.md
  • Main Programming Language: Shell
  • Alternative Programming Languages: Python
  • Coolness Level: Level 3: Genuinely Clever
  • Business Potential: 2. The “Micro-SaaS / Pro Tool”
  • Difficulty: Level 2: Intermediate
  • Knowledge Area: Configuration Management
  • Software or Tool: chezmoi or custom solution
  • Main Book: N/A (chezmoi documentation)

What you’ll build: A dotfiles system that handles multiple machines (work laptop, personal laptop, servers) with shared base configuration and machine-specific overrides, using templating or conditional logic.

Why it teaches dotfiles: Real dotfiles aren’t one-size-fits-all. Your work machine needs different git emails, your server doesn’t need GUI tools, and your personal machine has different paths. This project teaches configuration management patterns.

Core challenges you’ll face:

  • Detecting machine context → maps to hostname, OS, and feature detection
  • Templating configuration → maps to Go templates (chezmoi) or shell conditionals
  • Managing secrets → maps to encrypted files or secret managers
  • Testing across machines → maps to CI/CD for dotfiles

Key Concepts:

  • chezmoi: chezmoi.io documentation
  • Configuration Management: Ansible-style templating concepts
  • Secrets Management: Age encryption, password managers

Difficulty: Intermediate Time estimate: 1-2 weeks Prerequisites: Project 9 (Bootstrap Script), comfortable with shell scripting

Real world outcome:

# Same dotfiles repo works on all machines:

# On personal MacBook:
$ chezmoi apply
Applying .gitconfig: email = personal@example.com
Applying .config/alacritty: font_size = 14
Applying .config/shell/local.zsh: includes personal aliases

# On work MacBook:
$ chezmoi apply
Applying .gitconfig: email = work@company.com
Applying .config/alacritty: font_size = 13 (different monitor)
Applying .config/shell/local.zsh: includes work VPN helpers

# On headless server:
$ chezmoi apply
Skipping .config/alacritty: not applicable (no GUI)
Applying .bashrc: server-specific prompt
Applying .config/nvim: minimal server config

# Your repo structure:
~/.local/share/chezmoi/
├── .chezmoiignore            # What to skip where
├── .chezmoidata.yaml         # Machine data
├── dot_gitconfig.tmpl        # Templated gitconfig
├── dot_config/
│   ├── exact_nvim/           # Nvim config (all machines)
│   └── alacritty/
│       └── alacritty.toml.tmpl  # GUI machines only
└── run_once_install-packages.sh.tmpl  # Install script

Implementation Hints:

Approach 1: chezmoi (Recommended)

chezmoi is a dotfile manager with built-in templating:

# Initialize
chezmoi init

# Add a file (creates a copy in source)
chezmoi add ~/.gitconfig

# Edit the templated version
chezmoi edit ~/.gitconfig

Templates use Go syntax:

[user]
    email = {{ if eq .chezmoi.hostname "work-laptop" }}work@company.com{{ else }}personal@email.com{{ end }}

Data in .chezmoidata.yaml:

machine_type: personal  # or "work" or "server"
gui: true

Approach 2: Custom with shell conditionals

In your sourced config:

# Detect machine
case "$(hostname)" in
    work-*) export MACHINE_TYPE="work" ;;
    server-*) export MACHINE_TYPE="server" ;;
    *) export MACHINE_TYPE="personal" ;;
esac

# Load machine-specific config
[[ -f ~/.config/shell/machine-$MACHINE_TYPE.zsh ]] && \
    source ~/.config/shell/machine-$MACHINE_TYPE.zsh

Approach 3: Nix Home Manager (Advanced)

For truly declarative, reproducible dotfiles across machines.

Secrets management:

  • chezmoi: Built-in age encryption
  • git-crypt: Encrypt files in git
  • pass: Password manager
  • 1Password CLI: op read op://vault/item/field

Learning milestones:

  1. Same repo works on 2+ machines → You understand conditional config
  2. Work/personal emails are correct → You understand templating
  3. Secrets aren’t in plain text → You understand secrets management
  4. Server gets minimal config → You understand machine types

Project 14: Custom CLI Dashboard (Fastfetch + Custom Scripts)

  • File: LEARN_DOTFILES_PRODUCTIVITY.md
  • Main Programming Language: Shell + various
  • Alternative Programming Languages: Python
  • Coolness Level: Level 3: Genuinely Clever
  • Business Potential: 1. The “Resume Gold”
  • Difficulty: Level 2: Intermediate
  • Knowledge Area: CLI UX / System Information
  • Software or Tool: fastfetch/neofetch + custom scripts
  • Main Book: N/A

What you’ll build: A personalized login dashboard that displays system info, project status, upcoming tasks, git status of key repos, weather, and motivational quotes—giving you a productive starting point every time you open a terminal.

Why it teaches dotfiles: This project combines multiple dotfile skills: shell scripting, API calls, output formatting, and startup optimization. It’s fun, personal, and demonstrates your CLI craftsmanship.

Core challenges you’ll face:

  • Fetching data from multiple sources → maps to APIs and local commands
  • Formatting output beautifully → maps to ANSI colors and layout
  • Keeping it fast → maps to async data fetching
  • Making it useful, not noisy → maps to information design

Key Concepts:

  • ANSI Escape Codes: Terminal colors and formatting
  • Shell async: Background jobs and job control
  • fastfetch configuration: fastfetch documentation

Difficulty: Intermediate Time estimate: 1-2 weeks Prerequisites: Project 7 (Shell Functions), understanding of APIs

Real world outcome:

┌──────────────────────────────────────────────────────────────────┐
│                                                                  │
│   ███████╗██████╗  ██████╗    ██████╗ ███████╗██╗   ██╗         │
│   ╚══███╔╝██╔══██╗██╔════╝    ██╔══██╗██╔════╝██║   ██║         │
│     ███╔╝ ██████╔╝██║         ██║  ██║█████╗  ██║   ██║         │
│    ███╔╝  ██╔═══╝ ██║         ██║  ██║██╔══╝  ╚██╗ ██╔╝         │
│   ███████╗██║     ╚██████╗    ██████╔╝███████╗ ╚████╔╝          │
│   ╚══════╝╚═╝      ╚═════╝    ╚═════╝ ╚══════╝  ╚═══╝           │
│                                                                  │
│  douglas@macbook                          Sat, Dec 21, 10:30 AM  │
│  macOS Sonoma 14.2 • M2 Pro • 96°F                              │
│                                                                  │
├──────────────────────────────────────────────────────────────────┤
│  📂 RECENT PROJECTS                      📋 TODAY'S TASKS       │
│  ├── api-service        main ✓           ☐ Review PR #245       │
│  ├── web-frontend       feat/auth ●      ☐ Update docs          │
│  └── infrastructure     main ✓ (2 ahead) ☑ Deploy staging       │
│                                                                  │
│  ⌚ TIME TRACKED: 3h 42m today           🔥 GitHub: 15 day streak │
│                                                                  │
│  💡 "First, solve the problem. Then, write the code." - Torvalds │
│                                                                  │
└──────────────────────────────────────────────────────────────────┘

Implementation Hints:

1. Start with fastfetch for system info:

brew install fastfetch
fastfetch --gen-config
# Edit ~/.config/fastfetch/config.jsonc

2. Build custom modules as shell functions:

~/.config/shell/dashboard/
├── dashboard.zsh      # Main entrypoint
├── modules/
│   ├── git-status.zsh  # Check key repos
│   ├── tasks.zsh       # Todoist/Things/Obsidian tasks
│   ├── weather.zsh     # Weather API
│   └── quote.zsh       # Random quotes
└── cache/              # Cached API responses

3. Performance patterns:

  • Cache API responses with timestamps
  • Fetch slow data in background
  • Only refresh on new terminal session

4. Ideas for modules:

  • Git status: Status of your key repos
  • Tasks: Pull from todoist, things, notion, or local markdown
  • Weather: openweathermap.org API
  • Calendar: Next meeting from icalbuddy
  • Quotes: Local file or API
  • Pomodoro status: If you use a CLI pomodoro
  • GitHub notifications: gh api notifications

5. Display techniques:

  • Use figlet or toilet for ASCII art headers
  • Box drawing characters: ─ │ ┌ ┐ └ ┘ ├ ┤ ┬ ┴ ┼
  • Color with tput setaf N or ANSI codes
  • Icons from Nerd Fonts

6. Add to shell startup (but make it skippable):

# Only show on new session, not every subshell
if [[ -z "$DASHBOARD_SHOWN" ]]; then
    export DASHBOARD_SHOWN=1
    ~/.config/shell/dashboard/dashboard.zsh
fi

Learning milestones:

  1. Basic dashboard displays → You understand shell output formatting
  2. External APIs work → You understand curl and JSON parsing
  3. Dashboard is fast → You understand caching and async
  4. You look forward to opening terminal → You’ve made something personal

Project 15: Local Dev Environment Scripts (Projects, Services, Workflows)

  • File: LEARN_DOTFILES_PRODUCTIVITY.md
  • Main Programming Language: Shell
  • Alternative Programming Languages: Python, Makefile
  • Coolness Level: Level 3: Genuinely Clever
  • Business Potential: 2. The “Micro-SaaS / Pro Tool”
  • Difficulty: Level 3: Advanced
  • Knowledge Area: Developer Experience / Automation
  • Software or Tool: Shell, docker-compose, tmux
  • Main Book: “Wicked Cool Shell Scripts, 2nd Edition” by Dave Taylor

What you’ll build: A suite of scripts that automate your local development: dev start to spin up all services, dev stop to tear down, dev logs to aggregate logs, dev test to run tests correctly, dev reset to clean state—all project-aware and intelligent.

Why it teaches dotfiles: This is where dotfiles graduate from configuration to automation. You’ll build tools that understand your projects, compose other tools, and create the seamless development experience that makes you productive.

Core challenges you’ll face:

  • Detecting project type → maps to file detection and heuristics
  • Composing other tools → maps to docker, npm, python, etc.
  • Managing background processes → maps to job control and PIDs
  • Providing consistent interface → maps to subcommand design

Key Concepts:

  • Script Design: “Wicked Cool Shell Scripts” - Dave Taylor
  • Process Management: Background jobs, signals, traps
  • Project Detection: File existence checks, package.json/pyproject.toml

Difficulty: Advanced Time estimate: 2-3 weeks (ongoing) Prerequisites: Projects 7, 8, 9, solid shell scripting

Real world outcome:

# In any project directory:

$ dev start
🚀 Starting project: api-service (Node.js + Docker)
  ✓ Starting docker-compose services...
  ✓ Waiting for postgres (5432)...ready
  ✓ Waiting for redis (6379)...ready
  ✓ Running database migrations...
  ✓ Starting Node.js server in tmux...

  📎 Dashboard: http://localhost:3000
  📎 API: http://localhost:3000/api
  📎 Logs: dev logs

$ dev logs
┌─────────────────────────────────────────────────────────────┐
│ [api] Server listening on port 3000                         │
│ [postgres] LOG: database system is ready                   │
│ [redis] Ready to accept connections                         │
│ [api] GET /api/health 200 12ms                              │
└─────────────────────────────────────────────────────────────┘

$ dev test
🧪 Running tests for api-service
  Running: npm test
  ✓ 42 tests passed (1.2s)
  ✓ Coverage: 87%

$ dev stop
🛑 Stopping project: api-service
  ✓ Stopped Node.js server
  ✓ Stopped docker-compose services

$ dev reset
🔄 Resetting project: api-service
  ✓ Stopped all services
  ✓ Removed docker volumes
  ✓ Cleared node_modules
  ✓ Ready for fresh start

# Works in different project types:
$ cd ~/python-project && dev start
🚀 Starting project: python-project (Python + Poetry)
  ✓ Activating virtualenv...
  ✓ Starting docker-compose services...
  ✓ Running flask server in tmux...

Implementation Hints:

1. Structure your dev command:

~/.local/bin/dev           # Main script
~/.config/dev/
├── commands/
│   ├── start.sh
│   ├── stop.sh
│   ├── logs.sh
│   ├── test.sh
│   └── reset.sh
├── detectors/
│   ├── node.sh
│   ├── python.sh
│   ├── go.sh
│   └── rust.sh
└── config.yaml            # Global settings

2. Project detection:

detect_project_type() {
    if [[ -f package.json ]]; then
        echo "node"
    elif [[ -f pyproject.toml ]] || [[ -f requirements.txt ]]; then
        echo "python"
    elif [[ -f go.mod ]]; then
        echo "go"
    elif [[ -f Cargo.toml ]]; then
        echo "rust"
    else
        echo "unknown"
    fi
}

3. Project-local configuration (.devrc or dev.yaml):

# In project root: .devrc
type: node
services:
  - docker-compose
ports:
  api: 3000
  db: 5432
commands:
  test: npm test
  lint: npm run lint

4. Key subcommands:

  • dev start: Start all services, open tmux session
  • dev stop: Stop services, clean up
  • dev logs: Aggregate logs from all sources
  • dev test: Run tests with correct runner
  • dev reset: Full clean reset
  • dev shell: Open shell in container
  • dev db: Database utilities (migrate, console, seed)

5. Service management patterns:

  • Use tmux for persistent sessions
  • Store PIDs for cleanup
  • Wait for services with port checks
  • Aggregate logs with tail -f or lnav

Learning milestones:

  1. dev start works in 2+ project types → You understand project detection
  2. Services wait for dependencies → You understand health checking
  3. dev stop cleans everything → You understand process management
  4. Team members use your script → You’ve built something useful

Project 16: Keybinding System (Hammerspoon/Karabiner on macOS)

  • File: LEARN_DOTFILES_PRODUCTIVITY.md
  • Main Programming Language: Lua (Hammerspoon) / JSON (Karabiner)
  • Alternative Programming Languages: AppleScript
  • Coolness Level: Level 4: Hardcore Tech Flex
  • Business Potential: 1. The “Resume Gold”
  • Difficulty: Level 3: Advanced
  • Knowledge Area: macOS Automation / System Integration
  • Software or Tool: Hammerspoon, Karabiner-Elements
  • Main Book: N/A (Hammerspoon documentation + examples)

What you’ll build: A comprehensive keyboard automation system with custom hyper keys, application-specific shortcuts, window management, text expansion, and smart automation triggered by keyboard—all configured as code.

Why it teaches dotfiles: This extends your dotfiles beyond the terminal to your entire OS. You’ll learn Lua scripting, event-driven programming, and how to make your keyboard do things you never thought possible.

Core challenges you’ll face:

  • Creating a hyper key → maps to Karabiner complex modifications
  • Window management → maps to Hammerspoon hs.window
  • Application switching → maps to focus and launch logic
  • Building useful automations → maps to identifying repetitive tasks

Key Concepts:

  • Hammerspoon API: Hammerspoon documentation
  • Karabiner Config: Karabiner-Elements complex modifications
  • Lua Basics: Hammerspoon uses Lua for configuration

Difficulty: Advanced Time estimate: 2-3 weeks Prerequisites: Comfortable with configuration as code, some programming experience

Real world outcome:

Your keyboard becomes a power tool:

🔑 HYPER KEY (Caps Lock remapped):
   Hyper + H/J/K/L   → Window: Left/Down/Up/Right half
   Hyper + F         → Window: Fullscreen
   Hyper + C         → Window: Center
   Hyper + M         → Window: Maximize
   Hyper + N         → Window: Next monitor

🚀 APP LAUNCHER (Hyper + letter):
   Hyper + T         → Terminal (Alacritty)
   Hyper + B         → Browser (Arc/Chrome)
   Hyper + S         → Slack
   Hyper + V         → VS Code
   Hyper + E         → Finder
   Hyper + O         → Obsidian

⚡ SMART SHORTCUTS:
   Hyper + /         → Search selected text
   Hyper + G         → Open GitHub for current project
   Hyper + P         → Screenshot → Preview

📝 TEXT EXPANSION:
   @@m               → your.email@domain.com
   ;;date            → 2024-01-15
   ;;sig             → [Your signature block]

🎯 CONTEXT-AWARE:
   In Terminal:
     Hyper + R       → Reload config
   In Browser:
     Hyper + D       → Toggle DevTools
   In Slack:
     Hyper + U       → Jump to unread

Implementation Hints:

Part 1: Karabiner-Elements (Hyper Key)

Create a “Hyper” key by remapping Caps Lock:

  • Hold Caps Lock → Hyper (Cmd+Ctrl+Opt+Shift)
  • Tap Caps Lock → Escape

Config location: ~/.config/karabiner/karabiner.json

{
  "manipulators": [{
    "from": {"key_code": "caps_lock", "modifiers": {"optional": ["any"]}},
    "to": [{"key_code": "left_shift", "modifiers": ["left_command", "left_control", "left_option"]}],
    "to_if_alone": [{"key_code": "escape"}],
    "type": "basic"
  }]
}

Part 2: Hammerspoon (Automation)

Config location: ~/.hammerspoon/init.lua

-- Hyper key setup
local hyper = {"cmd", "alt", "ctrl", "shift"}

-- Window management
hs.hotkey.bind(hyper, "h", function()
  local win = hs.window.focusedWindow()
  win:moveToUnit(hs.layout.left50)
end)

-- App launching
hs.hotkey.bind(hyper, "t", function()
  hs.application.launchOrFocus("Alacritty")
end)

Key Hammerspoon modules:

  • hs.window: Window manipulation
  • hs.application: App control
  • hs.hotkey: Keybindings
  • hs.eventtap: Key/mouse events
  • hs.menubar: Menu bar items
  • hs.chooser: Spotlight-like picker

Ideas for automations:

  • Move windows to exact grid positions
  • Chain modifier keys (hold H, then tap 1-4)
  • Clipboard manager with history
  • Password input automation
  • Meeting quick-join (parse calendar)
  • Context-aware shortcuts

Learning milestones:

  1. Hyper key works → You understand Karabiner
  2. Window management is fluid → You understand Hammerspoon basics
  3. You have 10+ hyper shortcuts → You’ve identified your workflow
  4. Friends ask “how did you do that?” → You’ve automated the unusual

Project 17: Shell History and Knowledge System

  • File: LEARN_DOTFILES_PRODUCTIVITY.md
  • Main Programming Language: Shell + Rust (tools)
  • Alternative Programming Languages: Python
  • Coolness Level: Level 3: Genuinely Clever
  • Business Potential: 2. The “Micro-SaaS / Pro Tool”
  • Difficulty: Level 2: Intermediate
  • Knowledge Area: CLI Productivity / Personal Knowledge
  • Software or Tool: atuin, fzf, shell history
  • Main Book: N/A

What you’ll build: An advanced shell history system that syncs across machines, provides context-aware search, tracks command statistics, and integrates with your personal knowledge base for command documentation.

Why it teaches dotfiles: Your command history is a personal database of everything you’ve ever done in the terminal. This project teaches you to treat it as valuable data, not just a linear log.

Core challenges you’ll face:

  • Setting up atuin or mcfly → maps to history tool configuration
  • Syncing across machines → maps to atuin server or cloud sync
  • Adding context to commands → maps to directory, git repo, time
  • Building a personal cheatsheet → maps to navi or custom solution

Key Concepts:

  • atuin: Enhanced shell history (Rust-based)
  • navi: Interactive cheatsheet
  • Contextual history: Directory-aware command recall

Difficulty: Intermediate Time estimate: Weekend Prerequisites: Project 1, 8, understanding of shell history

Real world outcome:

# Search history with context (atuin):
$ <Ctrl-R>
┌──────────────────────────────────────────────────────────────────┐
│ Search: docker                                                   │
├──────────────────────────────────────────────────────────────────┤
│ ⏱ 2h ago   📂 ~/api-project    docker-compose up -d            │
│ ⏱ 1d ago   📂 ~/api-project    docker logs -f api               │
│ ⏱ 2d ago   📂 ~/api-project    docker exec -it api bash         │
│ ⏱ 1w ago   📂 ~/old-project    docker build -t myapp .          │
│ ⏱ 1m ago   📂 ~/work/infra     docker system prune -af          │
└──────────────────────────────────────────────────────────────────┘

# History synced across machines:
[on laptop]$ <Ctrl-R> kubectl apply
→ Shows command you ran on desktop yesterday!

# Statistics:
$ atuin stats
Commands run: 12,847
Most used: git (1,234), docker (876), cd (654)
Busiest hour: 10-11 AM
Busiest day: Tuesday

# Personal cheatsheet (navi):
$ navi
> docker: Remove all stopped containers
docker container prune -f

> kubernetes: Get pods in namespace
kubectl get pods -n <namespace>

# Quick documentation lookup:
$ explain docker run -it --rm -v $(pwd):/app node
docker run    → Run a command in a new container
  -it         → Interactive + TTY (for terminal)
  --rm        → Remove container when it exits
  -v          → Mount volume: $(pwd):/app
  node        → Image to use

Implementation Hints:

1. Install and configure atuin:

brew install atuin
# Add to .zshrc:
eval "$(atuin init zsh)"

atuin config (~/.config/atuin/config.toml):

dialect = "us"
auto_sync = true
sync_frequency = "10m"
search_mode = "fuzzy"
filter_mode = "global"  # or "host" or "directory"

2. History best practices:

# In .zshrc:
HISTSIZE=100000
SAVEHIST=100000
setopt EXTENDED_HISTORY      # Save timestamp
setopt INC_APPEND_HISTORY    # Add immediately
setopt SHARE_HISTORY         # Share between sessions
setopt HIST_IGNORE_DUPS      # No duplicates
setopt HIST_IGNORE_SPACE     # Space prefix = don't save

3. Set up navi for cheatsheets:

brew install navi
# Add to .zshrc:
eval "$(navi widget zsh)"

Create personal cheat files (~/.config/navi/cheats/personal.cheat):

% docker

# Remove all stopped containers
docker container prune -f

# Remove all unused images
docker image prune -af

# Shell into running container
docker exec -it <container> sh

$ container: docker ps --format '{{.Names}}'

4. Build a command explainer (shell function):

# Using explainshell.com API or local tldr
explain() {
    # Your implementation
}

Learning milestones:

  1. History search is instant → You understand atuin/fzf integration
  2. History syncs across machines → You understand atuin sync
  3. You have 20+ cheatsheet entries → You’ve built a personal knowledge base
  4. You recall complex commands easily → You’ve increased your productivity

Project 18: Complete Development Container (VS Code Dev Containers or Docker)

  • File: LEARN_DOTFILES_PRODUCTIVITY.md
  • Main Programming Language: Dockerfile + Shell
  • Alternative Programming Languages: Nix
  • Coolness Level: Level 3: Genuinely Clever
  • Business Potential: 3. The “Service & Support”
  • Difficulty: Level 3: Advanced
  • Knowledge Area: Containerization / Reproducible Environments
  • Software or Tool: Docker, VS Code Dev Containers
  • Main Book: N/A (devcontainers.json specification)

What you’ll build: A containerized development environment that includes all your dotfiles, tools, and configurations—providing a fully reproducible environment that you can spin up on any machine or cloud instance.

Why it teaches dotfiles: This is the ultimate test of your dotfiles: can they work in a container? You’ll learn about Dockerfiles, dotfile installation patterns, and how to create environments that are truly portable.

Core challenges you’ll face:

  • Installing dotfiles in container → maps to bootstrap script in Docker
  • Volume mounting for persistence → maps to Docker volumes strategy
  • Performance optimization → maps to layer caching, bind mounts
  • IDE integration → maps to VS Code Dev Containers

Key Concepts:

  • Dockerfile best practices: Multi-stage builds, layer caching
  • Dev Containers: VS Code devcontainer.json specification
  • Dotfiles in containers: Installation patterns

Difficulty: Advanced Time estimate: 1-2 weeks Prerequisites: Project 9, Docker experience, VS Code familiarity

Real world outcome:

# Open any project with dev container:
$ code project-folder/
# VS Code detects .devcontainer/devcontainer.json
# → "Reopen in Container" prompt appears
# → Click to open in container

# Inside container:
# - All your dotfiles are installed
# - Your shell config works
# - Your vim/neovim is configured
# - Git is configured with your identity
# - All project dependencies are installed

# Alternatively, start manually:
$ docker run -it --rm \
    -v $(pwd):/workspace \
    -v ~/.ssh:/home/dev/.ssh:ro \
    -v ~/.gitconfig:/home/dev/.gitconfig:ro \
    ghcr.io/yourusername/devcontainer:latest

# You're in a fully configured environment:
dev@container:~/workspace$ nvim .
# → Neovim with all plugins, LSP working

dev@container:~/workspace$ git status
# → Git works, knows who you are

dev@container:~/workspace$ npm test
# → All tools available

Implementation Hints:

1. Project structure:

.devcontainer/
├── devcontainer.json    # VS Code configuration
├── Dockerfile           # Container definition
├── docker-compose.yml   # Multi-service setup
└── scripts/
    └── post-create.sh   # Post-creation setup

2. devcontainer.json:

{
  "name": "My Dev Environment",
  "build": {
    "dockerfile": "Dockerfile",
    "context": ".."
  },
  "customizations": {
    "vscode": {
      "settings": {},
      "extensions": ["vscodevim.vim"]
    }
  },
  "features": {
    "ghcr.io/devcontainers/features/common-utils:2": {},
    "ghcr.io/devcontainers/features/docker-in-docker:2": {}
  },
  "postCreateCommand": ".devcontainer/scripts/post-create.sh",
  "mounts": [
    "source=${localEnv:HOME}/.ssh,target=/home/vscode/.ssh,type=bind,readonly"
  ]
}

3. Dockerfile patterns:

FROM mcr.microsoft.com/devcontainers/base:ubuntu

# Install tools
RUN apt-get update && apt-get install -y \
    neovim tmux fzf ripgrep fd-find \
    && rm -rf /var/lib/apt/lists/*

# Install your dotfiles
ARG DOTFILES_REPO=https://github.com/yourusername/dotfiles
RUN git clone $DOTFILES_REPO /home/vscode/dotfiles \
    && cd /home/vscode/dotfiles \
    && ./install.sh

4. Strategies for dotfiles in containers:

  • Clone and run bootstrap: Best for complete environments
  • Volume mount: Mount ~/.config from host
  • Chezmoi in container: Run chezmoi init in post-create
  • Minimal container: Only essential tools, dotfiles from volume

5. Persistence strategies:

  • Named volumes for data you want to persist
  • Bind mounts for code and config
  • Git for configuration changes

Learning milestones:

  1. Container builds with dotfiles → You understand Docker + dotfiles
  2. VS Code works in container → You understand Dev Containers
  3. Your workflow is identical in/out of container → You achieved portability
  4. New team members use your container → You created reproducible environments

Project Comparison Table

Project Difficulty Time Depth of Understanding Fun Factor
1. Shell Alias System Beginner Weekend ★★☆☆☆ ★★★☆☆
2. Git Configuration Beginner Weekend ★★★☆☆ ★★★☆☆
3. Custom Shell Prompt Intermediate Weekend ★★★☆☆ ★★★★☆
4. SSH Config Mastery Intermediate Weekend ★★★☆☆ ★★★☆☆
5. Neovim Configuration Advanced 1-2 weeks ★★★★★ ★★★★★
6. tmux Setup Intermediate Weekend ★★★★☆ ★★★★☆
7. Shell Functions Library Intermediate 1-2 weeks ★★★★☆ ★★★★☆
8. FZF Power User Intermediate Weekend ★★★★☆ ★★★★★
9. Bootstrap Script Intermediate Weekend ★★★★☆ ★★★★☆
10. Terminal Emulator Beginner Half-day ★★☆☆☆ ★★★☆☆
11. ZSH Plugin System Advanced 1-2 weeks ★★★★★ ★★★☆☆
12. XDG Compliance Intermediate Weekend ★★★☆☆ ★★☆☆☆
13. Machine-Specific Config Intermediate 1-2 weeks ★★★★☆ ★★★☆☆
14. CLI Dashboard Intermediate 1-2 weeks ★★★☆☆ ★★★★★
15. Dev Environment Scripts Advanced 2-3 weeks ★★★★★ ★★★★★
16. Hammerspoon/Karabiner Advanced 2-3 weeks ★★★★☆ ★★★★★
17. Shell History System Intermediate Weekend ★★★☆☆ ★★★★☆
18. Dev Container Advanced 1-2 weeks ★★★★★ ★★★★☆

Based on building skills progressively:

Phase 1: Foundation (Weeks 1-2)

  1. Project 10: Terminal Emulator - Quick win, visual improvement
  2. Project 1: Shell Alias System - Start customizing
  3. Project 2: Git Configuration - Essential tool config

Phase 2: Core Tools (Weeks 3-4)

  1. Project 3: Custom Shell Prompt - Make it yours
  2. Project 4: SSH Config - Remote work productivity
  3. Project 6: tmux Setup - Session management

Phase 3: Power User (Weeks 5-7)

  1. Project 7: Shell Functions - Build your toolkit
  2. Project 8: FZF Power User - Speed up everything
  3. Project 9: Bootstrap Script - Portability

Phase 4: Deep Customization (Weeks 8-11)

  1. Project 5: Neovim Configuration - The deep dive
  2. Project 11: ZSH Plugin System - Understand your shell
  3. Project 12: XDG Compliance - Clean organization

Phase 5: Advanced Integration (Weeks 12+)

  1. Project 13: Machine-Specific Config - Multi-machine
  2. Project 15: Dev Environment Scripts - Full automation
  3. Project 16: Hammerspoon/Karabiner - OS-level control
  4. Project 18: Dev Container - Ultimate portability

Optional Enhancements (Any time)

  • Project 14: CLI Dashboard - Fun personalization
  • Project 17: Shell History System - Knowledge management

Final Project: The Complete Portable Development Environment

  • File: LEARN_DOTFILES_PRODUCTIVITY.md
  • Main Programming Language: Shell + Lua + Docker
  • Alternative Programming Languages: Nix
  • Coolness Level: Level 5: Pure Magic
  • Business Potential: 4. The “Open Core” Infrastructure
  • Difficulty: Level 5: Master
  • Knowledge Area: Full-Stack Developer Experience
  • Software or Tool: All of the above
  • Main Book: All resources combined

What you’ll build: A complete, polished development environment system that:

  • Sets up any new machine in under 10 minutes
  • Works identically across macOS/Linux/containers
  • Has machine-specific configurations that just work
  • Provides documentation for every customization
  • Is version controlled and continuously improved
  • Could be published as a template for others

Why it’s the ultimate project: This combines every skill from the previous projects. It’s not just configuration—it’s a complete system that represents your development philosophy.

Core challenges you’ll face:

  • Integration of all systems → maps to consistent design across tools
  • Documentation that stays current → maps to self-documenting config
  • Testing your dotfiles → maps to CI/CD for dotfiles
  • Sharing while keeping secrets → maps to separation of public/private

Real world outcome:

# New machine setup:
$ curl -fsSL https://yourusername.github.io/dotfiles/install.sh | bash
# ... everything installs and configures ...

# 10 minutes later:
- Terminal: Beautiful, fast, yours
- Shell: All functions and aliases
- Editor: Neovim fully configured
- Git: Ready to commit
- tmux: Sessions restored
- Hammerspoon: Keyboard automation active
- Dev containers: Ready to use

# Your dotfiles repo:
github.com/yourusername/dotfiles/
├── README.md           # Beautiful documentation
├── docs/
│   ├── philosophy.md   # Why these choices
│   ├── keybindings.md  # All keyboard shortcuts
│   └── tools.md        # Tool explanations
├── install.sh          # Main entry point
├── Makefile           # Alternative interface
└── ... (all your config)

# Stars: 500+ (people use your setup as a template)

Implementation Hints:

This project is about integration and polish:

  1. Audit all your configurations - Document every choice
  2. Create a cohesive theme - Same colors everywhere
  3. Build comprehensive keybinding reference - Know every shortcut
  4. Add CI/CD - Test your install script on each commit
  5. Write genuine documentation - Not just what, but why
  6. Share your philosophy - Blog post or detailed README

This is less about new code and more about refinement, testing, and documentation of everything you’ve built.

Learning milestones:

  1. Install works on fresh machines → You’ve tested portability
  2. Others can use your dotfiles → You’ve documented well
  3. You rarely touch your config → It’s stable and complete
  4. You help others with theirs → You’ve internalized the concepts

Summary: All Projects

# Project Name Main Language
1 Shell Alias System Bash/Zsh
2 Git Configuration Powerhouse Git config / Bash
3 Custom Shell Prompt TOML (Starship) / Zsh
4 SSH Config Mastery SSH config syntax
5 Vim/Neovim Configuration Vimscript / Lua
6 Terminal Multiplexer Setup (tmux) tmux config
7 Shell Functions Library Bash/Zsh
8 FZF Power User Setup Bash/Zsh + FZF
9 Dotfiles Bootstrap Script Bash
10 Terminal Emulator Configuration YAML / TOML
11 ZSH Plugin System Zsh
12 XDG Base Directory Compliance Shell
13 Machine-Specific Configuration Shell
14 Custom CLI Dashboard Shell
15 Local Dev Environment Scripts Shell
16 Keybinding System (Hammerspoon) Lua / JSON
17 Shell History and Knowledge System Shell + Rust tools
18 Complete Development Container Dockerfile + Shell
Final Complete Portable Dev Environment All

Resources Summary

Essential Books

  • “The Linux Command Line, 2nd Edition” by William E. Shotts - Foundation
  • “Effective Shell” by Dave Kerr - Modern practices (free online)
  • “Practical Vim, 2nd Edition” by Drew Neil - Editor mastery
  • “tmux 3: Productive Mouse-Free Development” by Brian P. Hogan - Multiplexing
  • “Wicked Cool Shell Scripts” by Dave Taylor - Scripting patterns

Online Resources

  • ArchWiki - Best practical reference for most tools
  • dotfiles.github.io - Inspiration and patterns
  • r/unixporn - Visual inspiration
  • GitHub dotfiles topic - Thousands of examples

Tools to Install

# Essential CLI tools
brew install git neovim tmux fzf ripgrep fd bat eza
brew install starship atuin zoxide

# Optional but recommended
brew install delta lazygit tldr navi

# macOS automation
brew install --cask hammerspoon karabiner-elements

# Terminal
brew install --cask alacritty  # or kitty, wezterm

Happy customizing! Remember: the best dotfiles are the ones that help YOU work better. Start simple, add what you need, and iterate.