Personal dotfiles for macOS and Linux, managed with GNU Stow.
Cross-platform dotfiles for a terminal-based development environment optimized for Drupal/YaleSites development at Yale University. The same configuration works seamlessly on both macOS and Linux with automatic platform detection. The setup features:
- Terminal: Alacritty with TokyoNight theme
- Multiplexer: tmux with vim-aware navigation
- Shell: Zsh with async git status and extensive YaleSites utilities
- Editor: Neovim with LazyVim distribution
- Theme: Consistent TokyoNight across all tools
-
✅ macOS 13+ (Ventura and later)
- Intel and Apple Silicon (M1/M2/M3)
- Package manager: Homebrew
-
✅ Linux (Debian/Ubuntu-based)
- Pop!_OS 22.04+ (tested)
- Ubuntu 22.04+ (tested)
- Other Debian derivatives (should work)
- Package manager: apt
- Display servers: X11 and Wayland both supported
📖 Linux Users: See README-LINUX.md for Linux-specific installation instructions.
# Clone the repository
git clone https://github.com/yourusername/dotfiles.git ~/.dotfiles
cd ~/.dotfiles
# For testing the Linux branch (before merge):
# git checkout linux
# Initialize git submodules (zsh plugins)
git submodule update --init --recursive
# Run the installation script
./install.shNote: The cross-platform support is currently on the linux branch. After testing on Linux, this will be merged to master.
After installation, validate your dotfiles setup:
# Run comprehensive health check
make validate
# Check platform detection and environment
make check-platform
# Check basic prerequisites
make checkThe dotfiles-check script validates:
- ✅ Symlinks point to valid targets
- ✅ Git submodules are initialized
- ✅ Required binaries are installed
- ✅ Scripts have correct permissions
- ✅ Platform detection is working
- ✅ Shell scripts pass shellcheck (if installed)
Required:
- macOS 13+ (Ventura and later)
- Homebrew -
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" - GNU Stow -
brew install stow - Git -
brew install git
Recommended packages:
# Core tools
brew install tmux neovim zsh
# Terminal emulator
brew install --cask alacritty
# Font (required for proper display)
brew install --cask font-cascadia-code-nf
# Runtime version manager
brew install mise
# Additional utilities
brew install fzf ripgrep fd bat ezaOr install all dependencies at once:
cd ~/.dotfiles
brew bundle # Uses Brewfile in the repositoryRequired:
- Pop!_OS 22.04+ or Ubuntu 22.04+ (or other Debian-based distributions)
- GNU Stow -
sudo apt install stow - Git -
sudo apt install git
Install all system packages:
cd ~/.dotfiles
sudo apt update
sudo apt install -y $(grep -v '^#' packages.linux.txt | tr '\n' ' ')Additional software (not in apt):
Use the automated installer for eza, mise, Nerd Fonts, Lando, and Alacritty:
# Install all extras automatically
./install-linux-extras.sh --all
# Or install individually
./install-linux-extras.sh --eza
./install-linux-extras.sh --mise
./install-linux-extras.sh --fonts
./install-linux-extras.sh --lando
./install-linux-extras.sh --alacrittyOr use the Makefile:
make install-linux-extras📖 See README-LINUX.md for detailed Linux installation instructions and PACKAGES.md for cross-platform package mapping.
tmux Plugin Manager (TPM): The tmux configuration declares plugins but TPM is optional. To enable tmux plugins:
# Install TPM
git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
# Inside tmux, press prefix + I (capital i) to install pluginsWithout TPM, tmux will still function normally - you'll just see a brief error message on startup about missing plugins.
This repository uses GNU Stow for dotfile management. Each top-level directory is a "stow package" that mirrors your home directory structure:
dotfiles/
├── alacritty/ # Terminal emulator config
│ └── .config/alacritty/
├── archive/ # Archived scripts (not stowed; kept for reference)
│ └── scripts/
├── git/ # Git configuration
│ ├── .gitconfig
│ ├── .gitignore (global)
│ └── .gitmessage
├── lazyvim/ # Neovim LazyVim config
│ └── .config/lazyvim/
├── scripts/ # Cross-platform utility scripts
│ └── .local/bin/
├── scripts-linux/ # Linux-only scripts (display management, gaming backups)
│ └── .local/bin/
├── scripts-mac/ # macOS-only scripts (lock, killexchange, Lando/Drupal tools)
│ └── .local/bin/
├── tmux/ # tmux configuration
│ └── .tmux.conf
├── zsh/ # Zsh configuration
│ ├── .zshrc
│ ├── .zprofile
│ └── .config/zsh/ # Plugins (as submodules)
├── hammerspoon/ # macOS automation (optional)
├── karabiner/ # Keyboard customization (optional)
├── nvim/ # Alternative nvim config (optional)
├── vim/ # Fallback vim config (optional)
└── asdf/ # Legacy version manager config (optional)
Multiple packages can share the same target directory — scripts/, scripts-linux/, and scripts-mac/ all symlink files into ~/.local/bin/. Stow only the packages relevant to your platform.
When you stow a package, files are symlinked from ~/.dotfiles/<package>/<path> to ~/<path>.
The install.sh script provides an interactive installation:
./install.shIt will:
- Check for prerequisites (Homebrew, Stow)
- Initialize git submodules
- Offer to install each package interactively
- Back up existing configurations
- Create necessary directories
- Stow selected packages
If you prefer manual control:
# Initialize submodules (zsh plugins)
git submodule update --init --recursive
# Stow core packages (all platforms)
stow zsh
stow tmux
stow git
stow scripts
# macOS-specific
stow scripts-mac
stow hammerspoon
stow karabiner
# Linux-specific
stow scripts-linux
stow autostart
stow mise
# Optional packages
stow alacritty
stow lazyvim
stow nvim # Alternative neovim config
stow vim # Fallback vim configYou can install only what you need:
# Minimal shell setup
stow zsh git
# Add editor
stow lazyvim
# Add terminal
stow alacritty tmuxSensitive or machine-specific configurations should be placed in .local files, which are gitignored:
~/.zprofile.local- Machine-specific environment variables~/.zprofile.local.portkey- Portkey configuration for Claude Code.lando.local.yml- YaleSites local Lando configuration
The shell configuration sets up standard XDG base directories:
XDG_CONFIG_HOME→~/.configXDG_DATA_HOME→~/.local/shareXDG_CACHE_HOME→~/.cacheXDG_STATE_HOME→~/.local/state
The active Neovim config is controlled by NVIM_APPNAME in .zprofile:
export NVIM_APPNAME="lazyvim" # Uses ~/.config/lazyvim
# export NVIM_APPNAME="nvim" # Alternative: uses ~/.config/nvimThe zsh configuration includes extensive utilities for YaleSites/Drupal development:
llogin [--copy] [terminus-args]- Get Drupal login URLwatchdog [terminus-args]- Tail Drupal logsyspull- Update all YaleSites repos (project + atomic + component-library-twig)gyst- Git checkout matching branch across all reposdbget [multidev]- Pull database from Pantheon (default: dev)dbandfiles [multidev]- Pull database and filesconfim- Config import + cache rebuildlocal-setup- Initialize new YaleSites sitesiteid <site-name>- Get Pantheon site ID (cached)
l→landolcr→lando drush crldr→lando drushlrb→lando rebuild -y
See zsh/.zshrc lines 385-725 for complete YaleSites utilities.
prefix + |or\- Split horizontalprefix + -- Split verticalprefix + h/j/k/l- Navigate panesCtrl+h/j/k/l- Navigate panes/vim (seamless)prefix + b- Jump to last promptprefix + r- Reload configCtrl+Space Ctrl+Space- Last session
Alt+f- Launch tmux-sessionizer (fuzzy session switcher)Ctrl+r- History searchCtrl+Space- Accept autosuggestion
See LazyVim documentation for complete keybindings.
cd ~/.dotfiles
git pullThe zsh plugins are managed as git submodules:
# Update all plugins to latest
git submodule update --remote
# Update specific plugin
git submodule update --remote zsh/.config/zsh/zsh-autosuggestions
# Commit the updates
git add .gitmodules zsh/.config/zsh/
git commit -m "chore: update zsh plugins"make update # Update submodules
make restow # Restow all packages (useful after changes)If stow reports conflicts:
# See what would be done (dry-run)
stow -n -v zsh
# Force restow (replaces existing)
stow -R zsh
# Unstow first if needed
stow -D zsh
stow zsh# Ensure submodules are initialized
git submodule update --init --recursive
# Check plugins exist
ls -la ~/.config/zsh/# Ensure config is properly stowed
ls -la ~/.config/lazyvim # Should be a symlink
# If it's a real directory, unstow and restow:
rm -rf ~/.config/lazyvim # Back up first if needed!
stow lazyvimProfile your shell startup to identify bottlenecks:
# Enable profiling (uncomment lines in .zshrc)
# Then restart shell and run:
zprof
# Or time the shell startup
time zsh -i -c exitCommon causes:
- Slow plugin loading
- Network calls during startup (check for API calls)
- Too many PATH modifications
Ensure the tools are installed:
# Install mise
brew install mise
# Install nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
# Install bun
curl -fsSL https://bun.sh/install | bashThe .zshrc has conditional checks, so missing tools won't cause errors.
# Check Docker is running
docker ps
# Check Lando is installed
lando version
# Rebuild if issues persist
lando rebuild -yIf you encounter errors after the modular restructure:
# Check modules directory exists
ls -la ~/.config/zsh/rc.d/
# Verify all modules are sourced
grep -r "source.*rc.d" ~/.zshrc
# Check for syntax errors in modules
zsh -n ~/.config/zsh/rc.d/env.zsh
zsh -n ~/.config/zsh/rc.d/aliases.zsh
zsh -n ~/.config/zsh/rc.d/functions.zsh
zsh -n ~/.config/zsh/rc.d/yalesites.zshInstall CaskaydiaMono Nerd Font:
brew install --cask font-cascadia-code-nfThen restart Alacritty.
To remove a package:
# Unstow (removes symlinks)
stow -D zsh
# The original files remain in ~/.dotfiles/To remove everything:
cd ~/.dotfiles
stow -D */ # Unstow all packages
cd ~
rm -rf ~/.dotfilesThese are personal dotfiles, but feel free to:
- Fork for your own use
- Open issues for questions
- Submit PRs for general improvements
MIT License - feel free to use and modify for your own dotfiles.
- GNU Stow - Dotfile management
- LazyVim - Neovim configuration
- TokyoNight - Color scheme
- Inspired by many dotfiles repos in the community