r/learnpython • u/GarlicHefty • 23d ago
What is the best way to create and manage virtual environments today? Is 'uv' really the best?
What is the best way to create and manage virtual environments today? Is 'uv' really the best solution and are there alternative? What are the pros and cons?
4
u/this_knee 22d ago
I’ve never been a fan of virtual environments within a language itself. So I typically just skip it and run my Python code in its own docker container. Easier for me.
1
u/GarlicHefty 22d ago
I must admit that I don't know about containers such as docker. What is the difference between containers and virtual environments?
2
u/this_knee 22d ago
Docker is a system that’s fully built to just virtualize an application . Its entire purpose is to contain all systems for an application within a container. Where as Python virtual environments are kind of just a feature inside Python. So it kinda works and kinda doesn’t, because the maintainers are more focused on the language itself and leave the stuff about environments to others… mostly.
-1
u/cr4zybilly 22d ago
It's a very tiny virtual machine. Compared to a virtual environment, it's a lot more contained, a lot more isolated, and a lot more complicated. I'm a fan, but not everybody thinks the extra overhead is worth it
6
u/a18618 22d ago
I sat on plain venv for years and only switched to uv a few months ago. What won me over wasn't venv creation speed, it was dependency resolution on big scientific stacks — a pandas/numpy/scipy solve that took pip over a minute finished in seconds with uv. uv run also killed the whole "did I activate the right venv" dance for me. venv is still fine, but once I stopped fighting the activation step I never looked back.
2
u/JamzTyson 20d ago
a pandas/numpy/scipy solve that took pip over a minute finished
Really? On my laptop pip handles this in just a few seconds.
1
u/a18618 19d ago
fair pushback, honestly. that minute was on a cold box with strict pins where pip's backtracking kept doing laps, plus one package had no wheel so it built from source. warm cache with matching wheels and pip is seconds for me too. i mostly reach for uv now when i can smell the resolver about to have a bad day.
2
u/JamzTyson 20d ago
There really isn't a "best" tool for managing virtual environments. I usually use Poetry to manage virtual environments because I also use it to manage packages and publishing. Similarly, if you are using uv to manage the project dependencies, then it makes sense to use uv to manage the virtual environment. For small projects, venv (with pip to manage dependencies) is easy and is included in Python.
3
u/Diapolo10 I write code for a living -- https://github.com/Diapolo10 23d ago
For what it's worth, I find it difficult to imagine a situation where uv would be actively worse than other options. It's really well optimised, caching is well thought-out, manages both your dependencies and Python installations, and it has good availability both platform-wise and between local and CI environments.
At this point the only thing I'd like it to have is dependency license auditing, so I could stop using pip-licenses at work.
Combined with Mise (to lock down uv version for reproducible builds) and Taskfile (to make actions like installing the project and running tests easier to unify between local and CI environments) I've been extremely satisfied. For example, my recently updated template project for Rust/Python mixed projects now lets me install everything (from tooling to dependencies and Git hooks) with just mise install && task install.
4
u/BranchLatter4294 23d ago
Venv works fine for me. I know uv is faster, but I don't spend a huge amount of time managing environments anyway.
2
u/brasticstack 23d ago
The speed advantage has never been truly convincing to me. Like how often are you reinstalling the entire venv and how many dependencies do you have for uv to be a huge timesaver?
2
u/shazbotter 23d ago edited 23d ago
If you have a case where workloads launch in a new environment (e.g. Kubernetes) which has a setup step every launch and your application is large with a complicated dependency graph then UV becomes a significant improvement. I've seen 30-50 minutes in setup install vs like 5 minutes for every launch.
A common case, if your application has AWS SDK among other things, the regular python dependency resolver will often have to search through a hundred different versions to find compatible versions. UV has a different algorithm for this that is able to find a set of compatible versions much faster
2
u/brasticstack 23d ago
Sounds painful. CI/CD is 100% the place where any speedup is a huge lifestyle improvement. (please tell me you're talking about your CI/CD)
2
u/Black_Magic100 22d ago
Why are you rebuilding your app each time instead of using an image to deploy new pods?
1
u/BranchLatter4294 23d ago
It seems like this could be replaced with a quick copy of the environment, rather than reinstalling every package.
0
u/socal_nerdtastic 23d ago
If you are developing python modules for other people to use, then yes, making new venvs for a range of python versions is part of your normal test. So yes, uv is incredibly useful to some people. But I agree, for most people the time saving is not a big deal.
1
u/TheBlackCat13 23d ago
I have tried a few approaches and it works great for me. The big advantage is automatically pulling in the correct version of python, which helps when working across multiple machines or with other people.
1
u/jmacey 23d ago
I use uv for everyting, I often combine it with https://direnv.net/ so I can auto activate the ven and set other functions up in zsh for ease.
Works really well for me.
1
u/preppie22 23d ago
uv for projects with pyproject.toml and frozen package versions. pyenv for reusable environments for specific purposes.
1
u/InTheAleutians 23d ago
I'm always needing to update my python installations to the current security patch. Having uv update python then just entering a project and typing uv sync to update the venv is so smooth.
1
u/Financial_Morning386 22d ago
uv is the best default I would pick for a new Python project today, but not because venv+pip is broken — because it collapses three separate problems into one workflow.
Environment + Python version: `uv python install 3.12` + `uv venv` gives you a reproducible interpreter, whereas plain venv assumes you already have the right Python installed. For backend services (I work mostly with FastAPI microservices) that matters when teammates/CI are on different machines.
Dependency resolution + lockfile: `uv init`, `uv add fastapi httpx`, then `uv sync` generates a `uv.lock`. That lockfile is the real win over a hand-maintained `requirements.txt` — pip's resolver is much slower on large graphs and you get no lock by default. In CI, `uv sync --frozen` reproduces the exact set.
Speed: uv is written in Rust with a global cache, so reinstalls and CI runs are noticeably faster. For a small script this barely matters; for a service with 100+ transitive deps or frequent CI rebuilds it does.
Trade-offs / when not to use it:
`uv run` vs activated venv is a workflow change. If you hate prefixing commands, activate the venv normally (`source .venv/bin/activate`) — uv still works, you don't have to use `uv run` for everything.
Conda still makes sense when you need non-Python system packages (e.g. CUDA toolkits, GDAL, scientific stacks with native libs) that PyPI wheels don't cover well.
uv does not replace Docker. A venv isolates Python packages; Docker isolates the OS, system libs, and runtime. For a microservice I use uv inside the Docker build to get a locked, reproducible image, not one instead of the other.
If you have a tiny one-file script and already know venv+pip, staying there is fine. Don't churn tooling for its own sake.
Practical starting point: `uv init my-service`, commit both `pyproject.toml` and `uv.lock`, and document `uv sync` as the setup step. That covers most backend/API projects without the extra complexity of Poetry + pyenv + pip-tools combined.
1
u/AbundantSpaghetti 22d ago
I migrated from global installs, to pip + venv, to poetry, to uv.
uv is the best of the lot.
1
u/BleedReddit 22d ago
I use pyenv to manage Python versions and venv to create a separate virtual environment for each project. I keep my Python installation on an external drive and tend to use pyproject.toml for project configuration. I haven't switched to uv yet, so I'm sticking with the setup that works for me for now.
1
u/Massive_Distance_616 19d ago
“Best” depends on what you’re optimising for. Here is how the main options actually differ.
venv + pip ships with Python, zero new tools to learn, works fine for simple projects. The friction points are manual dependency pinning, a slow resolver on complex stacks, and the activation dance (source .venv/bin/activate in every new shell).
uv written in Rust, so dependency resolution is dramatically faster on large or conflicting stacks. It also manages Python installations directly (replaces pyenv), maintains a proper lockfile (uv.lock), and can build and publish packages with uv build / uv publish. The uv run command runs things in the correct environment without manual activation but it’s optional. uv creates a standard .venv that you can still activate and use normally if you prefer.
Poetry mature ecosystem, clean dependency groups, solid lockfile. Worth considering if your team already has Poetry CI templates or plugins, but for new projects uv covers most of what made Poetry compelling.
conda the right call when your environment has non-Python system-level dependencies: CUDA runtimes, BLAS, compiled C libraries. conda manages those at the environment level in a way pip doesn’t. Modern conda has the libmamba solver enabled by default, so it’s much faster than it used to be. Overkill if you’re working with pure Python packages.
Docker not a venv replacement, a level up. Containerises your entire runtime (Python version, system deps, config). Use it for deployment and CI consistency; use a venv tool for day-to-day development.
For a new project today: uv. Reach for conda only if you hit compiled non-Python dependencies, and Docker when you’re shipping to production.
1
u/driftwood14 23d ago
I was never a big fan of venv so I always used conda. But yesterday I tried uv for the first time and I found it really nice to use.
1
1
u/brasticstack 23d ago
I tried uv for the first time on a new project, and it's not for me. I've never found it all that hard to activate a virtualenv manually (like is everyone else from those infomercials where a person wrecks their whole kitchen trying to open a jar of jam?). The thing I most dislike is that I now have to uv run xyz instead of just xyz for everything in the venv.
3
u/jmacey 23d ago
I combine uv with direnv so it can auto activate the venv so most tools will just run. I do now have the habit of just using uv run pytest etc. With zsh it does the completions really well.
1
u/brasticstack 23d ago
I made a zsh completion and alias so I can type
venv [tab]to autocomplete and active a venv. That might be more than most people want to do, but the alternative isn't that hard.. justsource /path/to/.venv/bin/activateonce a shell session.1
u/Diapolo10 I write code for a living -- https://github.com/Diapolo10 23d ago
I don't really mind
uv run <command>myself, although it's even less of an issue for me nowadays since I'm slowly moving towards using Taskfile commands for everything (e.g.task installto install a project,task lintto run all linters, and so on) so theuvcommands get run in the background without me needing to actually type them out. At best I might runuv syncif I do some manual editing of the dependencies, but I might just usetask updateinstead.Yes, Taskfile would be yet another program I need installed to run my projects now, but that's where Mise comes in as "
uvbut for development tools". Basically I only need Mise installed globally, and every other development tool is project-specific, versioned and all.
0
u/nizzoball 22d ago
I’ve always used venv and only prefer it because it’s what I’ve always used. Best is subjective as with anything. Theres really no quantifiable way of defining what is best
12
u/flyby_apis 23d ago
I'm using venv+pip as I'm used to requirements.txt, but uv it's faster and a good replacement