Per-Directory Environment Variables with direnv

less than 1 minute read

While tinkering with ledger, it was a pain to constantly specify the input file. The app supports a LEDGER_FILE environment variable, but it didn’t make sense to specify that in my user profile’s dotfiles. Enter direnv:

direnv is an extension for your shell. It augments existing shells with a new feature that can load and unload environment variables depending on the current directory.

In my specific scenario, I have the following .envrc file in the working directory for my ledger project:

# .envrc
export LEDGER_FILE=transactions.dat
export LEDGER_DATE_FORMAT=%Y/%m/%d

When I cd into the directory, direnv loads the file:

$ cd finances
direnv: loading .envrc
direnv: export +LEDGER_DATE_FORMAT +LEDGER_FILE
$ echo $LEDGER_FILE
transactions.dat

And when I cd back out of the directory, direnv unloads:

$ cd ..
direnv: unloading
$ echo $LEDGER_FILE

This allows me to keep project-specific configuration committed to the same git repository as the project itself. It’s available to install in most Unix-like distributions. I have it in my Brewfile for macOS and bootstrap.sh for Raspbian, and have added eval "$(direnv hook zsh)" to my .zsh_profile.