wouter bolsterlee edited this page Aug 17, 2018 · 26 revisions


The default python layout uses virtualenv to sandbox a project's dependencies.

Add this to the .envrc:

layout python

The first time the .envrc is loaded it will automatically create the virtualenv under .direnv/python-$python_version. The sandbox is also automatically activated whenever direnv loads the .envrc file (although the prompt won't change).

Restoring the PS1

The PS1 is not modified during activation as it does when doing it by hand. To restore that functionality it's possible to add something like this in your .zshrc/.bashrc:

show_virtual_env() {
  if [ -n "$VIRTUAL_ENV" ]; then
    echo "($(basename $VIRTUAL_ENV))"
export -f show_virtual_env

If you do not add this export show_virtual_env line, when you entering a sub-bash process, the function will not be seen and some error will occur.

If using Conda instead of virtualenv, replace $VIRTUAL_ENV with $CONDA_DEFAULT_ENV.

Selecting python versions

The layout python directive will look for a python executable on the path. It's possible to specify another executable if the virtualenv needs to be created with a different one. For example: layout python ~/.pyenv/versions/2.7.6/bin/python

For python3 there is a shortcut layout python3

venv (stdlib module)

Python 3.3 and later provide built-in support for virtual environments via the venv module in the standard library. This means the virtualenv tool is no longer needed. To use venv to automatically create and activate virtual environments, add this snippet to your ~/.config/direnv/direnvrc:

layout_python-venv() {
    local python=${1:-python3}
    [[ $# -gt 0 ]] && shift
    unset PYTHONHOME
    if [[ -n $VIRTUAL_ENV ]]; then
        VIRTUAL_ENV=$(realpath "${VIRTUAL_ENV}")
        local python_version
        python_version=$("$python" -c "import platform; print(platform.python_version())")
        if [[ -z $python_version ]]; then
            log_error "Could not detect Python version"
            return 1
    export VIRTUAL_ENV
    if [[ ! -d $VIRTUAL_ENV ]]; then
        log_status "no venv found; creating $VIRTUAL_ENV"
        "$python" -m venv "$VIRTUAL_ENV"
    PATH_add "$VIRTUAL_ENV/bin"

Now you can use it like this in your .envrc:

layout python-venv

To specify the Python executable to use, use:

layout python-venv python3.6

(This works similar to the layout python ... that ships with direnv itself.)

To use a different directory for the virtualenv, set the $VIRTUAL_ENV variable to the desired path, which may be relative:

export VIRTUAL_ENV=.venv
layout python-venv python3.6


It's possible to use pyenv to manage python versions and direnv to load them. For this add the following in the ~/.direnvrc file:

use_python() {
  local python_root=$PYENV_ROOT/versions/$1
  load_prefix "$python_root"
  if [[ -x "$python_root/bin/python" ]]; then
    layout python "$python_root/bin/python"
    echo "Error: $python_root/bin/python can't be executed."

Using pyenv, install a couple of versions.

Then in any project's .envrc: use python 2.6.7


It's possible to use pyenv-virtualenv to manage python versions and virtualenvs, and rely on direnv to load them. For this add the following in the ~/.direnvrc (or ~/.config/direnv/direnvrc) file:

# use a certain pyenv version
use_python() {
    if [ -n "$(which pyenv)" ]; then
        local pyversion=$1
        pyenv local ${pyversion}

layout_virtualenv() {
    local pyversion=$1
    local pvenv=$2
    if [ -n "$(which pyenv virtualenv)" ]; then
        pyenv virtualenv --force --quiet ${pyversion} ${pvenv}-${pyversion}
    pyenv local --unset

layout_activate() {
    if [ -n "$(which pyenv)" ]; then
        source $PYENV_ROOT/versions/$1/bin/activate

Using pyenv, install a couple of versions.

Then in any project's .envrc:

# -*- mode: sh; -*-
# (rootdir)/.envrc : direnv configuration file
# see https://direnv.net/
# pyversion=$(head .python-version)
# pvenv=$(head     .python-virtualenv)

use python ${pyversion}
# Create the virtualenv if not yet done
layout virtualenv ${pyversion} ${pvenv}
# activate it
layout activate ${pvenv}-${pyversion}

You can replace your myproject above with: pvenv=$(basename $PWD) to default to the base name of the current path. I use a BASH function to drop the contents of this into the .envrc in $CWD so I have less setup/editing files.


You can define a new layouts in your ~/.direnvrc file to activate a virtual environment automatically.

Add this to your ~/.direnvrc file:

layout_virtualenv() {
  local venv_path="$1"
  source ${venv_path}/bin/activate

layout_virtualenvwrapper() {
  local venv_path="${WORKON_HOME}/$1"
  layout_virtualenv $venv_path

and use it like this in .envrc of project folder:

layout virtualenv /path/to/my-awesome-project


layout virtualenvwrapper my-awesome-project


$ echo layout_pipenv >> .envrc

Or more generally, in the .envrc:



It's possible to use anaconda for virtual environments. For this add the following in the ~/.direnvrc (or ~/.config/direnv/direnvrc) file:

layout_anaconda() {
  local ANACONDA_HOME="${HOME}/miniconda3/"

  if [ -n "$1" ]; then
    # Explicit environment name from layout command.
    local env_name="$1"
    source activate ${env_name}
  elif (grep -q name: environment.yml); then
    # Detect environment name from `environment.yml` file in `.envrc` directory
    source activate `grep name: environment.yml | sed -e 's/name: //' | cut -d "'" -f 2 | cut -d '"' -f 2`
    (>&2 echo No environment specified);
    exit 1;

Then specify anaconda in your .envrc with:

layout anaconda root


layout anaconda

to activate an environment specified in environment.yml.

pycharm editor support

Using direnv with Pycharm explained...

You can use direnv to create your local virtualenv following normal means: echo "layout python3" > .envrc

But certain editors that look for local .env, env or venv will not find .direnv/python-x.x.x/. You can however create a soft link. Pycharm will automatically find and use the local environment.

echo "ln -s .direnv/\$(basename \$VIRTUAL_ENV)/ .env" >> .envrc

Shared my entire setup for this in a gist.

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.