zsh
Three files, each with a different job. See Shell overview for when each one runs.
.zshenv — every zsh
Section titled “.zshenv — every zsh”Runs for every zsh, including scripts and cron jobs, so it only holds things those need — and nothing that prints output or is slow.
| What | Details |
|---|---|
| OS detection | sets IS_MACOS or IS_LINUX (see overview) |
| Locale | LANG / LC_ALL from ~/.config/locale.conf, falling back to C.UTF-8 — see Locale |
DOTNET_CLI_TELEMETRY_OPTOUT=true |
turns off .NET telemetry |
~/.zsh_secrets |
loaded if it exists — API keys etc. See Local files |
~/.zshenv.local |
loaded if it exists — machine-specific PATH |
| Homebrew | sets PATH for brew packages (Linux, Apple Silicon or Intel locations) |
| nvm | sets NVM_DIR and puts your default Node version on PATH |
Homebrew, cached
Section titled “Homebrew, cached”brew shellenv prints the PATH settings Homebrew needs. Running it takes 20–40 ms, on every
shell start. .zshenv saves its output to ~/.cache/brew_shellenv and only re-runs it when the
brew program is newer than the saved copy (i.e. after a Homebrew update).
If brew’s paths ever look wrong, delete the cache and open a new shell:
rm ~/.cache/brew_shellenvNode without loading nvm
Section titled “Node without loading nvm”Loading nvm (nvm.sh) takes 150–300 ms. .zshenv instead reads nvm’s default alias (following
chains like default → lts/iron → 20.18.0) and puts that version’s bin folder on PATH.
Scripts and cron get a working node instantly; nvm itself only loads when you use it (see
.zshrc below).
.zprofile — login shells
Section titled “.zprofile — login shells”Currently empty. It’s the place for once-per-login things like starting ssh-agent or
auto-attaching to tmux.
.zshrc — interactive shells
Section titled “.zshrc — interactive shells”Options
Section titled “Options”| Option | What it does |
|---|---|
AUTO_CD |
type a folder name (or ..) to cd into it |
AUTO_PUSHD |
every cd remembers the previous folder — popd goes back |
PUSHD_IGNORE_DUPS |
don’t remember the same folder twice |
EXTENDED_HISTORY |
save when each command ran and how long it took |
SHARE_HISTORY |
all open shells share one history |
HIST_IGNORE_ALL_DUPS |
drop older duplicates when a command repeats |
HIST_IGNORE_SPACE |
a command starting with a space isn’t saved (useful for secrets) |
HIST_REDUCE_BLANKS |
tidy extra spaces before saving |
History: ~/.zsh_history, 50,000 commands. (zsh saves nothing by default — SAVEHIST is 0.)
Completion
Section titled “Completion”Tab completion (compinit) checks its cache file ~/.zcompdump fully once a day and skips the
check otherwise — saving 50–100 ms per shell start.
Matching is forgiving, tried in this order:
- what you typed, completed as usual
- anywhere in the name:
conf<Tab>findskitty.conf - any case:
doc<Tab>findsDocuments
source <Tab> only offers files in the current folder. zsh’s default would also list every
command on PATH, which is never what you want to source.
If completion acts strangely after installing new tools, rebuild the cache:
rm ~/.zcompdump && exec zshnvm stubs
Section titled “nvm stubs”nvm, node, npm and npx are defined as tiny functions. The first time you run any of them,
they remove themselves, load nvm, and run your command. After that the real commands are used.
Also in .zshrc
Section titled “Also in .zshrc”lesspipe,dircolorsand coloured completion- Loads
.aliases,.functions, their.localversions, and~/.zshrc.local— see Local files DISABLE_AUTO_TITLE=trueso tmuxp can name its windows- The Starship prompt, if starship is installed