Project A wants one API endpoint. Project B wants another. direnv loads the right variables when you cd in, and takes them back when you cd out.
direnv hooks the shell. On directory change it looks for .envrc (or .env) and, if you have allowed that file, exports what it sets. Leave the directory and those exports disappear. Nothing is loaded until you allow it — that is the point, not a bug. Checked on direnv 2.38.1: direnv allow loaded an .envrc, and direnv export zsh printed the export diff.
install
# macOS
brew install direnv
# in the default repos
sudo apt install direnv
# in the default repos
sudo dnf install direnv
# Arch extra
sudo pacman -S direnv
examples
# Allow the .envrc in this directory. Refuses unknown files until you do this
direnv allow
# Print the hook. Add the eval line to ~/.zshrc once — do not paste this into a file by itself and expect the shell to change
direnv hook zsh
# Show what this directory would export, without entering it
direnv export zsh
pro tip
After you edit .envrc, direnv blocks it again until you direnv allow. That second allow is the review. direnv edit opens the file in $EDITOR and allows it when you save, which is the shorter loop.
honest limits
The hook is not optional. Without eval "$(direnv hook zsh)" in the shell rc, cd will not load anything and you will think the tool is dead. It will not read a file you have not allowed, including one a teammate just changed. Do not allow an .envrc you have not read — it is shell. This is not a secrets manager.