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

pyenvuv
What it isA Python version switcher, written as shell scriptsA package, project and Python manager, written in Rust
How it gets PythonMostly compiles from sourceDownloads prebuilt standalone builds
Build dependenciesNeeded on your machineNot needed for the download
Switching versionsShims at the front of PATHPer-command --python, .python-version, project settings
Virtual environmentsNot included (pyenv-virtualenv plugin)Built in (uv venv, uv sync)
Dependencies/lockfileNoYes
WindowsNot natively; pyenv-win forkSupported

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-virtualenv to 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-downloads to manual, or pass --no-python-downloads, to stop that.
  • --python on most commands. For example uv venv --python 3.11.6 makes sure that version is available, downloading it if needed, before creating the environment.
  • Prebuilt builds. uv uses python-build-standalone distributions. Its docs note that building from source, as pyenv does, requires preinstalled system dependencies.
  • Upgrades. uv python upgrade upgrades 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, python3 and python3.x on PATH, 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-win if 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.