Skip to content

direnv

direnv loads and unloads environment variables automatically when you enter and leave directories. Each project gets its own isolated environment.

Create .envrc in your project root:

Terminal window
# Set env vars
export DATABASE_URL="postgresql://localhost/mydb"
export API_KEY="development-key"
# Load .env if it exists
dotenv_if_exists .env
# Add project bin to PATH
PATH_add ./bin
# Use language versions from mise
use mise

You need to approve it the first time (and after any change):

Terminal window
direnv allow

Combine with mise for automatic language runtime switching:

.envrc
use mise

Specify versions in .mise.toml:

[tools]
node = "20.10.0"
python = "3.12"
go = "1.21"

Just cd into the directory and the right versions activate.

.envrc
export DATABASE_URL="postgresql://localhost/dev_db"
export REDIS_URL="redis://localhost:6379"
.envrc
export AWS_PROFILE="development"
export AWS_REGION="us-west-2"
.envrc
PATH_add ./scripts
PATH_add ./node_modules/.bin
Terminal window
# .envrc (committed)
dotenv_if_exists .env.local
# .env.local (never committed)
OPENAI_API_KEY="sk-..."
STRIPE_SECRET_KEY="sk_test_..."
  • Always gitignore .envrc.local for machine-specific secrets
  • Never put real secrets in .envrc — use placeholders
  • direnv allow is an explicit trust mechanism
  • Review .envrc changes carefully in PRs

Give each worktree its own isolated environment:

Terminal window
# Create a feature worktree
wtp add feature/new-api
cd ../project-feature-new-api
# Set up environment for this worktree
cat > .envrc << EOF
export FEATURE_FLAG_NEW_API=true
export API_VERSION=v2
use mise
EOF
direnv allow
# Main worktree stays unaffected