Kennt ihr das? Man arbeitet an Projekt A, exportiert schnell ein paar Variablen – OPENAI_API_KEY, AWS_PROFILE, KUBECONFIG. Alles läuft. Mittags kurz auf Projekt B umschalten, cd ../projekt-b in derselben Shell, terraform apply… und nach 20 Sekunden klingelt der Groschen: der Apply läuft mit dem AWS_PROFILE von Projekt A. Tip top.

Solche Momente sind der Grund, warum es direnv gibt.

Was direnv eigentlich macht

direnv ist ein winziges Tool für die Shell. Du legst in einem Verzeichnis eine Datei namens .envrc an, schreibst rein, was dein Environment für dieses Verzeichnis sein soll – und direnv kümmert sich um den Rest. Wechselst du ins Verzeichnis, sind die Variablen da. Verlässt du es, sind sie wieder weg. Kein Aufräumen, kein „aus Versehen mitnehmen", kein Drama.

Installation – 30 Sekunden

Mac:

brew install direnv

Linux:

sudo apt install direnv   # Debian/Ubuntu
sudo pacman -S direnv     # Arch

Dann der Shell-Hook. Bei zsh ans Ende der ~/.zshrc:

eval "$(direnv hook zsh)"

Bei bash in die ~/.bashrc:

eval "$(direnv hook bash)"

Shell neu öffnen, fertig.

Erstes Mini-Beispiel

Ins Projektverzeichnis wechseln und eine .envrc anlegen:

cd ~/projects/projekt-a
echo 'export OPENAI_API_KEY="sk-projekt-a-..."' > .envrc

Beim ersten Mal motzt direnv:

d i r e n v : e r r o r / U s e r s / r e n e / p r o j e c t s / p r o j e k t - a / . e n v r c i s b l o c k e d . R u n ` d i r e n v a l l o w ` t o a p p r o v e i t s c o n t e n t

Eigentlich sehr sympathisch. direnv führt nichts aus, was du nicht explizit freigeschaltet hast – sonst könnte ja jedes geklonte Repo dir beim ersten cd mal eben ein rm -rf ~ als „Environment" unterjubeln.

Also:

direnv allow

Und ab jetzt: jedes Mal beim Reinwechseln ins Verzeichnis ist der Key gesetzt, beim Verlassen wieder weg.

$ d d $ s $ d $ # i i k i c r r e - c r e l d e e c p d e c e n n h r n h e ~ v o o v o r / : : j : . p $ e $ r l e O k u O o o x P t n P j a p E - l E e d o N a o N c i r A a A t n t I d I s g _ i _ / + A n A p ~ O P g P r P I I p E _ _ j r N K K e o A E E k j I Y Y t e _ - c A a t P s I / _ p K r E o Y j e k t - a / . e n v r c

So weit, so „export mit Stil". Aber das ist erst der Anfang.

Was ich wirklich täglich damit mache

1. API-Keys & Tokens pro Projekt

Klassiker. Jeder Kunde, jedes Side-Projekt hat seinen eigenen Schlüssel-Bunch:

# .envrc
export OPENAI_API_KEY="sk-..."
export GITHUB_TOKEN="ghp_..."
export STRIPE_SECRET_KEY="sk_test_..."

.envrc gehört dabei immer in die .gitignore. Ich lege im Repo stattdessen eine .envrc.example mit Platzhaltern ab – als Doku, was dieses Projekt erwartet.

2. Cloud-Profile sauber getrennt

export AWS_PROFILE="kunde-x-prod"
export AWS_REGION="eu-central-1"
export KUBECONFIG="$PWD/kube/config.yaml"

Verlässt du das Verzeichnis – pang, $AWS_PROFILE ist wieder weg. Keine Chance mehr, im falschen Kontext einen apply durchzudrücken.

3. PATH lokal erweitern

In Node-Projekten will man oft ./node_modules/.bin im PATH – ohne den globalen PATH dauerhaft zuzumüllen:

PATH_add ./node_modules/.bin

PATH_add ist ein direnv-Helfer und hängt das Verzeichnis sauber vorne dran, mit korrekter Auflösung relativer Pfade.

4. Python-virtualenv automatisch

layout python python3.12

Beim ersten cd erstellt direnv ein .direnv/python-3.12/-venv, beim Reinwechseln wird’s aktiviert, beim Rausgehen deaktiviert. Kein source .venv/bin/activate mehr von Hand.

Gleicher Trick für Node:

use node 22

(funktioniert, wenn du nodenv, nvm, asdf o.ä. einsetzt – direnv weiß, was da ist.)

5. Geheimnisse aus dem Passwort-Manager ziehen

Statt Klartext-Tokens in der .envrc:

export OPENAI_API_KEY="$(op read 'op://Private/OpenAI/credential')"

(op ist die 1Password-CLI – Bitwarden, pass o.ä. funktionieren genauso.) Die Keys werden beim cd frisch aus dem Tresor gezogen, leben nur in der laufenden Shell und liegen nirgendwo auf der Platte rum.

Ein paar Pro-Tipps aus der Praxis

  • .envrc immer in .gitignore. Immer. Ein Token-Leak im Repo holt dich Jahre später noch ein.
  • .envrc.example ins Repo legen, mit Platzhaltern. Spart dem nächsten Kollegen 20 Minuten Rätselraten.
  • .envrc lassen sich verschachteln: eine Variable in ~/.envrc gilt überall, kann aber im Projekt überschrieben werden.
  • direnv status zeigt dir, was gerade geladen ist und ob die aktuelle .envrc noch freigeschaltet ist.
  • Bei jeder Änderung an einer .envrc musst du wieder direnv allow aufrufen. Klingt nervig, ist aber Absicht – jede Änderung muss aktiv abgesegnet werden.

Was bleibt am Ende

direnv löst kein Mond-Problem. Es macht eine winzige Sache richtig gut: Es trennt deine Projekte mental und technisch sauber voneinander. Du musst dir nicht mehr merken, in welcher Shell welcher Key gerade gesetzt ist. Und Tippfehler à la AWS_PROFLIE (echt jetzt, schon dreimal passiert) führen nicht mehr dazu, dass du eine Stunde später ratlos in der falschen Region schaust.

Wenn dein aktueller Workflow gerade von einer Wand mit Tokens in der ~/.zshrc lebt – probier’s mal ein Wochenende lang. Du wirst überrascht sein, wie viel Kopf danach frei wird.