direnv

This skill provides comprehensive guidance for working with direnv, covering installation, configuration, stdlib functions, and best practices for per-project environment management.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "direnv" with this command: npx skills add julianobarbosa/claude-code-skills/julianobarbosa-claude-code-skills-direnv

direnv Skill

This skill provides comprehensive guidance for working with direnv, covering installation, configuration, stdlib functions, and best practices for per-project environment management.

When to Use This Skill

Use this skill when:

  • Installing and configuring direnv on macOS or Linux

  • Creating or modifying .envrc files for projects

  • Setting up per-project environment variables

  • Configuring language-specific layouts (Python, Node.js, Ruby, Go, Perl)

  • Integrating direnv with Nix or Nix Flakes

  • Managing secrets and environment configuration for teams

  • Troubleshooting environment loading issues

  • Creating custom direnv extensions

Core Concepts

What is direnv?

direnv is a shell extension that loads and unloads environment variables based on the current directory. When you cd into a directory with a .envrc file, direnv automatically loads the environment. When you leave, it unloads the changes.

Security Model

direnv uses an allowlist-based security approach:

  • New or modified .envrc files must be explicitly allowed with direnv allow

  • Prevents automatic execution of untrusted scripts

  • Use direnv deny to revoke access

How It Works

  • Shell hook intercepts directory changes

  • Checks for .envrc file in current or parent directories

  • If allowed, executes .envrc in a bash subshell

  • Captures exported variables and applies them to current shell

Installation

macOS (Homebrew - Recommended)

brew install direnv

Linux

Ubuntu/Debian

sudo apt install direnv

Fedora

sudo dnf install direnv

Arch

sudo pacman -S direnv

Binary installer (any system)

curl -sfL https://direnv.net/install.sh | bash

Verify Installation

direnv version

Shell Configuration

Add the hook to your shell's config file. This is required for direnv to function.

Zsh (~/.zshrc)

eval "$(direnv hook zsh)"

With Oh My Zsh:

plugins=(... direnv)

Bash (~/.bashrc)

eval "$(direnv hook bash)"

Important: Place after rvm, git-prompt, and other prompt-modifying extensions.

Fish (~/.config/fish/config.fish)

direnv hook fish | source

After Configuration

Restart your shell:

exec $SHELL

.envrc File Basics

Creating an .envrc

In your project directory

touch .envrc

Edit with your preferred editor

vim .envrc

Basic Syntax

Export environment variables

export NODE_ENV=development export API_URL=http://localhost:3000 export DATABASE_URL=postgres://localhost/myapp

The export keyword is required for direnv to capture variables

Allowing the .envrc

Allow current directory

direnv allow

Allow specific path

direnv allow /path/to/project

Deny/revoke access

direnv deny

Standard Library Functions

direnv includes a powerful stdlib. Always prefer stdlib functions over manual exports.

PATH Management

Prepend to PATH (safer than manual export)

PATH_add bin PATH_add node_modules/.bin PATH_add scripts

Add to arbitrary path-like variable

path_add PYTHONPATH lib path_add LD_LIBRARY_PATH /opt/lib

Remove from PATH

PATH_rm "*/.git/bin"

Environment File Loading

Load .env file (current directory)

dotenv

Load specific file

dotenv .env.local

Load only if exists (no error)

dotenv_if_exists .env.local dotenv_if_exists .env.${USER}

Source another .envrc

source_env ../.envrc source_env /path/to/.envrc

Search upward and source parent .envrc

source_up

Source if exists

source_env_if_exists .envrc.local

Language Layouts

Node.js:

Adds node_modules/.bin to PATH

layout node

Python:

Creates virtualenv in .direnv/python-X.X/

layout python

Use specific Python version

layout python python3.11

Shortcut for Python 3

layout python3

Use Pipenv (reads from Pipfile)

layout pipenv

Ruby:

Sets GEM_HOME to project directory

layout ruby

Go:

Modifies GOPATH and adds bin to PATH

layout go

Perl:

Configures local::lib environment

layout perl

Nix Integration

Load nix-shell environment

use nix

With specific file

use nix shell.nix

Load from Nix flake

use flake

Load specific flake

use flake "nixpkgs#hello" use flake ".#devShell"

For better Nix Flakes support, install nix-direnv:

Provides faster, cached use_flake implementation

https://github.com/nix-community/nix-direnv

Version Managers

rbenv

use rbenv

Node.js (with fuzzy version matching)

use node 18 use node 18.17.0

Reads from .nvmrc if version not specified

use node

Julia

use julia 1.9

Validation

Require environment variables (errors if missing)

env_vars_required API_KEY DATABASE_URL SECRET_KEY

Enforce minimum direnv version

direnv_version 2.32.0

Check git branch

if on_git_branch main; then export DEPLOY_ENV=production fi if on_git_branch develop; then export DEPLOY_ENV=staging fi

File Watching

Reload when files change

