# pyenv-virtualenv: Python Virtual Environment Plugin


pyenv-virtualenv is a plugin for [pyenv](https://pydevtools.com/handbook/reference/pyenv.md) that creates and manages [virtual environments](https://pydevtools.com/handbook/explanation/what-is-a-virtual-environment.md) tied to specific Python versions. It extends pyenv with a `pyenv virtualenv` command and hooks into shell initialization so the right environment activates whenever a directory's [`.python-version` file](https://pydevtools.com/handbook/explanation/what-is-a-python-version-file.md) names it.

## When to use pyenv-virtualenv

pyenv-virtualenv fits teams already running pyenv who want directory-scoped virtual environments without changing version managers. The plugin pairs with [pip](https://pydevtools.com/handbook/reference/pip.md) or any other installer because it only handles environment creation and activation. Teams looking for a single tool that combines Python version management, virtual environments, lockfiles, and dependency resolution may prefer [uv](https://pydevtools.com/handbook/reference/uv.md). For pyenv users moving to uv, see [How to switch from pyenv to uv for managing Python versions](https://pydevtools.com/handbook/how-to/how-to-switch-from-pyenv-to-uv-for-managing-python-versions.md).

## Installation

Install with [Homebrew](https://pydevtools.com/handbook/reference/homebrew.md):

```bash
brew install pyenv-virtualenv
```

Or clone into pyenv's plugin directory:

```bash
git clone https://github.com/pyenv/pyenv-virtualenv.git $(pyenv root)/plugins/pyenv-virtualenv
```

After installation, add the init hook to the shell startup file (`.bashrc`, `.zshrc`, or `config.fish`) below the existing `pyenv init` line:

```bash
eval "$(pyenv virtualenv-init -)"
```
pyenv-virtualenv does not support Windows. WSL is the official workaround.

[uv](https://pydevtools.com/handbook/reference/uv.md) provides cross-platform Python version management and virtual environments with the same commands on every OS.
## Key Commands

### Creating a virtual environment

```bash
# Create a virtualenv from a specific installed Python version
pyenv virtualenv 3.12.4 my-project

# Create a virtualenv from the currently active Python version
pyenv virtualenv my-project
```

### Activating and deactivating

```bash
# Activate manually
pyenv activate my-project

# Deactivate
pyenv deactivate
```

### Auto-activating with .python-version

```bash
# Set the active environment for the current directory
pyenv local my-project
```

`pyenv local my-project` writes `my-project` into a `.python-version` file in the current directory. With the `pyenv virtualenv-init` hook installed, the environment activates automatically when entering the directory and deactivates when leaving it.

### Listing and removing environments

```bash
# List all virtualenvs managed by pyenv
pyenv virtualenvs

# Delete an environment
pyenv uninstall my-project
```

## How activation works

The `pyenv virtualenv-init` hook adds a shell function that checks the `.python-version` file every time the working directory changes. When the file names a virtualenv created by the plugin, the hook activates it; when the file is absent or names only an interpreter, the hook deactivates whatever was active. This is the same shim mechanism pyenv uses for interpreter selection, extended to environment activation.

## Limitations

- macOS and Linux only. No Windows support; WSL is the workaround.
- Bound to pyenv. Environments live under `$(pyenv root)/versions/` and depend on pyenv-installed Python interpreters. Removing pyenv removes the environments.
- No dependency management. The plugin only creates environments. Dependency resolution and lockfiles require separate tools.
- Shell-hook activation. Auto-activation depends on the `pyenv virtualenv-init` hook firing on every directory change. Subshells, scripts run from outside an interactive shell, and editor-launched processes do not always pick up the active environment.

## Related Handbook Pages

- [pyenv](https://pydevtools.com/handbook/reference/pyenv.md) reference
- [How do pyenv and uv compare for Python interpreter management?](https://pydevtools.com/handbook/explanation/how-do-pyenv-and-uv-compare-for-python-interpreter-management.md)
- [How to switch from pyenv to uv for managing Python versions](https://pydevtools.com/handbook/how-to/how-to-switch-from-pyenv-to-uv-for-managing-python-versions.md)
- [What is a .python-version file?](https://pydevtools.com/handbook/explanation/what-is-a-python-version-file.md)
- [What is a virtual environment?](https://pydevtools.com/handbook/explanation/what-is-a-virtual-environment.md)

## Learn More

- [pyenv-virtualenv on GitHub](https://github.com/pyenv/pyenv-virtualenv)
- [pyenv on GitHub](https://github.com/pyenv/pyenv)
