Personal macOS/Linux shell and terminal setup with a single bootstrap command.
Fresh machine:
bash -c "$(curl -fsSL https://raw.githubusercontent.com/Akagitsunee/dotfiles/master/bootstrap.sh)"That script will:
- clone this repo to
~/dev/dotfilesif it is not there yet - update it if it already exists
- run
install.sh
If you already have the repo locally:
cd ~/dev/dotfiles
./install.shBoth scripts accept component names (core zsh nvim tmux terminal firefox); without arguments everything is handled. core always runs first.
./install.sh --list
./install.sh nvim tmux
./uninstall.sh tmuxLinks live in one table, LINKS in lib/common.sh, shared by both scripts.
zsh/environment.zsh holds per-machine settings (work, private, ...). It is git-ignored; install.sh creates an empty stub if missing and links it to ~/.config/zsh/environment.zsh, and .zshrc sources it when present. uninstall.sh removes the link but keeps the file.
The installer is idempotent. Running it again updates plugin repos and refreshes links.
It will:
- back up existing files before replacing them
- install or update
oh-my-zshin~/.oh-my-zsh - install or update
nvm(cloned from GitHub, not Homebrew — see Node below) - install or update the required Oh My Zsh custom plugins
- install required CLI tools when missing and a supported package manager is available
- on macOS with Homebrew, install
ghostty,starship,borders, and the JetBrainsMono Nerd Font if missing - install or update tmux plugins in
~/.config/tmux/plugins - sync the ShyFox theme into the Firefox profile and link
user.js(see Browser) - create the git-ignored
zsh/environment.zshstub if it is missing (see Machine-specific config) - symlink the configs from this repo into
~and~/.config - only handle the components you name, if you name any (see Installing only parts)
- Homebrew itself —
install.shuses it to install other tools but does not install it. On a fresh Mac, install it first from brew.sh. - uv — the
python/pipaliases route through it, so they fail without it; install it from docs.astral.sh/uv. - AeroSpace — window manager the
aerospace/config targets; install manually (brew install --cask nikitabobko/tap/aerospace). - Fonts for
wezterm/— if you go back to using wezterm, its fallback list expects several Nerd Fonts beyond the JetBrainsMono oneinstall.shinstalls for ghostty (FiraCode, CaskaydiaCove, SauceCodePro, CommitMono, RobotoMono); install what you need manually.
Backups are stored in:
~/.dotfiles-backups/<timestamp>/This repo only keeps personal config and custom files. Third-party dependencies are installed by the bootstrap scripts.
zsh/.zprofile->~/.zprofilezsh/.zshenv->~/.zshenvzsh/.zshrc->~/.config/zsh/.zshrc- zsh modules in
zsh/->~/.config/zsh/ oh-my-zsh->~/.oh-my-zsh- Oh My Zsh custom plugins ->
~/.oh-my-zsh/custom/plugins/ - CLI tools used by the shell config:
zoxide,eza,bat,fd,fzf,rg .zshrcpinsSSH_AUTH_SOCKto the static socket~/.ssh/ssh-agent.sock, starts an agent there if none answers, and loads keys from the macOS keychain;tmux.confpoints tmux at the same socket so every pane shares one agentMANPAGERpipes throughcol -bxbeforebatso man pages render without backspace overstrike;~/.local/binis prepended last in.zshenv, so it wins over the other PATH entries- Debian/Ubuntu package names are normalized when needed by linking
batcat->batandfdfind->fdin~/.local/bin
zsh/aliases.zsh deliberately overrides several commands:
ls/tree->eza,grep->rg,vim->nvimnpm->pnpm,npx->pnpm dlxpython/python3->uv run python,pip/pip3->uv pipstim->caffeinate -dimsu(macOS: keep display, system and disks awake and simulate user activity)
Node itself is intentionally not installed by this repo. install.sh clones nvm from GitHub into ~/.local/share/nvm (not the Homebrew formula, which nvm's own docs advise against) and .zshenv/.zshrc load it from there. Install whatever Node versions you need with nvm install <version> after running the installer.
npm ships with whichever Node version nvm installs, so there's nothing separate to set up. For pnpm, prefer corepack enable (built into Node) over a global Homebrew/npm install — it keeps the pnpm version scoped per project instead of one global version drifting out of sync.
ghostty/->~/.config/ghostty/— the terminal actually in use;install.shinstalls it via Homebrew cask on macOS if missingstarship/starship.toml->~/.config/starship.toml— auto-installed via Homebrew on macOS if missingwezterm/->~/.config/wezterm/wezterm/wezterm.lua->~/.wezterm.lua- kept for reference but no longer the daily driver; config is symlinked but not auto-installed
nvim/->~/.config/nvim/nvimitself is auto-installed (asneovim) byinstall.shif missing- everything Mason installs is a prebuilt binary or an npm package (Node comes from nvm), so no extra system prerequisite is installed for it
- Go tooling is gated on
go:gopls,goimports,gofumpt,golangci-lintanddelveare only installed by Mason whengois on$PATH, so nvim works on a fresh machine without the Go SDK (seenvim/README.md) - not yet automated: the build toolchain some plugins need (
make, a C compiler, andgoif you want Go support;blink.cmp/blink.pairsship prebuilt binaries, socargois no longer needed) — seenvim/README.md
tmux/tmux.conf->~/.config/tmux/tmux.conftmux/onedark-theme.conf->~/.config/tmux/onedark-theme.conftmux/nord-theme.conf->~/.config/tmux/nord-theme.conftmuxitself is auto-installed byinstall.shif missing (ghostty launches straight into it, so this matters)- tmux plugins ->
~/.config/tmux/plugins/ tmux/tmux-cheatsheet.mdlists the key bindings (prefixCtrl+Space,Ctrl+h/j/k/lnavigation shared with nvim)tmux.confenablesfocus-eventsandextended-keysand advertises Ghostty's features (true colour, hyperlinks), so nvim's focus autocmds and modified keys work inside tmux;ghostty/configsetsmacos-option-as-alt = truetmux-powerline/->~/.config/tmux-powerline/
firefox/chrome/is synced (copied), not symlinked, into<Firefox profile>/chrome/— the ShyFox userChrome theme (auto-hiding toolbars/urlbar, plus a Sidebery skin). Firefox refuses to applyuserContent.css's@-moz-documentrule targeting Sidebery'smoz-extension://sidebar page when the source resolves outside the profile directory via a symlink (confirmed by reproducing it twice); a real copy inside the profile works fine. This means editing the theme requires re-runninginstall.shto push changes into the live profile — it won't reflect instantly like a symlink would.firefox/user.js-><Firefox profile>/user.js— still a normal symlink, since it's just a prefs file and unaffected by the above restriction. Setstoolkit.legacyUserProfileCustomizations.stylesheets(required for the theme to load at all) andsidebar.revamp=false(reverts Firefox 154+'s new native sidebar default, which otherwise breaks Sidebery's and ShyFox's sidebar layout).- the profile path is resolved at install/uninstall time by globbing
*.default-releaseunder the platform's Firefox profiles directory (macOS:~/Library/Application Support/Firefox/Profiles, Linux:~/.mozilla/firefox), since the profile folder name includes a random per-install prefix; if none or more than one match is found, linking/syncing is skipped with a logged message rather than guessing - requires the Userchrome Toggle Extended and Sidebery Firefox addons, installed manually via Firefox's Add-ons Manager — neither the addons nor Userchrome Toggle Extended's Style 1/2/3 toggle state are portable, so re-enable/re-toggle them by hand after a fresh install
aerospace/aerospace.toml->~/.config/aerospace/aerospace.toml— requires AeroSpace itself, installed manually (see prerequisites above)borders(JankyBorders) draws the active-window border AeroSpace triggers on startup;install.shinstalls it via Homebrew (FelixKratz/formulaetap) on macOS if missing
- Existing files are moved out of the way before links are created.
- The bootstrap command needs
gitand network access. DOTFILES_BACKUP_DIRoverrides where backups go;bootstrap.shsetsDOTFILES_SKIP_PULL=1so the repo isn't pulled a second time byinstall.sh.- Shared helpers (paths, logging, the link table, Firefox profile lookup) live in
lib/common.sh. DOTFILES_DIR,DOTFILES_REPO_URL, andDOTFILES_BRANCHcan be set before runningbootstrap.sh.
cd ~/dev/dotfiles
./uninstall.shPass component names to remove only those links (./uninstall.sh tmux). This removes symlinks created by the repo. It does not remove ~/.oh-my-zsh, installed CLI tools, downloaded tmux plugins, your zsh/environment.zsh, or the copied Firefox chrome/ directory.