watch_file package.json watch_file requirements.txt watch_file .tool-versions watch_file config/*.yaml

Watch entire directory

watch_dir config watch_dir migrations

Utility Functions

Check if command exists

if has docker; then export DOCKER_HOST=unix:///var/run/docker.sock fi

Expand relative path to absolute

expand_path ./bin

Find file searching upward

find_up package.json

Enable strict mode (exit on errors)

strict_env

Load prefix (configures CPATH, LD_LIBRARY_PATH, etc.)

load_prefix /usr/local/custom

Load remote script with integrity verification

source_url https://example.com/script.sh "sha256-HASH..."

Best Practices

Recommended .envrc Template

#!/usr/bin/env bash

.envrc - Project environment configuration

Enforce direnv version for team consistency

direnv_version 2.32.0

Load .env if exists

dotenv_if_exists

Load local overrides (not committed to git)

source_env_if_exists .envrc.local

Language-specific layout

layout node # or: layout python3

Add project bin directories

PATH_add bin PATH_add scripts

Development defaults

export NODE_ENV="${NODE_ENV:-development}" export LOG_LEVEL="${LOG_LEVEL:-debug}"

Watch for dependency changes

watch_file package.json watch_file .nvmrc

Git Configuration

.gitignore:

Environment files with secrets

.env .env.local .envrc.local

direnv virtualenv/cache

.direnv/

Commit to repository:

  • .envrc (base configuration, no secrets)

  • .env.example (template for team members)

Secrets Management

Never commit secrets. Use environment variable fallbacks:

.envrc (committed)

export DATABASE_URL="${DATABASE_URL:-postgres://localhost/dev}" export API_KEY="${API_KEY:-}"

Validate required secrets

env_vars_required API_KEY

.envrc.local (gitignored)

export DATABASE_URL="postgres://user:secret@prod/app" export API_KEY="actual-secret-key"

Layered Configuration

~/projects/.envrc (global dev settings)

export EDITOR=vim

~/projects/api/.envrc

source_up export API_PORT=3000

~/projects/api/feature/.envrc

source_up export FEATURE_FLAG=true

Project Structure

my-project/ ├── .envrc # Base environment (committed) ├── .envrc.local # Local overrides (gitignored) ├── .env # Environment variables (gitignored) ├── .env.example # Template for team (committed) └── .direnv/ # direnv cache (gitignored)

Custom Extensions

Create ~/.config/direnv/direnvrc for custom functions:

#!/usr/bin/env bash

~/.config/direnv/direnvrc

Custom function: Use specific Kubernetes context

use_kubernetes() { local context="${1:-default}" export KUBECONFIG="${HOME}/.kube/config" kubectl config use-context "$context" >/dev/null 2>&1 log_status "kubernetes context: $context" }

Custom function: Load from AWS Secrets Manager

use_aws_secrets() { local secret_name="$1" local region="${2:-us-east-1}" eval "$(aws secretsmanager get-secret-value
--secret-id "$secret_name"
--region "$region"
--query SecretString
--output text | jq -r 'to_entries | .[] | "export (.key)="(.value)""')" log_status "loaded secrets from: $secret_name" }

Custom function: Use asdf versions from .tool-versions

use_asdf() { watch_file .tool-versions source_env "$(asdf direnv local)" }

Usage in .envrc :

use kubernetes dev-cluster use aws_secrets myapp/dev use asdf

Commands Reference

Command Description

direnv allow

Allow the current .envrc

direnv deny

Revoke .envrc access

direnv reload

Force reload environment

direnv status

Show current status

direnv dump

Dump current environment

direnv edit

Open .envrc in editor

direnv version

Show direnv version

Troubleshooting

Environment Not Loading

Check status

direnv status

Force reload

direnv reload

Re-allow .envrc

direnv allow

Check if hook is installed

echo $DIRENV_DIR

Shell Hook Issues

  • Verify hook is in shell config file

  • Ensure it's at the END of the file

  • Restart shell completely: exec $SHELL

  • Check for errors: direnv hook zsh

Performance Issues

Show what's being evaluated

direnv show_dump

For Nix, use nix-direnv for caching

https://github.com/nix-community/nix-direnv

Debugging

Verbose output

export DIRENV_LOG_FORMAT='%s'

Show exported variables

direnv dump | jq

Test .envrc syntax

bash -n .envrc

IDE Integration

VS Code

Install direnv extension for automatic environment loading in integrated terminal.

JetBrains

Install direnv integration plugin.

Neovim

Use direnv.vim or configure with lua.

Common Patterns

Development vs Production

.envrc

export NODE_ENV="${NODE_ENV:-development}"

if [[ "$NODE_ENV" == "development" ]]; then export DEBUG=true export LOG_LEVEL=debug else export DEBUG=false export LOG_LEVEL=info fi

Multi-Service Projects (Monorepo)

root/.envrc

export PROJECT_ROOT="$(pwd)" export COMPOSE_PROJECT_NAME=myapp

services/api/.envrc

source_up export SERVICE_NAME=api export SERVICE_PORT=3000

services/web/.envrc

source_up export SERVICE_NAME=web export SERVICE_PORT=8080

Docker Integration

.envrc

export COMPOSE_FILE=docker-compose.yml export COMPOSE_PROJECT_NAME="${PWD##*/}"

if has docker-compose; then export DOCKER_HOST="${DOCKER_HOST:-unix:///var/run/docker.sock}" fi

Add Docker bin for containers that install CLI tools

PATH_add .docker/bin

References

  • Official Documentation

  • Installation Guide

  • Shell Hook Setup

  • Standard Library Reference

  • nix-direnv

  • Homebrew Formula

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

obsidian-vault-management

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

zabbix

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

neovim

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

obsidian

No summary provided by upstream source.

Repository SourceNeeds Review