direnv Integration
envref integrates with direnv to automatically resolve your environment variables when you cd into a project directory. This is the recommended way to use envref for local development.
Overview
direnv is a shell extension that loads/unloads environment variables based on the current directory. envref acts as a resolution layer — direnv calls envref resolve --direnv and evals the output to inject resolved variables into your shell.
cd my-project/
-> direnv triggers
-> .envrc runs: eval "$(envref resolve --direnv)"
-> envref merges .env files, resolves ref:// from keychain
-> shell receives resolved KEY=VALUE exports
Setup
Prerequisites
Install direnv if you haven't already:
# macOS
brew install direnv
# Ubuntu/Debian
sudo apt install direnv
# From source
go install github.com/direnv/direnv@latest
Add the direnv hook to your shell (add to ~/.bashrc, ~/.zshrc, etc.):
# Bash
eval "$(direnv hook bash)"
# Zsh
eval "$(direnv hook zsh)"
# Fish
direnv hook fish | source
Initialize with direnv support
envref init --direnv
This creates the standard envref files (.envref.yaml, .env, .env.local) plus an .envrc file:
# .envrc (generated by envref init --direnv)
eval "$(envref resolve --direnv 2>/dev/null)" || true
If direnv is installed, envref init --direnv also runs direnv allow automatically. If direnv is not installed, it prints installation guidance.
Trust the .envrc
If the .envrc wasn't automatically trusted:
direnv allow
This tells direnv to trust and execute the .envrc in this directory.
How it works
The resolve --direnv flag
envref resolve --direnv outputs environment variables in export KEY=VALUE format, compatible with shell eval:
$ envref resolve --direnv
export APP_NAME=my-app
export APP_PORT=3000
export DATABASE_URL=postgres://user:secret@localhost/mydb
export API_KEY=sk-abc123
The 2>/dev/null || true in the .envrc ensures that if envref encounters an error (missing backend, locked vault), the shell still loads without failing.
Performance
envref is optimized for <50ms startup with 100 variables. This matters because direnv calls envref resolve on every cd into the project directory, and slow resolve times would make navigation feel sluggish.
Using profiles with direnv
Set a default profile
envref profile use staging
The active profile in .envref.yaml is used automatically by envref resolve --direnv, so direnv will load the staging profile every time.
Override the profile
To temporarily use a different profile, modify your .envrc:
# .envrc
eval "$(envref resolve --direnv --profile production 2>/dev/null)" || true
Or set a profile per-directory by editing .envref.yaml:
active_profile: staging
Strict mode
For CI environments or when you want to ensure all references resolve successfully, use --strict:
# .envrc for strict environments
eval "$(envref resolve --direnv --strict)"
With --strict, envref resolve exits with a non-zero code and produces no output if any ref:// reference cannot be resolved. This prevents partial environments from being loaded.
Watch mode
During development, you can use envref resolve --watch to automatically re-resolve when .env files change:
envref resolve --watch --direnv
This performs an initial resolve, then watches all .env files (.env, .env.<profile>, .env.local) via filesystem notifications. Changes are debounced (100ms) to handle rapid edits. Press Ctrl+C to stop.
Note: Watch mode is a development convenience for seeing changes in real-time. For normal direnv usage, the standard .envrc setup (without --watch) is sufficient since direnv reloads on file changes automatically.
Troubleshooting
direnv: error .envrc is blocked
Run direnv allow to trust the .envrc file. This is required after any change to .envrc.
Environment not loading
Check that envref can resolve successfully:
envref resolve --direnv
If this produces output, the issue is with direnv. If it errors, fix the envref configuration first.
Secrets not resolving
Verify your secrets are stored:
envref secret list
envref status
The status command shows which references are resolved and which are missing, with actionable hints.
Slow shell startup
If cd into the project feels slow:
- Check resolve time:
time envref resolve --direnv - Target is <50ms for 100 variables
- Ensure you're using the compiled binary, not
go run - Check if backend access (keychain prompts) is adding latency
envref: command not found
Ensure envref is on your $PATH. If installed via go install, confirm $GOPATH/bin is in your path. If using a binary, move it to /usr/local/bin or another directory on your path.
Example: full setup
# Install envref
go install github.com/xcke/envref/cmd/envref@latest
# Initialize project with direnv
cd my-project
envref init --project my-app --direnv
# Add secret references to .env
cat .env
# APP_NAME=my-app
# APP_PORT=3000
# DATABASE_URL=ref://secrets/database_url
# API_KEY=ref://secrets/api_key
# Store the secrets
envref secret set database_url --value "postgres://user:pass@localhost/mydb"
envref secret set api_key --value "sk-abc123"
# Verify resolution
envref resolve
# Leave and re-enter the directory to trigger direnv
cd .. && cd my-project
# direnv: loading .envrc
# direnv: export +APP_NAME +APP_PORT +DATABASE_URL +API_KEY
# Confirm
echo $API_KEY
# sk-abc123
See also
- Getting Started — basic envref setup
- Profiles — manage per-environment configurations
- Secret Backends — configure where secrets are stored