Making Conda Work with Python Tools (uv, pipx)

Posted on Fri 24 January 2025 in Python • 2 min read

Modern Python tools like uv and pipx detect the active environment using the VIRTUAL_ENV environment variable. Conda environments use CONDA_PREFIX instead. This mismatch means these tools don't recognize an active conda environment.

The Problem

When you activate a conda environment:

conda activate myenv
echo $CONDA_PREFIX    # /home/user/miniconda3/envs/myenv
echo $VIRTUAL_ENV     # (empty)

Tools that check VIRTUAL_ENV think there's no active environment and may install packages to the wrong location or refuse to work.

The Solution

Conda supports activation and deactivation hooks - scripts that run automatically when you activate or deactivate an environment. We can use these to set and unset VIRTUAL_ENV.

Step 1: Activate the Target Environment

conda activate your_env_name

Step 2: Create the Hook Scripts

Run these commands to create the activation and deactivation scripts:

# Create activation hook directory
mkdir -p $CONDA_PREFIX/etc/conda/activate.d/

# Create script that sets VIRTUAL_ENV on activation
echo 'export VIRTUAL_ENV="$CONDA_PREFIX"' > $CONDA_PREFIX/etc/conda/activate.d/env_vars.sh

# Create deactivation hook directory
mkdir -p $CONDA_PREFIX/etc/conda/deactivate.d/

# Create script that unsets VIRTUAL_ENV on deactivation
echo 'unset VIRTUAL_ENV' > $CONDA_PREFIX/etc/conda/deactivate.d/env_vars.sh

Step 3: Verify

Deactivate and reactivate the environment to test:

conda deactivate
conda activate your_env_name
echo $VIRTUAL_ENV    # Should print: /home/user/miniconda3/envs/your_env_name

Why This Works

When you run conda activate:

  1. Conda loads the environment
  2. Conda runs all scripts in $CONDA_PREFIX/etc/conda/activate.d/
  3. Our script sets VIRTUAL_ENV=$CONDA_PREFIX

When you run conda deactivate:

  1. Conda runs all scripts in $CONDA_PREFIX/etc/conda/deactivate.d/
  2. Our script unsets VIRTUAL_ENV
  3. Conda unloads the environment

Per-Environment Setup

This setup is per-environment. If you have multiple conda environments you use with uv or pipx, repeat these steps for each one.

For a reusable script:

#!/bin/bash
# save as: setup-virtualenv-hook.sh
# usage: ./setup-virtualenv-hook.sh myenv

ENV_NAME=$1
if [ -z "$ENV_NAME" ]; then
    echo "Usage: $0 <environment_name>"
    exit 1
fi

conda activate $ENV_NAME

mkdir -p $CONDA_PREFIX/etc/conda/activate.d/
mkdir -p $CONDA_PREFIX/etc/conda/deactivate.d/

echo 'export VIRTUAL_ENV="$CONDA_PREFIX"' > $CONDA_PREFIX/etc/conda/activate.d/env_vars.sh
echo 'unset VIRTUAL_ENV' > $CONDA_PREFIX/etc/conda/deactivate.d/env_vars.sh

echo "VIRTUAL_ENV hook configured for $ENV_NAME"

Testing with uv

After setting up the hook:

conda activate myenv
uv pip install requests  # Now works correctly

uv now detects the conda environment and installs packages to the right location.

This simple hook bridges the gap between conda's environment management and the broader Python tooling ecosystem.