My macOS config, managed with GNU stow. Each top-level directory is a stow
package whose internal layout mirrors $HOME, so stow zsh creates
~/.zshrc -> ~/dotfiles/zsh/.zshrc.
Primary machine is macOS (Apple Silicon), and that is what install.sh targets.
The zsh, nvim and tmux packages are written to work on Linux and WSL too:
home paths go through $HOME, and anything machine-specific lives in
~/.zshrc.local rather than in the tracked config. install.sh itself is
macOS only, so on Linux run stow by hand for the packages you want.
| Package | Target | Tool |
|---|---|---|
zsh |
~/.zshrc |
shell |
nvim |
~/.config/nvim |
Neovim, lazy.nvim, native LSP |
ghostty |
~/.config/ghostty/config |
terminal |
starship |
~/.config/starship.toml |
prompt |
tmux |
~/.tmux.conf |
tmux + tpm |
direnv |
~/.config/direnv |
per-directory env |
aerospace |
~/.config/aerospace/aerospace.toml |
tiling WM |
eza |
~/.config/eza/theme.yaml |
ls replacement theme |
git |
~/.config/git/ignore |
global gitignore |
nushell |
~/.config/nushell |
nushell |
bin |
~/.local/bin |
small scripts |
bash |
~/.bashrc, ~/.bash_profile |
fallback shell |
agents |
~/.agents/skills |
shared Codex and Claude skills |
Versions below are what this config is currently developed against. Older usually works, but Neovim 0.10 or lower will not: the config uses the 0.11 native LSP API.
- macOS on Apple Silicon, Homebrew at
/opt/homebrew - git 2.50 or newer
- zsh 5.9 (ships with macOS)
- GNU stow 2.4
- Neovim 0.11.6 or newer
- tmux 3.5a
- starship 1.22
- A Nerd Font. The terminal config asks for
JetBrainsMono Nerd Font.
Core set the configs actually depend on:
brew install stow neovim tmux starship eza zoxide direnv fzf bat git-lfs gh tree wget
brew install --cask ghostty aerospace font-jetbrains-mono-nerd-font
Not installed by the bootstrap script, install what you need:
- Node via nvm (
~/.nvm), currently v22 - Python 3.12 (miniconda) plus
uv - Rust via rustup, Go,
openjdk@17,bun
The .zshrc sources nvm, conda and bun only if they are present, so a machine
without them still gets a working shell.
conform.nvim formats on save and expects these on PATH:
brew install stylua
npm install -g prettier
uv tool install black
uv tool install isort
uv tool install mdformat
Missing formatters degrade to LSP formatting, they do not break anything.
git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
Then open tmux and press prefix + I (prefix is C-a) to install the rest.
git clone git@github.com:JDRanpariya/dotfiles.git ~/dotfiles
cd ~/dotfiles
./install.sh
install.sh checks prerequisites, backs up any existing real file it would
replace into ~/.dotfiles-backup/<timestamp>/, then runs stow for the macOS
packages.
To stow or unstow one package by hand:
cd ~/dotfiles
stow zsh # link
stow -D zsh # unlink
stow -R zsh # relink after moving files around
Stow refuses to overwrite an existing real file. If it complains, move the existing file aside first.
~/.zshrc holds PATH, aliases and shell integrations only. Anything secret or
machine-specific goes in ~/.zshrc.local, which is gitignored and sourced at
the end of .zshrc if it exists:
[ -f "$HOME/.zshrc.local" ] && source "$HOME/.zshrc.local"Homebrew's shellenv lives in ~/.zprofile, which is not tracked here because
its contents differ per machine.
Plugin manager is lazy.nvim, bootstrapped on first launch. lazy-lock.json is
committed, so :Lazy restore reproduces exact plugin versions. LSP servers are
installed through Mason on first use.
nvim/README.md documents the keymaps.
The CodeCompanion adapters point at a local proxy on http://127.0.0.1:8800
and read their key from the FHGENIE_PROXY_KEY environment variable. Without
that proxy running the AI plugin simply fails to connect, the rest of the
editor is unaffected.
Config assumes JetBrainsMono Nerd Font at size 24 and the GruvBox Dark theme.
Adjust font-size per display.
Prefix is C-a. tmux-continuum auto-saves and restores sessions.
start-at-login is false in the committed config. Turn it on per machine.
The agents package installs sanitized, reusable skills in ~/.agents/skills,
the user-level location supported by Codex. install.sh links the same skill
folders into ~/.claude/skills, so Codex and Claude use one canonical copy.
If an older copy with the same name exists under ~/.codex/skills or
~/.claude/skills, the installer moves it into the timestamped dotfiles
backup before installing the canonical copy.
Included public skills:
career-explorer: profile-driven career research and conversionlink-dump-to-obsidian: capture selected browser tabs into a vault note
Personal profiles and runtime state are intentionally excluded. Create
~/.config/career-explorer/config.json from the bundled template and keep the
referenced profile workspace in a private repository or outside version
control. Set OBSIDIAN_VAULT in ~/.zshrc.local rather than hard-coding a
vault path in the skill. API keys also belong only in machine-local secret
storage.
On Linux, after stow agents, link any skills wanted by Claude:
mkdir -p "$HOME/.claude/skills"
ln -s "$HOME/.agents/skills/career-explorer" "$HOME/.claude/skills/career-explorer"
ln -s "$HOME/.agents/skills/link-dump-to-obsidian" "$HOME/.claude/skills/link-dump-to-obsidian"- API keys and tokens. Those live in
~/.zshrc.local(gitignored). ~/.gitconfig. It carries a personal email and a GPG signing key id, so it is machine-local. Set yours withgit config --global user.name/user.email.~/.ssh/configand any SSH keys.~/.zprofile,~/.zshenv,~/.netrc.- The password-store contents. Use
pass gitagainst a private remote instead. - Machine state: nvm/conda/bun installs, Mason binaries, tmux plugin checkouts.
- Career profiles, CVs, resumes, databases, trackers, application artifacts, Obsidian vault paths and other private AI-assistant context.