pyenv vs uv: Managing Python Versions
pyenv or uv for installing and switching Python versions? How each works, the commands, build-from-source versus prebuilt downloads, and which to choose.
If you are starting fresh, use uv for Python versions; if pyenv already works for you, there is no urgent reason to move. Both do the same core job: put the right Python on your machine and pick the right one per project. They differ in how they get the interpreter and how much else they do.
At a glance
| pyenv | uv | |
|---|---|---|
| What it is | A Python version switcher, written as shell scripts | A package, project and Python manager, written in Rust |
| How it gets Python | Mostly compiles from source | Downloads prebuilt standalone builds |
| Build dependencies | Needed on your machine | Not needed for the download |
| Switching versions | Shims at the front of PATH | Per-command --python, .python-version, project settings |
| Virtual environments | Not included (pyenv-virtualenv plugin) | Built in (uv venv, uv sync) |
| Dependencies/lockfile | No | Yes |
| Windows | Not natively; pyenv-win fork | Supported |
pyenv
pyenv switches between multiple Python versions. It supports a global version per user, a per-project version, and an environment-variable override. It works by inserting a directory of shims at the front of your PATH: when you run python or pip, the shim hands the call to pyenv, which picks the version from PYENV_VERSION, a .python-version file, or the global setting.
pyenv install 3.10.4 # install a version
pyenv global 3.10.4 # set the default
pyenv local 3.10.4 # set the version for this directory and below
Two things to know from the README:
- Most versions are built from source as part of installation, so you need your platform’s build dependencies installed first. That is the usual reason installs are slow or fail.
- It doesn’t manage virtual environments. You create them yourself, or use
pyenv-virtualenvto automate it.
On Windows, the README says pyenv doesn’t officially support it and doesn’t work outside the Windows Subsystem for Linux; it recommends the pyenv-win fork for native use.
uv
uv manages Python versions as part of a wider toolchain. It calls the builds it installs managed installations, and everything else system installations.
uv python install 3.12 # latest 3.12 patch release
uv python install 3.9 3.10 3.11 # several at once
uv python list # installed and available versions
uv python pin 3.12 # write .python-version in this directory
uv python upgrade 3.12 # move a minor version to its latest patch
Key behaviours from uv’s documentation:
- Automatic downloads. If a command needs a Python version you don’t have, uv downloads it. Set
python-downloadstomanual, or pass--no-python-downloads, to stop that. --pythonon most commands. For exampleuv venv --python 3.11.6makes sure that version is available, downloading it if needed, before creating the environment.- Prebuilt builds. uv uses
python-build-standalonedistributions. Its docs note that building from source, as pyenv does, requires preinstalled system dependencies. - Upgrades.
uv python upgradeupgrades uv-managed versions only. Each minor version directory is a symlink to a patch version, so virtual environments pick up the upgrade. - Discovery. uv checks its managed installs, then
python,python3andpython3.xonPATH, and on Windows the registry and Microsoft Store. If nothing matches, it falls back to a download.
Using them together
You don’t have to choose. The uv documentation says a Python installation managed by pyenv is still considered a system Python in uv, so uv can use interpreters pyenv installed but won’t manage them. Both tools read the .python-version file, which makes moving from one to the other straightforward.
Which should you pick?
- New machine or new project: uv. One tool installs Python, creates the environment and locks dependencies; see uv vs venv vs conda and Poetry vs uv vs Hatch.
- Existing pyenv setup that works: keep it. Add uv for projects when it suits you.
- Windows without WSL: uv, or
pyenv-winif you specifically want the pyenv workflow. - You need a build with custom compile options: pyenv, since it builds from source and uv downloads standard prebuilt builds.
- CI and containers: uv is simpler because there is nothing to compile; see Docker for Python with uv.
Before choosing a version to install, check the Python version support dates. If you are on an older one, Python 3.12 end of life covers how to plan the move.
On Windows? See how to install Python on Windows, which covers the Python install manager, winget and uv.
Frequently Asked Questions
Can uv replace pyenv?
For installing and switching Python versions, yes. uv can install interpreters (uv python install 3.13), pin a project’s version with a .python-version file (uv python pin), and download missing versions automatically. If you already use pyenv, uv treats pyenv-managed interpreters as system installations rather than managing them.
What is the difference between pyenv and uv?
pyenv is a shell-script tool that switches between Python versions using shims on your PATH and builds most versions from source. uv is a Rust-based package and project manager whose Python management downloads prebuilt standalone builds, and which also handles virtual environments, dependencies and lockfiles.
Does pyenv work on Windows?
Not natively. The pyenv README says it does not officially support Windows and does not work outside the Windows Subsystem for Linux, and recommends the pyenv-win fork for native Windows. uv supports Windows.
Why is pyenv install slow?
Most pyenv-provided Python releases are source releases that are compiled during installation, and you need the build dependencies installed first. uv instead downloads prebuilt python-build-standalone distributions.
What is a .python-version file?
A one-line file naming the Python version a directory should use. Both pyenv local and uv python pin write it, and both tools read it, so a project can keep working if you move from one to the other.
Do I still need venv if I use uv?
You still need a virtual environment per project, but uv creates it for you (uv venv, or automatically with uv sync). pyenv does not manage virtual environments itself; the README points to pyenv-virtualenv or creating them yourself.