The list that decides every command
$PATH is a colon-separated list of directories. The shell walks it left-to-right looking for executables. Everything you install adds to it; managing the order is what keeps multiple Pythons / Nodes / brews from fighting.
Append vs prepend
export PATH="$PATH:/new/dir"— append. New tool used only if a system one with the same name doesn't exist.export PATH="/new/dir:$PATH"— prepend. New tool wins. What you want for Homebrew, pyenv, mise, etc.
The Apple Silicon Homebrew dance
On Apple Silicon, Homebrew lives at /opt/homebrew/bin. Add this to ~/.zprofile:
eval "$(/opt/homebrew/bin/brew shellenv)"That one line sets PATH, MANPATH, INFOPATH, and a few brew vars in one atomic step. The official install script writes it for you on a fresh Mac.
Deduplicate
Sourcing the same file twice can repeat entries. zsh has a typeset -U path declaration that auto-deduplicates. After typeset -U path, every PATH addition is unique by string.
Inspect
echo $PATH | tr ':' '\n'
echo $PATH | tr ':' '\n' | sort | uniq -d # any duplicates?
type python3 # which one wins?Per-project PATH overrides
direnv (next-but-one lesson) lets a project-local .envrc insert its own bin dir at the front of PATH for that directory only. Combined with mise (modern-tools), each project can ship its toolchain without polluting the global env.