Claude Code for Direnv — Workflow Guide
The Setup
You are using Direnv to automatically load and unload environment variables when entering and leaving project directories. Direnv eliminates the need to manually source .env files and ensures each project has its own isolated environment. Claude Code can configure Direnv, but it modifies .bashrc or .zshrc for environment variables instead of using .envrc files.
What Claude Code Gets Wrong By Default
-
Adds environment variables to shell config. Claude writes
export DATABASE_URL=...in.zshrc. Direnv uses per-project.envrcfiles that activate automatically when youcdinto the directory. -
Sources
.envfiles manually. Claude addssource .envto shell config or startup scripts. Direnv loads variables automatically withdotenvin.envrc— no manual sourcing needed. -
Uses
.envfor secrets without gitignore. Claude puts secrets in.envand commits it. Direnv uses.envrc(which can be committed with non-secret config) and.env.local(gitignored for secrets), loaded together. -
Ignores Direnv’s stdlib functions. Claude writes raw shell commands in
.envrc. Direnv provides stdlib functions:layout node,use nix,dotenv,PATH_addthat handle common setups elegantly.
The CLAUDE.md Configuration
# Direnv Environment Management
## Environment
- Tool: Direnv (auto-load env vars per directory)
- Config: .envrc at project root
- Secrets: .env.local (gitignored), loaded via dotenv_if_exists
## Direnv Rules
- .envrc is the config file (committed to git)
- Run direnv allow after creating/modifying .envrc
- Use dotenv for loading .env files
- Use dotenv_if_exists for optional .env.local
- Use layout node for Node.js PATH setup
- Use PATH_add for adding to PATH
- Never put secrets in .envrc — use .env.local
- eval "$(direnv hook zsh)" required in .zshrc
## Conventions
- .envrc: non-secret environment setup (committed)
- .env.local: secrets and personal config (gitignored)
- .envrc loads .env.local with dotenv_if_exists .env.local
- Use layout commands for language-specific setup
- direnv allow must be run after .envrc changes (security feature)
- Use source_env_if_exists for parent directory env
Workflow Example
You want to set up Direnv for a project with multiple environments. Prompt Claude Code:
“Configure Direnv for this project with a DATABASE_URL, API_KEY, and custom PATH for local bin scripts. Non-secret vars should be in .envrc (committed), secrets in .env.local (gitignored). Include Node.js layout setup.”
Claude Code should create .envrc with layout node, PATH_add bin, non-secret variable exports, and dotenv_if_exists .env.local at the end. Create .env.local.example with placeholder values for secrets, and add .env.local to .gitignore.
Common Pitfalls
-
Forgetting
direnv allow. Claude creates.envrcbut forgets that Direnv blocks untrusted files by default. After creating or modifying.envrc, rundirenv allowto trust the file. This is a security feature to prevent malicious.envrcfiles. -
Shell hook not configured. Claude installs Direnv but does not add the shell hook. Without
eval "$(direnv hook zsh)"in.zshrc, Direnv does not activate when changing directories. -
Overriding system PATH. Claude writes
export PATH=/project/binin.envrc, replacing the entire PATH. UsePATH_add bininstead, which prepends to PATH without removing existing entries.