Virtual Environments

What are virtual environments

When you install a Python package with a simple pip install, it goes straight into your system’s global Python installation. Over time, as you work on more and more projects, this can lead to a tangled web of conflicting library versions: one project might need NumPy 1.22 while another requires NumPy 1.25, and upgrading or downgrading for one breaks the other. A virtual environment solves this by giving each project its own private copy of the Python interpreter and its own “site-packages” folder. In practice, this means that when you create a new environment, you end up with a directory (often named .venv) that contains everything that project needs — its own python executable, its own pip, and a clean slate of installed libraries — completely isolated from every other project on your machine.

Under the hood, Python’s built-in venv system simply copies (or on some operating systems, hard-links) the interpreter into your project folder and creates fresh lib and bin (or Scripts on Windows) subdirectories. When you “activate” the environment, your shell’s PATH is adjusted so that typing python or pip in that terminal session uses the environment’s private executables instead of the global ones. This guarantees that any library you install — be it Pandas, Matplotlib, or PyTorch — goes into the .venv folder and cannot affect other projects. When you’re finished, running deactivate restores your original settings, so you’re back to your system Python with everything else untouched.

For beginners, the beauty of a virtual environment is that it behaves exactly like normal Python once activated: you run scripts, launch Jupyter notebooks, or import libraries just as before. Yet under the surface, you know nothing you do will leak out to other projects, and nothing installed elsewhere will break your code. This makes experimentation safe — if you accidentally install the wrong version of a package, you can simply delete the .venv folder and start over without fear of collateral damage.

UV embraces virtual environments as a first-class concept: every project you initialize or synchronize with UV gets its own environment automatically. You never need to remember a separate set of commands or worry about mixing system and project dependencies. With UV managing the creation, activation hints, and isolation for you, virtual environments become an invisible safety net that keeps your projects clean, reproducible, and easy to share.

Creating and Managing the Virtual Environment

Once you have initialized your project with UV, the next step is to set up an isolated environment where your code and its dependencies can live without interfering with other projects on your system. A virtual environment is simply a self-contained folder that holds its own Python interpreter and library directory, so that when you install packages, they stay within that folder instead of being installed globally. UV makes creating and working with these environments remarkably straightforward.

To create the environment, navigate into your project directory and run:

uv venv create

By default, UV will place a folder named .venv at the root of your project. This folder contains a copy (or, when possible, a hardlink) of the Python interpreter you have selected, and its own bin (on macOS/Linux) or Scripts (on Windows) directory for executables. If you want to name your environment something else—for example, env—you can simply pass that name as an argument:

uv venv create env

Under the hood, UV checks whether the requested Python version is already available in its global cache. If not, it will download and install the correct interpreter automatically, sparing you from installing Python separately or juggling tools like Pyenv. Thanks to UV’s use of copy-on-write and hardlinking, creating a new virtual environment is fast and space-efficient, even if you already have several projects on your machine.

After the environment folder exists, you’ll need to “activate” it so that your shell knows to use the isolated Python and packages within. On macOS and Linux, activation is as simple as sourcing a script:

source .venv/bin/activate

On Windows PowerShell you’d run:

.\.venv\Scripts\Activate

Once activated, you’ll notice your prompt changes to include the environment name—usually (.venv)—and any call to python, pip, or installed command-line tools will reference the environment’s interpreter and libraries. This ensures that when you install NumPy, Pandas, or PyTorch, they go into this sandbox rather than your system Python.

When you’re done working in the environment, simply run:

(or, on Windows, the same deactivate command), and your shell will revert to the global Python interpreter. There’s no harm in leaving an environment active if you close the terminal afterwards—it simply resets automatically when the session ends.

UV also integrates environment management into its other commands. If you run uv pip install or uv sync without an active environment, UV will prompt you to create or activate one first, preventing accidental installations outside your project. And if you ever need to remove the environment, you can safely delete the .venv folder (or whatever name you chose) and recreate it with uv venv create. This flexibility makes it easy for beginners to experiment, reset, and maintain clean, reproducible project setups.

Check the Python version of your virtual environment

Now that we have created our virtual environment we can check which Python version is available within the environment by just running:

Remember each virtual environment can have its own version of Python running. This makes it very easy to handle multiple Python projects on the same machine that have different requirements.

Last updated