Personal configuration files for development environment using GNU Stow with work/personal separation.
On a brand-new Mac, clone this repo and run the interactive bootstrap — it installs Nix, bootstraps nix-darwin, clones TPM and installs plugins, offers to set the hostname, and runs stow at the end:
git clone git@github.com:josephschmitt/dotfiles.git ~/.dotfiles
cd ~/.dotfiles
./install.sh --bootstrapThe bootstrap is idempotent — re-running it on a configured machine will skip completed steps. See the top-level README.md for the full flow description.
Required:
- GNU Stow for symlink management (installed automatically by nix-darwin)
- Git with SSH keys configured for GitHub
Install Stow manually if not using nix-darwin:
# macOS
brew install stow
# Ubuntu/Debian
sudo apt install stow
# Arch Linux
sudo pacman -S stow# 1. Clone the repository
git clone git@github.com:josephschmitt/dotfiles.git ~/.dotfiles
cd ~/.dotfiles
# 2. Update personal email in personal/.gitconfig
# Edit personal/.gitconfig and replace "your-personal@email.com" with your actual email
# 3. Apply configurations (pre-creates required directories, then runs stow)
./install.sh shared personal
# 5. Restart your shell or source configs
exec $SHELLNote: The shell configuration has been reorganized to follow Unix best practices. Your existing shell configs will be replaced with the new modular structure that eliminates duplication across Fish, Zsh, and Bash.
# 1. Clone the repository
git clone git@github.com:josephschmitt/dotfiles.git ~/.dotfiles
cd ~/.dotfiles
# 2. Initialize work submodule (requires access to private work repo)
git submodule update --init --recursive work
# 3. Apply configurations (pre-creates required directories, then runs stow)
./install.sh shared work
# 4. Restart your shell or source configs
exec $SHELLNotes:
- Work setup requires access to the private
dotfiles-work-privaterepository - The shell configuration has been reorganized to follow Unix best practices with shared modules
# 1. Clone the repository
git clone git@github.com:josephschmitt/dotfiles.git ~/.dotfiles
cd ~/.dotfiles
# 2. Initialize rca submodule (requires access to private rca repo)
git submodule update --init --recursive rca
# 3. Apply configurations (pre-creates required directories, then runs stow)
./install.sh shared rca
# 4. Restart your shell or source configs
exec $SHELLNotes:
- RCA setup requires access to the private
dotfiles-rca-privaterepository
shared/- Common configurations used on all machinespersonal/- Personal-specific configs (personal email, etc.)work/- Work-specific configs (private submodule with work email, company tools, etc.)rca/- RCA-specific configs (private submodule)
Multi-shell setup following Unix best practices with shared configuration:
-
Fish Shell (
.config/fish/) - Primary shell with modern features- Self-contained configuration with Fish-specific syntax
- Vi-mode keybindings and custom functions
- Oh-my-posh prompt integration
-
Zsh (
.zshrc,.zshenv,.zprofile) - Alternative shell- Zinit plugin manager with syntax highlighting and autocompletion
- Shared aliases and functions via POSIX-compliant modules
- macOS Terminal.app compatibility (login shell handling)
-
Bash (
.bashrc,.bash_profile) - Fallback shell- POSIX-compliant configuration
- Shared environment and interactive setup
Shared Configuration Philosophy:
.profile- Central environment setup (PATH, exports) for all POSIX shells.config/shell/- Modular shared configuration:exports.sh- Environment variablesaliases.sh- Common aliases (git-spice, development tools)functions.sh- Shared shell functions
- No duplication - Environment and aliases defined once, sourced everywhere
- Shell-specific optimizations - Each shell can have unique features while sharing core config
Setup Details:
- Stow will symlink individual
.configsubdirectories (never the entire.configfolder) - Shell profiles (
.zshrc,.bashrc, etc.) will be symlinked to your home directory - The new
.profilefile provides centralized environment setup for all shells
How Stow Handles Directories: Stow's symlinking behavior depends on whether directories exist at the target location:
- Directory doesn't exist: Stow creates a symlink to the entire directory
- Directory exists: Stow "unfolds" it and creates symlinks for individual files/subdirectories
This is why we create ~/.config/tmux before running stow. The -p flag creates both parent and child directories:
~/.config(parent) - Forces Stow to symlink individual app configs (.config/fish/,.config/tmux/, etc.) rather than the entire.configdirectory, preserving other applications' local-only configurations~/.config/tmux(child) - Ensures Stow symlinks individual tmux config files (liketmux.conf) instead of the entire directory, allowing TPM (Tmux Plugin Manager) to create and manage theplugins/subdirectory properly
- Helix (
.config/helix/) - Modal text editor- Catppuccin theme
- Custom keybindings for navigation
- Yazi file picker integration
- Git permalink generation
- Vim (
.vimrc) - Plain-Vim port of the Kickstart Neovim config for SSH boxes- Inline tokyonight-moon palette (no plugin needed for colors)
- Same options/keymaps as
shared/.config/nvim/where Vim 8+ supports them - Auto-bootstraps vim-plug; minimal plugin set: vim-commentary, vim-surround, vim-repeat, vim-fugitive, fzf.vim
- Neovim ignores this file, so it only loads when running plain
vim
- tmux (
.config/tmux/) - Terminal session management- Catppuccin theme with custom fork
- Plugin ecosystem (fzf, sessionx, floax)
- Vim-style navigation
- Session persistence
- Note:
~/.config/tmuxmust exist before stowing to prevent symlinking theplugins/directory (see tmux README)
- Git (
.gitconfig) - Version control with custom aliases - Ghostty (
.config/ghostty/) - Terminal emulator - Warp (
.warp/) - Modern terminal with AI features
- Nix configuration for reproducible environments
- pnpm, bun, cargo path configurations
- asdf version manager setup
- Consistent theming across all tools (Catppuccin)
- Vi-mode everywhere for consistent navigation
- Fuzzy finding integration (fzf) throughout the workflow
- Git workflow optimization with custom aliases and git-spice
- Development environment paths and tool configurations
If stow reports conflicts with existing files:
# Backup existing configs
mkdir ~/dotfiles-backup
mv ~/.gitconfig ~/dotfiles-backup/ # repeat for conflicting files
# Then retry stow
stow shared personal # or workIf work directory is empty:
git submodule update --init --recursive --forceEnsure your SSH key has access to the repositories:
ssh -T git@github.qkg1.topcd ~/.dotfiles
git pull origin main
# For work machines, also update submodule
git submodule update --remote- Add files to appropriate directory (
shared/,personal/, orwork/) - Re-run stow:
stow shared personal(orwork)
To remove all symlinks:
cd ~/.dotfiles
stow -D shared personal # or work