How to Create a Python Virtual Environment with virtualenv

15 minute read     Updated:

Michael Nyamande %
Michael Nyamande

Managing dependencies for multiple projects is a common challenge for developers, particularly in Python, where all dependencies are installed globally by default. Imagine working on multiple projects, each requiring different versions of the same library or even different versions of Python. If not properly isolated, these dependencies may clash, causing various problems and wasting valuable project time debugging the issues.

Thankfully, virtual environments can help. Virtual environments allow you to create dedicated environments for your projects, ensuring that each project has its own set of isolated dependencies that don’t interfere with other projects.

In this article, you’ll learn about Python virtual environments and why they’re important. You’ll also learn how to create and manage virtual environments using virtualenv.

What Is a Virtual Environment?


In Python, a virtual environment is an isolated environment that allows you to install and manage packages independently from the global Python installation. This isolation is beneficial for several reasons, as you can:

  • Avoid dependency conflicts: Different projects can depend on different versions of the same package. For example, one project might require Flask 3.0, while another needs Flask 2.0. Virtual environments ensure that each project uses the correct version of its dependencies without affecting others.
  • Reproduce environments: By isolating dependencies, you can ensure that your project will run the same way on any machine, as long as the virtual environment is recreated properly. This makes it easier to collaborate on projects since you can easily share your environment with teammates.
  • Use different Python versions: You can use virtual environments to work with multiple Python versions on the same machine. This is especially useful for testing code compatibility.
  • More easily test and debug: With virtual environments, you can quickly switch between different environments to test how your code behaves with different sets of dependencies or configurations. For example, when your favorite web framework releases a new version, you can easily create a new environment to test for breaking changes before upgrading.

Virtual Environments Using virtualenv

While there are multiple tools available for setting up virtual environments in Python, such as venv, Poetry, and conda, virtualenv is a popular choice due to its simplicity, effectiveness, and ability to work seamlessly with older versions of Python. It offers key benefits like dependency isolation (ensuring that each project has its own set of dependencies), reproducibility across different machines, and the ability to manage multiple Python versions.

Let’s learn how you can use virtualenv to manage your Python project dependencies.

Installing virtualenv and Creating a Project

The first thing you need to do is install virtualenv. Since virtualenv is available as a Python package, you can install it using pip:

pip install virtualenv

Once you’ve installed virtualenv, you need to create a directory for your new project using the following commands:

mkdir my_project
cd my_project

This directory serves as the root for your project’s files and virtual environment. This step is optional but recommended for better organization.

Creating a Virtual Environment

To create a virtual environment with virtualenv, run the following command inside your project directory:

virtualenv venv

Here, venv is the name of your virtual environment folder. You can name it anything you like, but venv is a common convention.

This step sets up a directory structure that contains its own Python interpreter and a site-packages directory where all the dependencies for your project will be installed. This keeps your project’s dependencies isolated from other projects.

At times, you may need to create a virtual environment with a specific version of Python. Thankfully, virtualenv allows you to specify which Python interpreter to use. For instance, if you have multiple versions of Python installed, you can select the desired one using -p or --python, followed by the path to the Python executable.

To create a virtual environment with Python 3.11, use the following command and specify the path to the version of Python you want to use:

virtualenv -p /path/to/python3.11 venv

Or, if the python3.11 executable is in your system’s PATH, you can simplify it like this:

virtualenv -p python3.11 venv

This command tells virtualenv to use Python 3.11 to create the virtual environment. The resulting environment has its own Python 3.11 interpreter, along with a separate site-packages directory. If you want to learn about other CLI options for virtualenv, check out the documentation.

Activating Your Virtual Environment

Once you’ve created a virtual environment, you need to activate it. Activating the virtual environment modifies your shell’s environment variables to use the Python interpreter and libraries from the virtual environment. This ensures that any packages you install and any scripts you run use the isolated environment.

To activate your environment on Windows, use the following command:


On macOS and Linux, use the following:

source venv/bin/activate

After activation, your command prompt will change to indicate that the virtual environment is active, typically by showing the name of the environment in parentheses, like this: (venv).

Installing Packages in a Virtual Environment

With the virtual environment active, you can install packages using pip, just as you would globally. For example, the following command shows you how to install Flask, a popular web framework:

pip install flask

You can specify a particular version in the install command using the syntax pip install package==version. For example, the following command installs version 2.2.5 of Flask:

pip install flask==2.2.5

This command installs the Flask library within the virtual environment, making it available for your project without affecting the global Python installation.

Managing and Removing Packages

Managing packages in a virtual environment is crucial for maintaining project consistency. One helpful practice is to use a requirements.txt file to keep track of your project’s dependencies. You can create this file by running the following:

pip freeze > requirements.txt

This command lists all installed packages and their versions, saving them to requirements.txt. To recreate the environment on another machine or after deleting the environment, you can use the following:

pip install -r requirements.txt

This ensures that the exact versions of the dependencies are installed, making your project environment reproducible.

When you’re done with development and want to stop using the virtual environment, you can deactivate it to restore your shell to its global settings. If you no longer need the environment, you can deactivate it and delete the environment folder. This can be helpful to free up space if you’re working on a big project with multiple environments.

To deactivate an environment, you can use the following command:


To delete the environment folder, use the following command:

rm -rf venv

This removes the virtual environment and all the packages installed within it.

Limitations of virtualenv


While virtualenv is a powerful tool, it has some limitations:

  • System-level dependencies: virtualenv only isolates Python packages. It does not handle setting up system-level dependencies that some Python packages require. For example, packages like libpng or libfreetype, used in the Matplotlib library, require certain dependencies to be installed separately on the system.
  • Reproducibility across different platforms: virtualenv does not guarantee reproducibility across different operating systems and hardware platforms. It only simplifies environment reproducibility when you’re not dealing with system- or platform-specific dependencies.
  • Integration with CI/CD pipelines: While virtualenv is great for working locally, it fails to seamlessly integrate with CI/CD pipelines. Ensuring the CI/CD environment matches the local development setup requires additional configuration and management.

Earthly is a CI/CD framework that allows you to build, test, and deploy your projects consistently across different environments. It excels at sandboxing system-level dependencies, ensuring your projects can run anywhere without the typical “it works on my machine” issues. By leveraging Earthly, you can overcome the limitations of virtualenv to ensure that both Python and system-level dependencies are managed efficiently, leading to more stable and reproducible builds.

Here’s how Earthly works:

  • It defines dependencies in an Earthfile: Earthly allows you to define all your dependencies, including system-level ones, in an Earthfile. This ensures a consistent setup across different machines.
  • It builds consistent environments: Earthly uses containerization to build environments, ensuring all dependencies are properly isolated and consistent.
  • It integrates with CI/CD pipelines: Earthly integrates seamlessly with CI/CD pipelines, allowing you to automate your workflows and run your builds, tests, and deployments in a consistent environment. This integration ensures that your application behaves the same throughout the development lifecycle.

The following is an example of an Earthfile for a Flask web app project. This setup installs both system-level and Python dependencies:

# Use a specific Python version
FROM python:3.8

# Install system-level dependencies
    RUN apt-get update && apt-get install -y libpq-dev

    # Install Python packages
    COPY requirements.txt .
    RUN pip install -r requirements.txt

    # Copy the project files
    COPY . .

# Run unit tests
    FROM +deps
    RUN python -m unittest discover

# Build the target and start the application
  ENTRYPOINT ["flask", "run", "--host=", "--port=3000"]
  SAVE IMAGE my-python-app:latest

For more details on using Earthly with Python, check out this Earthly blog post.


In this article, you learned how to create and manage Python virtual environments using virtualenv. Virtual environments are essential for maintaining clean and conflict-free project dependencies, and virtualenv makes this process straightforward. You also explored some limitations of virtualenv and how Earthly can help manage system-level dependencies and create reproducible environments.

By mastering these tools, you can ensure that your Python projects are well organized and free from dependency conflicts, allowing you to focus on what matters most: writing great code.

Earthly Cloud: Consistent, Fast Builds, Any CI
Consistent, repeatable builds across all environments. Advanced caching for faster builds. Easy integration with any CI. 6,000 build minutes per month included.

Get Started Free

Michael Nyamande %
Michael Nyamande
A digital product manager by day, Michael is a tech enthusiast who is always tinkering with different technologies. His interests include web and mobile frameworks, NoCode development, and blockchain development.


Get notified about new articles!
We won't send you spam. Unsubscribe at any time.