Python
virtualenv
pyenv
Python environment
Python tools

What is the relationship between virtualenv and pyenv?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

virtualenv and pyenv are often mentioned together, which makes them sound like competing tools. They are not competitors. They solve two different layers of the Python setup problem: choosing which Python interpreter exists on your machine, and isolating project dependencies from each other.

They Solve Different Problems

pyenv is a Python version manager. Its job is to install and select interpreters such as Python 3.10, 3.11, or 3.12 without replacing the system Python. That matters when one project depends on an older interpreter and another needs a newer one.

bash
1pyenv install 3.11.9
2pyenv install 3.12.4
3pyenv global 3.12.4
4python --version

When you run pyenv local 3.11.9 inside a project directory, pyenv writes a .python-version file so shells entering that directory resolve python to the chosen interpreter.

bash
cd my-project
pyenv local 3.11.9
python --version

virtualenv, by contrast, does not install Python versions. It takes an interpreter that already exists and creates an isolated environment around it. Inside that environment, pip install affects only that project’s packages and console scripts.

bash
1python -m virtualenv .venv
2source .venv/bin/activate
3python --version
4pip install requests

That is the core relationship in one sentence: pyenv chooses the interpreter, and virtualenv isolates packages that run on top of that interpreter.

How They Work Together

A common workflow is to start with pyenv, pick the Python version the project requires, and then build a virtual environment from that version.

bash
1pyenv install 3.11.9
2pyenv local 3.11.9
3python -m virtualenv .venv
4source .venv/bin/activate
5python --version

Because the shell now resolves python through pyenv, the virtual environment is created from Python 3.11.9. If you skip the pyenv local step and create the environment first, the environment may be based on the wrong interpreter.

This layered workflow is useful because version choice and dependency isolation are separate concerns. Two projects can both use Python 3.11 and still require different package versions. pyenv alone cannot solve that package conflict.

You can inspect the active interpreter path to confirm what happened:

bash
pyenv which python
python -c "import sys; print(sys.executable)"

Before activation, those commands point to the interpreter chosen by pyenv. After activation, the second command points into .venv/bin/python, which is exactly what you want.

Where venv and pyenv-virtualenv Fit

Modern Python includes the standard library module venv, which often replaces the third-party virtualenv package for everyday use:

bash
python -m venv .venv
source .venv/bin/activate

Conceptually, venv fills the same role here. It creates an isolated environment from the active interpreter. If pyenv selected Python 3.12, then python -m venv .venv builds the environment from Python 3.12.

You may also see pyenv-virtualenv, which is a plugin integrating the two workflows:

bash
pyenv virtualenv 3.11.9 project-3.11
pyenv local project-3.11

This can feel more unified because the environment itself becomes a pyenv-managed choice. Even so, the underlying model stays the same. One layer manages interpreters. Another layer isolates dependencies.

Common Pitfalls

The most common mistake is assuming pyenv removes the need for virtual environments. It does not. If two applications both run on Python 3.11 but need different versions of Django or requests, you still need isolated environments.

Another mistake is creating the virtual environment before selecting the correct interpreter. The environment will then keep pointing at whichever Python executable was active when it was created, even if you later change the local pyenv version.

Developers also sometimes forget activation and then install packages into the wrong place. If pip install behaves strangely, check which python and which pip before assuming the toolchain is broken.

Finally, it helps to separate concepts that are often bundled together in conversation: pyenv manages interpreter versions, virtualenv or venv manages isolated package environments, and tools such as Poetry or Pipenv add higher-level dependency workflows on top.

Summary

  • 'pyenv manages which Python interpreter version is available and active.'
  • 'virtualenv creates an isolated environment from an interpreter that already exists.'
  • A common pattern is pyenv first, then virtualenv or venv.
  • 'pyenv-virtualenv combines the commands, but not the underlying responsibilities.'
  • If the Python version is wrong, inspect pyenv; if packages are leaking, inspect the virtual environment.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.