More practical direnv
Some considerable time ago I wrote my praise for direnv
along with some usage tips. That blog post continues to receive plenty of traffic from people seeking direnv configuration guidance.
Since then, I have continued to use direnv
and (quietly) advocate for it among anyone who will listen. However, what I have not done is share how my usage of the tool has evolved and improved.
For anyone needing a brief introduction, direnv
is a tool that runs hook scripts (.envrc
) as you cd
around a file system. For example, you can cd
into a directory holding a Python codebase and have its virtualenv automatically activated. If you leave the directory, the virtualenv is automatically deactivated. direnv
’s power is its flexibility: it can run any script, update the PATH
or any other environment variables, without coupling to a specific shell.
With a custom ~/.direnvrc
script direnv
gives me automatic setup of language tooling for:
- Python
- Java
- NodeJS
- Ruby
Examples #
All examples assume that my custom ~/.direnvrc
script is being used. My script is only set up for use with Mac OS and requires Homebrew.
You’ll also need to have direnv
installed and hooked in to your shell, of course!
Java #
If you want to use Java 11 in a specific directory, you just create an .envrc
file containing:
use java adopt@1.11.0-6
After modifying an .envrc
file you must allow direnv
to run it, for security reasons. This is simply done by entering direnv allow
at the shell. For example:
$ echo "use java [email protected]" >> .envrc
direnv: error /Users/rnorth/somedir/.envrc is blocked. Run `direnv allow` to approve its content
$ direnv allow
direnv: loading ~/somedir/.envrc
direnv: using java [email protected]
JAVA_HOME=/Users/rnorth/.jabba/jdk/[email protected]/Contents/Home
direnv: export +CPATH +JAVA_HOME +LD_LIBRARY_PATH +LIBRARY_PATH +MANPATH +NODE_VERSIONS +PKG_CONFIG_PATH +PYENV_ROOT ~PATH
$ java -version
openjdk version "11.0.6" 2020-01-14
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.6+10)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.6+10, mixed mode)
From now on, any time you cd
into this directory, direnv
will:
- Automatically install
jabba
from Homebrew, if required - Use
jabba
to download this particular version of Java, if required - Set
JAVA_HOME
and thePATH
to point to the right version of Java
.jabbarc
files are also respected, and will be automatically applied from the current or parent directory. All that’s needed is a blank .envrc
file to trigger direnv
into action.
Python #
Similarly, create an .envrc
file containing:
use python 3.7.6
direnv
will:
- Automatically install
pyenv
from Homebrew, if required - Use
pyenv
to download this version of Python, if required - Create and/or activate a virtualenv in the current directory
- Run
pip3 install
to install dependencies
NodeJS and Ruby #
Unsurprisingly, the pattern continues for NodeJS and Ruby! For example:
use node 12.16.3
and
use ruby 2.3.3
install and set up NodeJS and Ruby automatically, as above.
Summary #
direnv
is a powerful tool, and one that I’m still very happy to use more than five years after first discovering it.
With a small amount of setting up, with a custom ~/.direnvrc
file, it’s extremely powerful, and I hope you find my example a useful starting point!
I’d strongly recommend direnv
for:
- people who are tired of manually updating environment variables
- people using Python who forget to activate/deactive virtualenvs
- people who tend to have to work in many programming languages
Enjoy a more productive, less hassle, shell experience!