UV vs Pyenv for Managing Python Development - Part 2

2026/02/03

The past few weeks I’ve been using UV more extensively. I started by completely removing Pyenv from my work laptop so I would be forced to learn the ins and outs of UV for day to day use. I wrote something in Part 1 of this series ov UV vs Pyenv, that inadevertenly being true, but not in the sense I had originally intended. In part 1, I wrote:

UV defaults to creating a development environment called venv and appears biased towards wanting to use that one. This could be my lack of experience using it widely so far, and I’ll chalk it up to that so far. Reading between the lines of the documentation seemed more bent towards just using venv as a single Python environment.

When you’re developing with Python, usually you have more than one virtual environment and want to be able to switch between them seamlessly. You also tend to want to name the virtual env to reflect what project it contains for easy reference.

Both of these statements are true… but I realized the way I’ve used virtual environments in the past and the way that made sense to use for my team has been different than standard practice for most Python software development. After digging thru a myriad of online Python tutorials and open source codebases, the following point finally clicked for me: for most Python projects, you checkout your repo, and create/use a “venv” or “.venv” folder in the project repo itself for your virtual environment. This is why venv and .venv global paths are part of almost every popular Python open-source project’s .gitignore that I could find. I simultaneously felt vindicated and a strong urge to facepalm. In this context, what I perceived as UV’s opinionated insistence on using venv as a default virtual environment location made sense to the vast majority of Python users who want to utilize UV to replace Pyenv or whatever other tool they’re using to manage their Python development environment.

To provide a clearer picture of why this behaviour on UV’s part struck me as so odd, I have to delve back a little ways into how I started using Python virtual environments and how the team at my day job use them on a daily basis. When I first started programming as a professional necessity, I was already well into my techincal career. I’d worked in the DevOps & infrastructure world and most of my needs were met by shell scripts and the occasional modification of existing Python code. Usually I’d just use whatever system version of Python I had installed, install the appropriate Python packages globally and if need be, uninstall them after. Once in the data world, Python became the bread and butter of my craft. Like most overzealous newbies, I tried to create a virtual environments for every little thing I did. I ended up with dozens of virtual environments, all with names of projects I half coded up and then never touched again. For ease of use, I always named my virtual environments after what I was working on and left them scattered about in various home directory or desktop locations. Thus the habit of naming virtual environments after the project I was working on stuck. For instance, when working with DBT models at work, my virtual environment is called dbt. The team I’m on consists of 5 full time IC’s, 3 of whom are analytics engineers. While all of them possess formidable technical skills, Python development environments aren’t their forte, and so my data engineering counterpart and I decided to make things as clear and simple as possible: to name their virtual environment dbt. Combined with Pyenv’s virtulenv plugin that makes creating, listing, and activating Python virtual environments easy from whatever directory you run it from, it makes the lives of the entire team much easier and removes the need for debugging basic development tooling on an ongoing basis. A simple pyenv activate dbt, and no matter where you are on your system, you’re in the named DBT virtual environment.

At this point, I actually really like both tools, and think Pyenv will likely be the right choice for the analytics engineers on my team. I’ve personally loved using UV and will continue to do so for the forseeable future. The next part of this series will highlight how I’ve adapted from Pyenv to using UV for my day to day workflows and its use in improving the performance of some of the CI/CD pipelines in our data environment.