Skip to content
Back to skills

Direnv

DSecurity

direnv loads and unloads environment variables automatically when you enter and leave a directory, using a per-project .envrc file. Use when a user asks to manage env vars per project, auto-switch configs, avoid manually sourcing .env files, set up .envrc, use dotenv with direnv, or pick a Python or Node version per directory.

  • 142 stars
  • 0 votes
  • 0 copies
  • 19 views
  • Added May 27, 2026
developmentpythonrustgorubyshellbashsqlnodegitapi

Works with

  • terminal
  • api

Security analysis

D59/100
  • criticalModifies startup scripts or system services for persistence
  • criticalModifies startup scripts or system services for persistence
  • criticalSends environment variables or credentials to an external URL
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 2 files and shows the line behind each finding

Scanned October 4, 2026

npx -y skills add TerminalSkills/skills --skill direnv --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Direnv?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Direnv
[![Security: D — Skills Directory](https://www.skillsdirectory.com/api/skills/terminalskills-direnv/badge)](https://www.skillsdirectory.com/skills/terminalskills-direnv)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: direnv
description: >-
  direnv loads and unloads environment variables automatically when you enter and leave a directory, using a per-project .envrc file. Use when a user asks to manage env vars per project, auto-switch configs, avoid manually sourcing .env files, set up .envrc, use dotenv with direnv, or pick a Python or Node version per directory.
license: Apache-2.0
compatibility: 'Linux, macOS, WSL; bash, zsh, fish, tcsh, elvish, nushell, PowerShell'
metadata:
  author: terminal-skills
  version: 1.1.0
  category: development
  repository: https://github.com/direnv/direnv
  tags:
    - direnv
    - environment
    - dotenv
    - shell
    - config
---

# direnv

## Overview

direnv is a single static binary that hooks into your shell. When the current directory (or a parent) contains an `.envrc` file that you have approved, direnv runs it in a bash subprocess, captures the exported variables and applies them to your shell; when you leave the directory, they are unloaded. `.envrc` is plain bash plus a standard library of helpers (`dotenv`, `PATH_add`, `layout`, `use`, `source_up`, `watch_file`). Latest release at the time of writing: v2.37.1.

## Instructions

### Step 1: Install and hook into the shell

```bash
brew install direnv          # macOS / Linuxbrew
sudo apt install direnv      # Debian, Ubuntu
sudo dnf install direnv      # Fedora
nix profile install nixpkgs#direnv   # Nix
```

Then add the hook to the end of your shell's startup file (after anything that changes the prompt, such as starship or oh-my-posh) and open a new shell:

```bash
eval "$(direnv hook bash)"      # ~/.bashrc
eval "$(direnv hook zsh)"       # ~/.zshrc
direnv hook fish | source       # ~/.config/fish/config.fish
```

Other shells (tcsh, elvish, nushell, PowerShell, murex) are covered in the direnv hook docs. Without the hook nothing happens when you `cd`.

### Step 2: Write an .envrc and approve it

```bash
# ~/code/billing-api/.envrc
export NODE_ENV=development
export DATABASE_URL="postgresql://billing:billing@localhost:5432/billing_dev"
dotenv_if_exists .env.local     # secrets live here, not in .envrc
env_vars_required STRIPE_API_KEY   # log an error if it is missing or empty
PATH_add bin
PATH_add node_modules/.bin
```

```bash
direnv allow          # approve this exact file; required the first time and after every edit
direnv status         # shows the loaded .envrc and whether it is allowed
direnv reload         # re-run without leaving the directory
direnv deny           # revoke approval
```

Unapproved or changed `.envrc` files are blocked with an `is blocked. Run direnv allow` message, which is the main security feature: a cloned repository cannot run code in your shell until you allow it. Read an `.envrc` before allowing it.

### Step 3: Per-project toolchains

The standard library provides these (check `direnv stdlib` for the version you have):

```bash
layout python3        # creates and activates a virtualenv in .direnv/python-<version>
layout node           # adds node_modules/.bin to PATH
layout ruby           # sets GEM_HOME inside .direnv/
layout go             # sets GOPATH inside .direnv/ and adds ./bin to PATH
use node              # reads .nvmrc / .node-version; needs NODE_VERSIONS pointing at a folder of installed Node versions
use nix               # or: use flake
```

`use nvm`, `use asdf` and similar are not in the standard library. Define them in `~/.config/direnv/direnvrc` (a `use_<name>` function) or use `use node`, `use nix` or `use flake`. Add `watch_file` for any file whose change should trigger a reload (for example `watch_file .tool-versions`).

### Step 4: Share and layer configuration

```bash
# repo-root/.envrc (committed, contains no secrets)
export COMPOSE_PROJECT_NAME=billing
source_env_if_exists .envrc.local    # personal overrides, gitignored

# repo-root/services/worker/.envrc
source_up                             # inherit the parent .envrc first
export QUEUE_NAME=invoices
```

Global settings go in `~/.config/direnv/direnv.toml` (`[global]` keys such as `warn_timeout`, `hide_env_diff`, `load_dotenv`; `[whitelist]` with `prefix` to pre-approve trusted directories).

## Examples

### Example 1: Node project with a local database and secret key

**User request:** "Every time I cd into billing-api I want DATABASE_URL set and my Stripe test key loaded, without committing the key."

Create `.envrc` (commit it) and `.env.local` (gitignore it):

```bash
# .envrc
export DATABASE_URL="postgresql://billing:billing@localhost:5432/billing_dev"
dotenv_if_exists .env.local
env_vars_required STRIPE_API_KEY
PATH_add node_modules/.bin
```

```bash
echo ".env.local" >> .gitignore
echo 'STRIPE_API_KEY=sk_test_replace_me' > .env.local
direnv allow
```

Result: `cd billing-api` prints `direnv: loading ~/code/billing-api/.envrc` and `direnv export: +DATABASE_URL +STRIPE_API_KEY ~PATH`; `cd ..` prints `direnv: unloading` and the variables are gone.

### Example 2: Isolated Python environment per repository

**User request:** "Make a virtualenv that activates automatically when I enter the ml-pipeline folder."

```bash
cd ~/code/ml-pipeline
printf 'layout python3\nwatch_file requirements.txt\n' > .envrc
direnv allow
pip install -r requirements.txt     # installs into .direnv/python-3.12.x
```

Result: `which python` points into `~/code/ml-pipeline/.direnv/python-<version>/bin`, and leaving the folder restores the global interpreter. Add `.direnv/` to `.gitignore`.

## Guidelines

- Keep secrets out of a committed `.envrc`: load them from a gitignored file with `dotenv_if_exists`, or from a secret manager command run at load time. If an `.envrc` holds secrets, gitignore it and commit an `.envrc.example` instead.
- Always run `direnv allow` only after reading the file; the approval is tied to the file's path and content, so every edit needs a new `direnv allow`.
- `.envrc` variables are exported only to your interactive shell and its children; they are not seen by cron, systemd or IDE launchers started elsewhere. Use `direnv exec <dir> <command>` to run a command with a directory's environment.
- Aliases and shell functions cannot be exported from `.envrc`; put scripts in a `bin/` folder and use `PATH_add bin`.
- A slow `.envrc` slows every prompt; cache expensive work or raise `warn_timeout` instead of hiding the warning.
- Add `strict_env` at the top of an `.envrc` to fail fast on unset variables and failing commands.
- direnv does not replace container or CI configuration; use real environment variables or a secret store there.

Files in this skill

  • SKILL.md1.3 KB
  • _scores.json1.5 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…