Aller au contenu

direnv Cheat Sheet

Overview

direnv is an environment switcher for the shell that loads and unloads environment variables depending on the current directory. When you cd into a directory containing an .envrc file, direnv automatically loads the defined environment variables. When you leave the directory, it unloads them, restoring the previous environment state.

direnv supports bash, zsh, fish, tcsh, and elvish shells. It provides a security model where new or modified .envrc files must be explicitly approved before they are loaded. direnv integrates with Nix for reproducible development environments and supports loading .env files, PATH modifications, Python virtualenvs, and custom functions through its stdlib.

Installation

# macOS
brew install direnv

# Ubuntu/Debian
sudo apt install direnv

# Arch Linux
sudo pacman -S direnv

# Fedora
sudo dnf install direnv

# From source (Go)
go install github.com/direnv/direnv@latest

# Nix
nix-env -i direnv

# Verify
direnv version

Shell Hook Setup

# Bash - add to ~/.bashrc
eval "$(direnv hook bash)"

# Zsh - add to ~/.zshrc
eval "$(direnv hook zsh)"

# Fish - add to ~/.config/fish/config.fish
direnv hook fish | source

# Tcsh - add to ~/.cshrc
eval `direnv hook tcsh`

Core Commands

CommandDescription
direnv allowApprove the current .envrc file
direnv denyDeny the current .envrc
direnv reloadReload the current environment
direnv statusShow direnv status and loaded files
direnv editOpen .envrc in editor and allow on save
direnv pruneRemove old allowed entries
direnv fetchurl <url>Fetch and cache a URL
direnv stdlibPrint the stdlib available in .envrc

Basic Usage

# Create an .envrc file
echo 'export API_KEY="sk-abc123"' > .envrc

# Allow the file (required for security)
direnv allow

# Environment is now loaded
echo $API_KEY  # sk-abc123

# Leave the directory - environment is unloaded
cd ..
echo $API_KEY  # (empty)

# Edit .envrc (opens in $EDITOR, auto-allows on save)
direnv edit .

.envrc Examples

Basic Environment Variables

# .envrc
export DATABASE_URL="postgres://user:pass@localhost:5432/mydb"
export REDIS_URL="redis://localhost:6379"
export API_KEY="sk-abc123"
export NODE_ENV="development"
export DEBUG="app:*"

Loading .env Files

# .envrc
dotenv

# Or load a specific .env file
dotenv .env.development

# Or load from a specific path
dotenv_if_exists .env.local

PATH Modifications

# .envrc
# Add project bin to PATH
PATH_add bin
PATH_add node_modules/.bin
PATH_add .venv/bin

# Add absolute path
path_add PATH /opt/custom/bin

# Prepend to other variables
path_add LD_LIBRARY_PATH /opt/custom/lib

Python Virtual Environments

# .envrc - Auto-create and activate virtualenv
layout python3

# Specific Python version
layout python python3.12

# Use existing virtualenv
source .venv/bin/activate

# Or with pyenv
layout pyenv 3.12.3

# Poetry integration
layout poetry

Node.js

# .envrc
# Use project Node modules
layout node

# Use specific Node version with nvm
use nvm 20

# Use volta
use volta

Ruby

# .envrc
layout ruby

Stdlib Functions

# .envrc

# Check if a command exists
has docker && export USE_DOCKER=true

# Watch a file for changes (reload when it changes)
watch_file Gemfile.lock
watch_file package-lock.json
watch_file requirements.txt

# Source another file
source_env .envrc.local
source_env_if_exists .envrc.secrets

# Load env from URL
source_url "https://example.com/envrc" "sha256-HASH"

# Expand variables
expand_path ~/projects/lib

# Log messages
log_status "Loading development environment"
log_error "Missing required configuration"

# Strict mode
strict_env   # Error on undefined variables
direnv_load  # Load from a command's output

Security Model

# When .envrc is new or modified:
# direnv: error .envrc is blocked. Run `direnv allow` to approve its content.

# Allow current directory
direnv allow

# Allow specific path
direnv allow /path/to/.envrc

# Deny/block an .envrc
direnv deny

# Check what's allowed
direnv status

# Prune stale allowed entries
direnv prune

Advanced Usage

Nix Integration

# .envrc - Use Nix for reproducible dev environment
use nix

# Or with flakes
use flake

# Custom Nix shell
use nix -p nodejs python3 postgresql

Shared Team Configuration

# .envrc (committed to git)
dotenv_if_exists .env                    # Shared defaults
dotenv_if_exists .env.local              # Personal overrides (gitignored)
source_env_if_exists .envrc.local        # Personal extensions (gitignored)

# .gitignore
.env.local
.envrc.local

Docker Compose Integration

# .envrc
export COMPOSE_PROJECT_NAME="myproject"
export COMPOSE_FILE="docker-compose.yml:docker-compose.dev.yml"
export DOCKER_BUILDKIT=1

dotenv

AWS Profile Switching

# .envrc
export AWS_PROFILE="production"
export AWS_REGION="us-east-1"
export AWS_DEFAULT_REGION="us-east-1"

# Or load from AWS SSO
aws sso login --profile production 2>/dev/null || true

Terraform Workspace

# .envrc
export TF_WORKSPACE="production"
export TF_VAR_region="us-east-1"
export TF_VAR_environment="prod"

dotenv_if_exists .env.terraform

Conditional Loading

# .envrc
if [ "$(uname)" = "Darwin" ]; then
  export OPENSSL_DIR=$(brew --prefix openssl@3)
fi

if has docker; then
  export TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE=/var/run/docker.sock
fi

Configuration

# direnv.toml (global config)
# Location: ~/.config/direnv/direnv.toml

# Allow all .envrc in trusted directories
[whitelist]
prefix = [ "/home/user/work" ]
exact = [ "/home/user/project/.envrc" ]

# Custom .envrc filename
[global]
load_dotenv = true    # Auto-load .env files
strict_env = false    # Don't error on undefined vars
warn_timeout = "5s"   # Warn if loading takes too long
# ~/.config/direnv/lib/*.sh
# Custom stdlib extensions available in all .envrc files
# Example: ~/.config/direnv/lib/use_nvm.sh
use_nvm() {
  local node_version=$1
  nvm_sh=~/.nvm/nvm.sh
  if [[ -s $nvm_sh ]]; then
    source $nvm_sh
    nvm use $node_version
  fi
}

Troubleshooting

IssueSolution
.envrc is blockedRun direnv allow to approve the file
Variables not loadingCheck shell hook is added; restart terminal
Slow loadingMinimize .envrc complexity; use watch_file sparingly
Variables persist after cdEnsure shell hook is properly installed
.env not loadingAdd dotenv to .envrc; run direnv allow
Editor not openingSet $EDITOR environment variable
Nix integration failsInstall Nix first; ensure use nix syntax is correct
Virtualenv not activatingUse layout python3 instead of manual activation