Skip to content

virtual environments

When you work on many Python projects, you’ll quickly run into conflicting dependency versions if you install everything globally (system-wide) with pip or a similar tool.

Virtual environments solve this problem by allowing you to give each project its own isolated environment with a specific set of packages, separate from your system Python. The standard library includes the venv module for creating these environments.

Beyond preventing version conflicts, virtual environments make your projects easier to onboard, test, and run consistently because everyone starts from the same baseline: an isolated environment you can create and recreate on demand.

Here’s a summary of best practices that you can apply:

  • Use a dedicated virtual environment for each project. Create and activate a separate environment for each project, rather than installing packages globally. This practice prevents dependencies from different projects from interfering with one another.
  • Follow common naming patterns. Name the environment directory .venv/ and keep it in your project root. The leading dot keeps the directory out of the way and avoids clashing with the .env files that some tooling reads, and it’s the name that tools like uv create and look for automatically. The plain venv/ spelling is still common, but .venv/ is the safer default.
  • Install packages into an active environment. Make sure you activate the appropriate environment before you install any package. This will prevent you from accidentally installing packages into the wrong environment.
  • Treat environments as disposable. Don’t try to fix a broken environment by poking around inside it. Instead, delete it and create a fresh one.
  • Keep the environment out of version control. Never commit the environment directory. Commit your dependency declarations instead, and let each contributor recreate the environment from those. Since Python 3.13, venv writes a .gitignore into the new environment for you, so Git skips it by default.

To see how these practices play out, check out a fragile setup that installs everything globally:

🔴 Avoid this:

Language: Shell
$ pip install requests flask
$ pip install "numpy<1.20"

$ # Months later, on the same machine, another project
$ pip install "numpy==2.0"

In this example, all your projects share the same global environment. Upgrading a package can silently break other projects. Additionally, you have no reliable way to re-create or reproduce the environment on another machine. In this scenario, you’re likely to encounter the it works on my machine issue. On many modern systems, that global install won’t even get that far. Distro- and Homebrew-supplied Pythons mark their installation as externally managed (PEP 668), so pip install refuses to touch the system interpreter and tells you to create a virtual environment instead.

Here’s a more robust approach that creates a dedicated environment for the project:

Favor this:

Language: Shell
$ # Create a project-specific environment
$ cd project/
$ python -m venv venv/

$ # Activate it
$ source venv/bin/activate

$ # Install packages into the active environment
(venv) $ python -m pip install requests flask

$ # When you're done, deactivate it
(venv) $ deactivate

With this approach, each project uses its own isolated environment. That isolation prevents cross-project conflicts and makes it easy to recreate the environment when something goes wrong.

Python Virtual Environments (venv)

Tutorial

Python Virtual Environments: A Primer

Create isolated project setups on all platforms, and gain a deep understanding of Python's virtual environments created with the venv module.

intermediate devops tools

For additional information on related topics, take a look at the following resources:


By Leodanis Pozo Ramos • Updated Aug. 20, 2026 • Reviewed by Martin Breuss