pyenv-virtualenv: Python Virtual Environment Plugin
pyenv-virtualenv is a plugin for pyenv that creates and manages virtual environments 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 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 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. For pyenv users moving to uv, see How to switch from pyenv to uv for managing Python versions.
Installation
Install with Homebrew:
brew install pyenv-virtualenvOr clone into pyenv’s plugin directory:
git clone https://github.com/pyenv/pyenv-virtualenv.git $(pyenv root)/plugins/pyenv-virtualenvAfter installation, add the init hook to the shell startup file (.bashrc, .zshrc, or config.fish) below the existing pyenv init line:
eval "$(pyenv virtualenv-init -)"Key Commands
Creating a virtual environment
# 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-projectActivating and deactivating
# Activate manually
pyenv activate my-project
# Deactivate
pyenv deactivateAuto-activating with .python-version
# Set the active environment for the current directory
pyenv local my-projectpyenv 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
# List all virtualenvs managed by pyenv
pyenv virtualenvs
# Delete an environment
pyenv uninstall my-projectHow 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-inithook 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 reference
- How do pyenv and uv compare for Python interpreter management?
- How to switch from pyenv to uv for managing Python versions
- What is a .python-version file?
- What is a virtual environment?