Posted in

If not Python venv, then what?

For years, python -m venv .venv has been the default answer to Python dependency management and isolation. It works, it’s built into Python and almost every tutorial assumes you’ll use it.

But today, more and more developers are asking a question Do I actually need venv anymore?

And the answer is: not always. This article explores what modern alternatives exist and when they make sense.

Option 1: uv

The biggest momentum shift in Python tooling right now is probably uv. It’s a Rust-based Python package manager that aims to be extremely fast while simplifying dependency and environment management.

To install uv, invoke:

ShellScript
curl -LsSf https://astral.sh/uv/install.sh | sh

Now you can call:

ShellScript
uv init my_app
cd my_app

This creates a project folder with the following files:

  • .python-version – contains the Python interpreter version
  • main.py – a ready-to-run hello world application
  • pyproject.toml
  • README.md

You can run the generated application with:

ShellScript
uv run main.py

If you want to add the requests library, call:

ShellScript
uv add requests

At this point, uv automatically creates a .venv folder and installs the dependency there.

Option 2: Poetry

Before uv, Poetry was often considered the “modern Python workflow” tool. To install Poetry, call:

ShellScript
curl -LsSf https://install.python-poetry.org | python3 -

Now you can call:

ShellScript
poetry new myapp
cd myapp

This creates a slightly different project structure than uv:

  • src/myapp/__init__.py
  • tests/__init__.py
  • pyproject.toml
  • README.md

Notice that there is no .venv folder inside the project directory. By default, Poetry stores all virtual environments centrally in one location. On Linux, you can usually find them in ~/.cache/pypoetry/virtualenvs where every Poetry-managed project gets its own dedicated virtual environment.

If you want to add the requests library, call:

ShellScript
poetry add requests

To run your application, invoke:

ShellScript
poetry run python src/myapp/main.py

AI is powerful. Snippets are instant.

Stop prompting for the same patterns repeatedly. Get almost 100 free VS Code snippets for C++, Python, CMake and Bazel from piko::snippets GitHub repository.


Option 3: PDM

PDM originally implemented an idea based on PEP 582. Instead of creating isolated virtual environments with separate interpreter binaries, dependencies (and only Python dependencies) would simply be stored in a local __pypackages__ directory inside the project.

To install PDM, invoke:

ShellScript
curl -LsSf https://pdm-project.org/install-pdm.py | python3 -

Now you can call:

ShellScript
pdm new myapp

Unlike uv and Poetry, PDM asks several interactive questions before creating the project, for example:

  • what Python interpreter should be used?
  • what is the project name?
  • what is the project version?
  • what license should be used?
  • what is the author name?
  • what is the email address?
  • should a Git repository be initialized?

After answering these questions, PDM creates a structure similar to:

  • .venv
  • .pdm-python
  • pyproject.toml

If you want to add the requests library, call:

ShellScript
pdm add requests

And the dependency lands in the .venv folder. So where is the promised __pypackages__ directory?

The answer is that PEP 582 was never accepted as an official Python standard, so ecosystem tooling never fully adopted it. As a result, modern PDM versions switched to .venv as the default approach.

If you still want to use __pypackages__, you must enable it explicitly:

ShellScript
pdm config python.use_venv false

Now dependencies will be stored in the __pypackages__ directory instead. Running your app is no surprise at this point:

ShellScript
pdm run main.py

Option 4: Containers instead of environments

Some teams skip Python environments entirely and isolate applications using containers. In this approach, dependency isolation happens at the container level rather than through local virtual environments.

In such setups, having a dedicated venv becomes less important because the container itself acts as the isolation boundary.

So are these really alternatives to venv?

Not really.

Most of these systems still rely on virtual environments in one form or another. The biggest shift is not abandoning venv, but changing how developers think about Python projects.

Traditional venv workflows treat virtual environments as standalone entities that developers explicitly create, activate and attach to projects. Modern tooling flips that model around: the project becomes the primary unit and the environment is automatically associated with it, so instead of thinking “I need to activate this environment.”, developers think “I’m working on this project.” while the tooling quietly ensures that the correct interpreter and dependencies are available behind the scenes.


Read also: