A complete macOS development environment — Ruby/Rails, Elixir/Phoenix, Node/React, Python, Go, Rust, Zig — with your choice of Tokyo Night, Aura Dark, or Catppuccin Mocha theme applied everywhere.
This setup is inspired by DHH's Omakub and his "Everything in one place, everything just works" philosophy. The goal is simple:
- One Command Installation - From zero to productive development environment in minutes
- Unified Theme - Choose Tokyo Night, Aura Dark, or Catppuccin Mocha — applied across 17 apps for visual consistency. If theme apply fails partway, all configs are automatically restored.
- Keyboard-First - Vim motions, tiling windows, keyboard shortcuts for everything
- Modular Configuration - Clean, organized configs that are easy to understand and modify
- Developer Ergonomics - Tools chosen for speed, reliability, and joy of use
Like DHH's Omakub for Ubuntu, this setup provides:
- Opinionated but customizable - Great defaults, easy to change
- Battle-tested tools - Used daily for professional Rails and Elixir development
- Productivity-focused - Everything configured to minimize friction
- Beautiful aesthetics - Because we stare at code all day
| Tool | Why |
|---|---|
| Aerospace | i3-style tiling for macOS — keyboard-driven, distraction-free |
| Ghostty | GPU-accelerated terminal, native macOS, modern |
| Neovim + Zed | Neovim with AstroNvim for terminal, Zed for GUI — both with full LSP |
| zsh + Starship | Fast, reliable shell with a beautiful prompt |
| tmux + Zellij | Session management with vim integration |
| Tokyo Night / Aura / Catppuccin | Choose your theme — applied consistently across all tools |
Choose your theme during install — it's applied across 22 apps:
| Auto-configured (17) | Manual (links provided) |
|---|---|
| Neovim, Ghostty, tmux, Zellij, Starship, Zed, VS Code, Warp, bat, git-delta, fzf, lazygit, borders, sketchybar, yazi, gitui, lsd | Slack, Chrome, Firefox, Telegram, Raycast |
Switch anytime: dotfiles theme tokyo-night, dotfiles theme aura, or dotfiles theme catppuccin
- Ruby/Rails - mise, ruby-lsp, RuboCop, RSpec tasks, ERB formatting
- Elixir/Phoenix - mise, elixir-ls, mix integration, tailwindcss-language-server
- TypeScript/React - prettier, eslint, auto-imports, inlay hints
- Zig - zls (auto-installed), build/test/run tasks, 26 snippets
- Node.js - mise, npm/yarn
- Git - lazygit, fugitive, gitsigns
- Aerospace - i3-like tiling window manager for macOS
- Neovim + AstroNvim - Modern Vim distribution with LSP, Treesitter, Telescope
- tmux - Session management, vim integration, persistent sessions
- Zellij - Modern alternative to tmux with on-screen hints
- Starship - Fast, customizable prompt (16x faster than Spaceship)
- Harpoon - Quick file navigation (ThePrimeagen workflow)
- Smart CLI -
cduses zoxide (frecency),ls→eza,cat→bat,grep→ripgrep,find→fd
- Window Manager: Aerospace (i3-like tiling for macOS)
- Terminal: Ghostty (GPU-accelerated)
- Shell: zsh with modular configuration
- Prompt: Starship
- Multiplexers: tmux + Zellij
- Editors: Neovim with AstroNvim, Zed (settings, snippets, tasks)
- Version Control: Git (smart defaults, respects
$EDITOR, per-directory identity), lazygit, GitHub CLI - Work Management: work-setup, work-nuke, work-switch, work-status, repos-clone
- Dotfiles CLI:
dotfiles update,dotfiles sync,dotfiles health,dotfiles theme,dotfiles add-theme,dotfiles cleanup,dotfiles doctor,dotfiles backup,dotfiles profile,dotfiles export - Custom Scripts:
~/bin(erb-lint-formatter, etc.)
- mise - Modern version manager (replaces rbenv, nvm, asdf)
- Ruby (latest via mise)
- Elixir + Erlang (latest)
- Node.js (latest)
- Python 3
- Zig
- Go, Rust (latest)
- PostgreSQL 14
- MySQL
- Redis
- SQLite (via litecli)
- ripgrep, fd, fzf (fuzzy finding)
- bat (cat with syntax highlighting)
- eza (modern ls)
- tree (directory visualization)
- yazi (terminal file manager)
- lnav, tailspin (log viewers)
bash <(curl -fsSL https://raw.githubusercontent.com/AnjanJ/dotfiles/main/install.sh)Or if you prefer to clone first:
git clone https://github.com/AnjanJ/dotfiles.git ~/dotfiles && bash ~/dotfiles/install.shBoth are fully non-interactive with sensible defaults. No prompts, no questions — just run it.
bash install.sh --name "AJ" --email "aj@example.com" --theme aura
bash install.sh --work-email "aj@corp.com" --ssh generate
bash install.sh --interactive # Prompt for every choice (old behavior)
bash install.sh --no-macos-defaults # Skip macOS system preferences
bash install.sh --force # Force reinstall everything
bash install.sh --help # Show all options- ✅ Install Homebrew (if not installed)
- ✅ Install all packages from Brewfile
- ✅ Create symlinks to dotfiles (shell, tmux, Neovim, Zed, ~/bin)
- ✅ Apply your chosen theme (Tokyo Night, Aura Dark, or Catppuccin)
- ✅ Set up tmux plugins
- ✅ Configure Neovim
- ✅ Configure Zed (settings, snippets, tasks)
- ✅ Set up shell environment, Git defaults, and SSH keys
- ✅ Apply macOS defaults
- ✅ Run health check
💡 Truly idempotent — run it 10 times, get the same result. No backup clutter, no duplicate configs, no re-prompting.
📋 Want the full breakdown? See WHAT_GETS_INSTALLED.md — every tool, language, config, and system change explained step by step.
Installed Tools:
├── Window Management
│ └── Aerospace (i3-like tiling)
├── Terminals
│ └── Ghostty (GPU-accelerated)
├── Shell
│ ├── zsh (modular configuration)
│ └── Starship prompt
├── Multiplexers
│ ├── tmux (with 8 plugins)
│ └── Zellij
├── Editors
│ ├── Neovim + AstroNvim
│ └── Zed
├── Languages
│ ├── Ruby + mise
│ ├── Elixir + Erlang
│ ├── Node.js
│ ├── Python
│ ├── Zig
│ ├── Go
│ └── Rust
├── Databases
│ ├── PostgreSQL 14
│ ├── MySQL
│ ├── Redis
│ └── SQLite (litecli)
├── Dotfiles CLI
│ ├── dotfiles update (upgrade & sync)
│ ├── dotfiles sync (quick refresh — pull, relink, theme)
│ ├── dotfiles health (verify setup)
│ ├── dotfiles theme (switch theme)
│ ├── dotfiles add-theme (scaffold new theme)
│ ├── dotfiles cleanup (remove unlisted Homebrew packages)
│ ├── dotfiles doctor (auto-fix issues)
│ ├── dotfiles backup (snapshot/restore)
│ ├── dotfiles profile (shell startup timing)
│ ├── dotfiles export (portable setup snapshot)
│ ├── dotfiles install (run installer)
│ ├── dotfiles uninstall (remove symlinks)
│ └── dotfiles edit / dir (open editor / print path)
├── Work Management
│ ├── work-setup (configure work identity)
│ ├── work-nuke (remove work config)
│ ├── work-switch (change employer)
│ ├── work-status (show current setup)
│ └── repos-clone (clone from GitHub/GitLab/Bitbucket/Codeberg)
├── Custom Scripts
│ └── ~/bin (erb-lint-formatter, etc.)
└── Tools
├── Git + lazygit
├── ripgrep, fd, fzf
└── bat, eza, tree
The .zshrc is organized into focused, modular files:
~/.zshrc # Main config (loads everything)
~/.zshrc-dhh-additions # DHH-inspired workflows
~/.zshrc-elixir-additions # Elixir/Phoenix tools
~/.zshrc-terminal-enhancements # tmux, Zellij, Neovim aliases
~/.zshrc-work # Work-specific settings (optional)
Why modular?
- Easy to understand and modify
- Enable/disable features by commenting one line
- Share common configs, keep private ones separate
- Inspired by DHH's clean, organized approach
dotfiles/
├── .zshrc # Core: prompt, PATH, tool initialization
├── .zshrc-dhh-additions # Rails workflows, aliases, functions
├── .zshrc-elixir-additions # Elixir/Phoenix development
├── .zshrc-terminal-enhancements # Terminal multiplexers, editors
├── .zshrc-work # Work-specific (created by work-setup, not in repo)
├── .tmux.conf # tmux: sessions, vim integration, shortcuts
├── .config/
│ ├── aerospace/ # Window management: layouts, keybindings
│ ├── ghostty/ # Terminal: theme, fonts
│ ├── mise/ # Version manager (Ruby, Node, Elixir, etc.)
│ ├── nvim/ # Editor: LSP, plugins, keymaps
│ ├── zed/ # Zed: settings, snippets, tasks
│ ├── zellij/ # Multiplexer: config, theme, layouts (rails, phoenix, work)
│ ├── lazygit/ # Git UI: config + theme
│ ├── borders/ # JankyBorders: active window highlighting
│ ├── sketchybar/ # Menu bar: config + plugins
│ └── starship.toml # Prompt: git, languages, colors
├── bin/ # Custom scripts (erb-lint-formatter, etc.)
└── Brewfile # Declarative package management
Each file has a single responsibility. Want to change your Rails workflow? Edit .zshrc-dhh-additions. Need different terminal aliases? Modify .zshrc-terminal-enhancements.
-
Restart your terminal
source ~/.zshrc
-
Install tmux plugins
tmux # Press: Ctrl+A then Shift+I -
Open Neovim (plugins auto-install)
nvim
-
Start Aerospace
aerospace reload # Or: logout and login again
Note: Uses Ctrl+Shift for international keyboard compatibility (DHH-inspired)
| Key | Action |
|---|---|
Ctrl+Shift+H/J/K/L |
Focus window (vim-style navigation) |
Ctrl+Alt+H/J/K/L |
Move window |
Ctrl+Shift+1-9 |
Switch to workspace 1-9 |
Ctrl+Alt+1-9 |
Move window to workspace 1-9 |
Ctrl+Shift+Tab |
Toggle between last two workspaces |
Ctrl+Shift+/ |
Toggle layout (tiles/accordion) |
Ctrl+Shift+- |
Decrease window size |
Ctrl+Shift+= |
Increase window size |
App Launchers (Workspace-aware):
| Key | App | Workspace |
|---|---|---|
Ctrl+Shift+C |
Chrome (work) | 1 |
Ctrl+Shift+Z |
Zed editor | 2 |
Ctrl+Shift+W |
Ghostty terminal | 3 |
Ctrl+Shift+F |
Firefox (personal) | 5 |
Ctrl+Shift+G |
Ghostty terminal | 7 |
Ctrl+Shift+O |
Obsidian (PKM) | 8 |
Ctrl+Shift+P |
1Password | 9 |
Browser Window Cycling (across all workspaces):
| Key | Action |
|---|---|
Ctrl+Shift+N |
Next Chrome window |
Ctrl+Shift+B |
Previous Chrome window |
Alt+Shift+N |
Next Firefox window |
Alt+Shift+B |
Previous Firefox window |
| Key | Action |
|---|---|
Prefix | |
Split vertical |
Prefix - |
Split horizontal |
Prefix h/j/k/l |
Navigate panes (vim-style) |
Prefix H/J/K/L |
Resize panes |
Prefix c |
New window |
Prefix r |
Rails server |
Prefix C |
Rails console |
Prefix P |
Phoenix server |
Prefix I |
IEx console |
Prefix Shift+I |
Install plugins |
Prefix Shift+U |
Update plugins |
| Key | Action |
|---|---|
<Leader>ff |
Find files (Telescope) |
<Leader>fw |
Find word (grep) |
<Leader>fb |
Find buffers |
<Leader>ha |
Harpoon: add file |
Ctrl+H/J/K/L |
Harpoon: jump to marks 1-4 |
gd |
Go to definition |
gr |
Find references |
<Leader>la |
Code actions |
K |
Hover documentation |
<Leader>rc |
Rails: controller |
<Leader>rm |
Rails: model |
<Leader>rv |
Rails: view |
<Leader>rs |
Rails: spec |
| Key | Action |
|---|---|
Ctrl+O |
Enter command mode (shows options) |
Ctrl+G |
Lock mode (pass keys to terminal) |
Alt+H/J/K/L |
Navigate panes |
Ctrl+Q |
Quit Zellij |
Zellij Layouts (pre-configured via aliases):
| Alias | Layout | Tabs |
|---|---|---|
zr |
Rails | editor, server (rails s + console), tests, terminal |
zp |
Phoenix | editor, server (phx.server + iex), tests, terminal |
zw |
Work | editor, server (two panes), terminal |
Choose between Tokyo Night (dark blue), Aura Dark (deep purple), or Catppuccin Mocha (warm pastels) during install. The theme is applied across 22 apps (17 auto-configured + 5 with manual instructions).
Browse the full galleries: Tokyo Night | Aura Dark | Catppuccin
| Tokyo Night | Aura Dark | Catppuccin Mocha | |
|---|---|---|---|
| Background | #1a1b26 |
#15141b |
#1e1e2e |
| Foreground | #c0caf5 |
#edecee |
#cdd6f4 |
| Primary accent | #7aa2f7 blue |
#a277ff purple |
#b4befe lavender |
| Secondary | #bb9af7 purple |
#61ffca green |
#94e2d5 teal |
| Success | #9ece6a green |
#61ffca green |
#a6e3a1 green |
| Error | #f7768e red |
#ff6767 red |
#f38ba8 red |
| Warning | #e0af68 yellow |
#ffca85 orange |
#f9e2af yellow |
Switch anytime: dotfiles theme tokyo-night, dotfiles theme aura, or dotfiles theme catppuccin
dotfiles/
├── install.sh # Main installation script (idempotent)
├── update.sh # Update script for syncing changes
├── Brewfile # Homebrew packages (auto-generated)
├── README.md # This file
├── QUICK_REFERENCE.md # Cheat sheet
├── .zshrc # Main shell config
├── .zshrc-dhh-additions # Rails workflows
├── .zshrc-elixir-additions # Elixir/Phoenix
├── .zshrc-terminal-enhancements # Terminal tools
├── .tmux.conf # tmux configuration
├── .config/
│ ├── aerospace/ # Window manager config
│ ├── ghostty/ # Terminal config
│ ├── mise/ # Version manager (Ruby, Node, Elixir, etc.)
│ ├── nvim/ # Neovim config (AstroNvim)
│ ├── zed/ # Zed editor config
│ │ ├── settings.json # Language, LSP, formatter, extension settings
│ │ ├── tasks.json # RSpec, Rails, Elixir, Zig, npm tasks
│ │ └── snippets/ # ruby.json, erb.json, zig.json
│ ├── zellij/ # Zellij config, theme, layouts
│ ├── lazygit/ # Lazygit config + theme
│ ├── borders/ # JankyBorders window highlighting
│ ├── sketchybar/ # Menu bar config + plugins
│ └── starship.toml # Prompt configuration
├── themes/ # Theme assets (each has a theme.conf registry)
│ ├── tokyo-night/ # Tokyo Night configs per app
│ ├── aura/ # Aura Dark configs per app
│ └── catppuccin/ # Catppuccin Mocha configs per app
├── bin/ # CLI commands (all available globally via ~/bin)
│ ├── dotfiles # Main CLI dispatcher
│ ├── dotfiles-update # Upgrade system & sync repo
│ ├── dotfiles-sync # Quick refresh: pull, relink, reapply theme
│ ├── dotfiles-health # Verify all tools are installed
│ ├── dotfiles-theme # Switch theme
│ ├── dotfiles-install # Run full installer
│ ├── dotfiles-uninstall # Remove all dotfiles symlinks
│ ├── dotfiles-backup # Snapshot/restore dotfiles state
│ ├── dotfiles-doctor # Auto-fix common issues + SSH key audit
│ ├── dotfiles-profile # Measure shell startup time
│ ├── dotfiles-export # Export setup as portable snapshot
│ ├── dotfiles-add-theme # Scaffold new theme directory
│ ├── dotfiles-cleanup # Remove unlisted Homebrew packages
│ ├── work-setup # Configure work identity
│ ├── work-nuke # Remove all work config
│ ├── work-switch # Change employer
│ ├── work-status # Show current work setup
│ ├── repos-clone # Clone repos from GitHub/GitLab/Bitbucket/Codeberg
│ ├── erb-lint-formatter # ERB lint wrapper for Zed
│ └── _work-helpers # Shared utilities for work scripts
├── Brewfile.backup # Previous Brewfile (one backup, for rollback)
├── scripts/
│ ├── _helpers.sh # Shared colors & print functions
│ ├── setup-git.sh # Git identity & defaults setup
│ ├── setup-ssh.sh # SSH key & config setup
│ ├── health-check.sh # Verify installation
│ ├── theme-utils.sh # Theme utility functions
│ └── apply-theme.sh # Apply theme across all apps
├── tests/ # 300 tests across 11 suites, run via GitHub Actions CI
│ ├── test-idempotency.sh # Idempotency tests (sandboxed)
│ ├── test-work-nuke.sh # Work-nuke edge case tests
│ ├── test-repos-clone.sh # Repos-clone logic tests
│ ├── test-ssh-adversarial.sh # SSH adversarial input tests
│ ├── test-update.sh # Update symlink tests
│ ├── test-theme.sh # Theme system tests (apply, rollback, scaffold)
│ ├── test-doctor.sh # Doctor auto-fix tests
│ ├── test-setup-git.sh # Git identity setup tests
│ ├── test-work-status.sh # Work status diagnostic tests
│ ├── test-backup.sh # Backup/restore cycle tests
│ └── test-sync.sh # Sync symlink refresh tests
├── .github/workflows/test.yml # CI: shellcheck + all test suites
└── docs/ # Additional documentation
All commands work from anywhere — no need to cd ~/dotfiles first.
dotfiles update # Upgrade system & sync repo (pull → brew upgrade → snapshot → push)
dotfiles sync # Quick refresh: pull, relink, reapply theme (no upgrades)
dotfiles health # Verify all tools are installed and configured
dotfiles theme aura # Switch theme (tokyo-night | aura | catppuccin)
dotfiles add-theme x # Scaffold a new theme directory with all required files
dotfiles cleanup # Find/remove Homebrew packages not in Brewfile (--force)
dotfiles doctor # Auto-fix common issues (symlinks, permissions, SSH keys)
dotfiles backup # Snapshot dotfiles state (--list, --restore <name>)
dotfiles profile # Measure shell startup time (--detailed for per-component)
dotfiles export # Export setup snapshot (--json for machine-readable)
dotfiles install # Re-run full installer (idempotent)
dotfiles edit # Open dotfiles in your editor
dotfiles dir # Print dotfiles directory pathAll commands support tab-completion. Shorthand also works: dotfiles-update, dotfiles-sync, etc.
- Pull latest changes from git
brew update+brew upgrade+brew cleanup- Snapshot Brewfile (captures any new apps you installed manually)
- Refresh all symlinks
- Upgrade mise tools
- Update tmux plugins
- Reload live configs (tmux, aerospace)
- Commit & push changes back to repo
Your Brewfile stays in sync automatically. Install apps with brew install or mas install anytime — the next dotfiles update captures them into the repo. One Brewfile.backup is kept for rollback.
dotfiles healthVerifies: core tools, config symlinks, language runtimes, running services (PostgreSQL, MySQL, Redis), shell integrations, and work identity.
The install script is truly idempotent — run it any number of times with identical results:
dotfiles install # Non-interactive, skips what's done
dotfiles install --interactive # Prompt for every choice
dotfiles install --force # Force reinstall everythingSwitch between Tokyo Night, Aura Dark, and Catppuccin Mocha from anywhere:
dotfiles theme tokyo-night # Switch to Tokyo Night
dotfiles theme aura # Switch to Aura Dark
dotfiles theme catppuccin # Switch to Catppuccin MochaThis updates 17 apps automatically (Neovim, Ghostty, tmux, Zellij, Starship, Zed, VS Code, Warp, bat, git-delta, fzf, lazygit, borders, sketchybar, yazi, gitui, lsd), then prints instructions for Slack, browsers, Telegram, and Raycast. If the apply fails partway through, all configs are automatically rolled back.
Adding a new theme is just creating a themes/<name>/ directory with a theme.conf — themes are auto-discovered, no code changes needed. Use dotfiles add-theme <name> to scaffold the full directory structure.
Edit Brewfile and run:
brew bundle install- Settings:
.config/zed/settings.json(languages, LSP, formatters) - Tasks:
.config/zed/tasks.json(RSpec, Rails, Zig, etc.) - Snippets:
.config/zed/snippets/(ruby.json, erb.json, zig.json)
- Aerospace:
.config/aerospace/aerospace.toml - tmux:
.tmux.conf - Neovim:
.config/nvim/lua/plugins/*.lua
During install, you can choose 1Password SSH Agent for SSH key management. This gives you:
- Touch ID for git push — each new terminal session requires biometric approval before SSH operations
- No key files on disk — keys live in your 1Password vault, encrypted and synced
- Works everywhere — GitHub, GitLab, Bitbucket, Codeberg, self-hosted Git
How it works:
- Install sets up
~/.ssh/configto use the 1Password agent socket - When you
git pushin a new terminal session, 1Password prompts for Touch ID - Approval lasts until 1Password locks (configurable timeout)
Recommended 1Password settings for maximum security:
| Setting | Value | Why |
|---|---|---|
| Ask approval for each new | application and terminal session |
Per-tab approval, not global |
| Remember key approval | until 1Password locks |
Approval expires on lock |
| Auto-lock after idle | 1 minute (or shortest you're comfortable with) |
Frequent re-authentication |
Note: This is per-session, not per-push. Once you approve in a terminal tab, subsequent pushes in that tab go through until 1Password locks. For additional protection, consider a short auto-lock timeout.
See QUICK_REFERENCE.md for SSH troubleshooting and testing commands.
# Apple Silicon
eval "$(/opt/homebrew/bin/brew shellenv)"
# Intel
eval "$(/usr/local/bin/brew shellenv)"# Remove and reinstall
rm -rf ~/.tmux/plugins
git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
tmux
# Press: Ctrl+A then Shift+I# Clear cache and reinstall
rm -rf ~/.local/share/nvim
rm -rf ~/.cache/nvim
nvim # Will reinstall everything# Reload configuration
aerospace reload
# Or restart
killall Aerospace
open -a AerospaceDetailed guides for each tool:
- What Gets Installed - Full breakdown of every tool and config change
- Quick Reference - Print this!
- Neovim Guide
- Daily Workflows
300 automated tests across 11 suites run on every push and PR via GitHub Actions:
- Shellcheck — lints all shell scripts (auto-discovers via glob patterns)
- Idempotency — verifies install/setup can run multiple times safely (84 assertions)
- Work identity — tests setup, nuke, switch lifecycle, and status diagnostics
- SSH config — adversarial inputs and edge cases
- Repo cloner — SSH alias detection and URL rewriting
- Update flow — symlink creation and refresh
- Theme system — apply, rollback, idempotency, scaffolding (39 assertions)
- Doctor — auto-fix symlinks, permissions, dry-run mode
- Git setup — identity configuration, work/personal split, smart defaults
- Backup — create, list, restore, prune cycle
- Sync — symlink refresh, broken link repair, dry-run mode
Run locally: bash tests/test-idempotency.sh (or any test file in tests/)
- DHH - Omakub philosophy, Rails workflows, clean configurations
- Omakub - "Everything in one place" installation concept
- ThePrimeagen - Harpoon workflow, tmux setup, vim-first development
- José Valim - Elixir tooling and workflows
- AstroNvim - Neovim distribution
- Tokyo Night - Dark blue theme by folke
- Aura Theme - Deep purple theme by daltonmenezes
- Starship - Fast prompt
- Aerospace - Window manager
- Ghostty - Modern terminal
MIT License - Feel free to use and modify!
Found a bug or have a suggestion? Open an issue or PR!
Made with ❤️ by AJ
If this setup saves you time, consider buying me a coffee ☕
Inspired by DHH's Omakub and ThePrimeagen's workflows
Last updated: 2026-03-14











