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…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.