My Dev Env Setup
2026-04-04
My Dev Env setup
I keep all my dotfiles and development configurations in sync across my personal Mac, my work Mac, and my Linux virtual machines using Chezmoi and a GitHub repository.
Here is exactly how I set up a new machine, followed by a breakdown of the configurations themselves.
1. Setting up a New Machine
On macOS
-
Install Homebrew (if not already installed):
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" -
Install Chezmoi and essential tools:
brew install chezmoi gh fzf eza bat ripgrep starship git-delta fd tmux fastfetch stern make gnupg age pinentry-mac mise jj hl -
Install GUI Apps (macOS only):
brew install --cask ghostty brew install --cask nikitabobko/tap/aerospace
On Linux (Ubuntu/Debian)
-
Update and install basics:
sudo apt update && sudo apt install -y curl git zsh tmux -
Install Chezmoi:
sh -c "$(curl -fsLS get.chezmoi.io)"(Note: You may need to install the other CLI tools using
aptor by installing Homebrew for Linux).
Universal Setup Steps (All OSs)
-
Apply Dotfiles via Chezmoi: Initialize and apply your dotfiles straight from GitHub (assuming your dotfiles repo is
ruarfff/dotfiles):chezmoi init --apply ruarfff -
Install Zsh Plugins (no oh-my-zsh needed):
mkdir -p ~/.zsh git clone https://github.com/zsh-users/zsh-autosuggestions ~/.zsh/zsh-autosuggestions git clone https://github.com/zsh-users/zsh-syntax-highlighting ~/.zsh/zsh-syntax-highlighting -
Install Fonts: I use Departure Mono for my terminal. Download the
.otfor.ttffiles from the website and install them (e.g. double-click on macOS, or move to~/.local/share/fontson Linux). -
Change default shell to Zsh (if not already):
chsh -s $(which zsh)
2. Reference Configurations
Here is what is inside those dotfiles being pulled down by Chezmoi:
Ghostty (~/.config/ghostty/config)
theme = Citruszest
font-family = "Departure Mono"
font-size = 18
font-feature = +liga +calt
font-thicken = true
cursor-style = block
cursor-style-blink = true
cursor-color = "#ff00ff"
cursor-text = "#000000"
scrollback-limit = 100000
# Ergonomics
window-padding-x = 12
window-padding-y = 12
window-height = 40
window-width = 120
Starship (~/.config/starship.toml)
add_newline = false
palette = "catppuccin-mocha"
format = """
$directory$git_branch$git_state$git_status$nodejs$python$kubernetes$cmd_duration$line_break$character
"""
[directory]
style = "bold lavender"
truncation_length = 3
truncate_to_repo = true
[git_branch]
style = "purple bold"
symbol = " "
[git_status]
style = "red"
ahead = "⇡${count}"
diverged = "⇕"
modified = "!${count}"
[kubernetes]
symbol = "☸️ "
format = "[$symbol $context](bold blue) "
disabled = false
[python]
symbol = "🐍 "
style = "bold green"
format = "[$symbol$version]($style) "
[nodejs]
symbol = "⬢ "
style = "bold yellow"
format = "[$symbol$version]($style) "
[time]
disabled = false
format = "🕒 [$time](bold gray) "
time_format = "%H:%M"
[character]
success_symbol = "[❯](bold green)"
error_symbol = "[❯](bold red)"
Git Config (~/.gitconfig)
Uses delta for a vastly improved git diff experience.
[user]
name = "Ruairí O'Brien"
email = 1150322+ruarfff@users.noreply.github.com
[core]
pager = delta
excludesfile = ~/.gitignore
[push]
default = simple
[interactive]
diffFilter = delta --color-only
[delta]
navigate = true
side-by-side = true
line-numbers = true
[diff]
colorMoved = default
mnemonicprefix = true
[init]
defaultBranch = main
[branch]
autosetuprebase = always
[filter "lfs"]
clean = git-lfs clean -- %f
smudge = git-lfs smudge -- %f
process = git-lfs filter-process
required = true
[alias]
# list all aliases
la = "!git config -l | grep alias | cut -c 7-"
co = checkout
st = status -s
cm = commit -m
d = diff --word-diff
dlc = diff --cached HEAD^
# Show verbose output about tags, branches or remotes
tags = tag -l
branches = branch -a
remotes = remote -v
rem="!git config -l | grep remote.*url | tail -n +2"
# Pretty log output
hist = log --graph --pretty=format:'%Cred%h%Creset %s%C(yellow)%d%Creset %Cgreen(%cr)%Creset [%an]' --abbrev-commit --date=relative
Tmux (~/.config/tmux/tmux.conf)
# Use Ctrl+A instead of Ctrl+B (easier to type)
unbind C-b
set -g prefix C-a
bind C-a send-prefix
# Vim-style pane navigation
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
# Split panes with | and -
bind | split-window -h
bind - split-window -v
# Enable mouse
set -g mouse on
# Start windows at 1, not 0
set -g base-index 1
setw -g pane-base-index 1
# Renumber windows when one is closed
set -g renumber-windows on
# Colors
set -g default-terminal "screen-256color"
set -ga terminal-overrides ",*256col*:Tc"
# Status bar
set -g status-style bg=default,fg=white
set -g status-left "[#S] "
set -g status-right "%H:%M %d-%b"
Zsh (~/.zshrc)
eval "$(atuin init zsh --disable-up-arrow)"
bindkey '^[[A' up-line-or-search
bindkey '^[[B' down-line-or-search
eval "$(starship init zsh)"
eval "$(zoxide init zsh)"
eval "$(mise activate zsh)"
# Plugins
source ~/.zsh/zsh-autosuggestions/zsh-autosuggestions.zsh
source ~/.zsh/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
# History
HISTFILE=~/.zsh_history
HISTSIZE=50000
SAVEHIST=50000
setopt SHARE_HISTORY
setopt HIST_IGNORE_ALL_DUPS
setopt HIST_IGNORE_SPACE
# General ergonomics
setopt AUTO_CD
setopt HIST_IGNORE_DUPS
alias k='kubectl'
alias g='git'
alias ls="eza --icons --group-directories-first"
alias ll="eza -la --icons --group-directories-first"
alias cat="bat"
alias grep="rg"
alias ..="cd .."
alias ...="cd ../.."
alias dev="cd ~/dev"
alias cd='z'
# Optional colorized output
autoload -U colors && colors
export LSCOLORS=ExFxBxDxCxegedabagacad
export CLICOLOR=1
# fzf setup
source <(fzf --zsh)
export FZF_DEFAULT_COMMAND='fd --type f --hidden --follow --exclude .git'
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
export FZF_DEFAULT_OPTS='
--height 60%
--layout=reverse
--border
--preview "bat --color=always {}"
--color=bg+:#1e1e2e,bg:#11111b,spinner:#f5e0dc,hl:#f38ba8
--color=fg:#cdd6f4,header:#f38ba8,info:#cba6f7,pointer:#f5e0dc
--color=marker:#b4befe,fg+:#cdd6f4,prompt:#89b4fa,hl+:#f38ba8
'
# Other tools
export PATH="$HOMEBREW_PREFIX/opt/make/libexec/gnubin:$PATH"
export PATH="$PATH:$HOME/.dotnet/tools"
export PATH="$HOME/.local/bin:$PATH"
function maintain() {
echo "--- Updating Homebrew ---"
brew update && brew upgrade && brew cleanup
echo "--- macOS System Updates ---"
softwareupdate -i -a
echo "--- Other Updates ---"
go install github.com/steveyegge/gastown/cmd/gt@latest
go install github.com/steveyegge/beads/cmd/bd@latest
echo "--- Done ---"
}
Profile (~/.zprofile)
eval "$(/opt/homebrew/bin/brew shellenv zsh)"
export PATH="$PATH:/Applications/Obsidian.app/Contents/MacOS"
fastfetch
Gitignore (~/.gitignore)
.DS_Store
*ignore/
*.ignore.*
.venv/
.pytest_cache/