My macOS dotfiles, managed with GNU Stow.
This setup is built around a few core ideas:
omniwmfor a Hyprland-style tiling workflow on macOSsketchybarto replace the native menu bar with the info I actually wanttmuxplustmux-sessionizerfor fast context switching between projectscodexandclaudesurfaced in the bar so usage is visible at a glanceghostty,zsh, andnvimas the terminal-first daily drivers
omniwm/- window manager settings, keybinds, layouts, and app rulessketchybar/- status bar config, widgets, plugins, and launch agent helperstmux/- tmux config plus thetmux-sessionizerhelperzsh/- shell config, prompt, aliases, and lazy-loading setupghostty/- terminal confignvim/- Neovim config, LSP, editing workflow, and AI integration
brew bundle
git clone --depth=1 https://github.com/ohmyzsh/ohmyzsh.git ~/.oh-my-zsh
stow omniwm sketchybar tmux zsh ghostty nvimIf you only want part of the setup, stow the packages you need individually.
To check a machine after setup:
brew bundle check
stow -n -v -t ~ zshomniwm is the window manager layer for the desktop. The config leans into:
- tiled layouts by default
- strong window borders and visible gaps
- workspace switching with
Option+1throughOption+4 Option+Shift+<number>for moving windows between workspaces- a quake-style terminal for quick access
The config lives in omniwm/.config/omniwm/settings.toml.
sketchybar replaces the stock macOS menu bar with a minimal, functional status bar.
It currently surfaces:
- workspace and window state from
omniwm - CPU, battery, and clock info
- Claude usage
- Codex usage
The bar depends on the font-sketchybar-app-font cask for app icons, so make sure brew bundle has installed it before starting the bar.
The config is written in Lua and uses SbarLua, which must be installed separately so require("sketchybar") can load:
git clone https://github.com/FelixKratz/SbarLua.git /tmp/SbarLua
cd /tmp/SbarLua
make installAlso you need to do
chmod +x ~/Library/LaunchAgents/com.omniwm.sketchybar-watcher.plist
The Claude widget shows session and weekly usage in the bar.
It reads the Claude Code-credentials item from macOS Keychain, expects that item to contain JSON with an accessToken, and uses that token to query Anthropic's usage endpoint.
If the keychain item is missing, the widget will show an error until Claude Code has been signed in and the credentials item exists locally.
To set it up manually:
- Open
Keychain Access. - Search for
Claude Code-credentials. - Open the item, go to
Access Control, and add SketchyBar as an allowed app. - If you need to find the binary manually, use
Cmd+Shift+Gin Finder, jump to/opt/homebrew/bin, and selectsketchybar. - Make sure the item still contains the Claude JSON payload, including the
accessToken.
The widget looks for that exact item name, so keep it consistent.
The Codex widget reads ~/.codex/auth.json, uses the stored access token, and displays usage percentage plus reset timing in the bar.
tmux is configured for a fast, editor-like terminal workflow:
F12is the prefix but I use Hyperkey to rebind this to my Caps Lock, with a top-right indicator while prefix mode is activeOption-free navigation and split management- Vim-style scrollback through tmux copy mode
lazygitopens in a popuptmux-sessionizerjumps between project sessions quickly
The sessionizer helper lives in tmux/.local/bin/tmux-sessionizer.
Useful bindings:
F12thensfor a horizontal splitF12thenvfor a vertical splitF12thengforlazygitF12thenffor the sessionizer popupF12thenmor[for copy mode, thenj/k,/,v, andyto move, search, select, and copy to the macOS clipboard
zsh is set up for a practical shell-first workflow:
- standard Zsh layering with
.zshenv,.zprofile, and.zshrc - Oh My Zsh as the interactive shell baseline
- eager completion initialization, plus lazy-loaded
nvm - Atuin for searchable shell history
- Homebrew-managed
zsh-autosuggestions,zsh-syntax-highlighting, andzsh-system-clipboard - aliases for
nvim,tmux-sessionizer, andlazygit - an OMZ-based prompt with git branch and status counts
- paths for Go, Android, Bun, Node, PostgreSQL, and local binaries
Make sure ~/.oh-my-zsh exists before expecting the full interactive shell to work. The config sources Oh My Zsh from there for the git and nvm plugins, and the prompt expects OMZ's git_current_branch helper. The Homebrew-managed zsh integrations come from the repo Brewfile, so brew bundle check should be clean before debugging shell behavior.
nvim is the main editor config and includes:
- LSP setup
- formatting and treesitter
- file navigation and git tooling
- AI integration
- This repo is organized as stow packages, so each top-level directory maps to a package.
- Some configs expect local secrets or machine-specific files, such as the Claude cookie and Codex auth state.
- The SketchyBar OmniWM watcher is wired through a LaunchAgent at
sketchybar/Library/LaunchAgents/com.omniwm.sketchybar-watcher.plist.