Environment and dependency management in Python

Software
Environments
Dependencies
Python
conda
venv
virtualenv
pyproject.toml
uv
Last reviewed

February 14, 2025

Last modified

September 19, 2025

When working with Python, managing dependencies and environments is important to ensure your project can be reproduced and shared.

Note Definitions:

A dependency is any external library your project needs, and a virtual environment is an isolated workspace where dependencies are installed.

There are several ways to manage dependencies and environments:

Conda Environments

Conda is a package and environment manager popular in the research and data science community. It allows you to manage both Python and non-Python dependencies.

Basic commands

# Create a new environment, e.g. with python 3.12
conda create -n your_env_name python=3.12

# List all environments
conda env list

# Activate an environment
conda activate your_env_name

# Install packages in an environment
conda install package_name

# Remove a package
conda remove package_name

# Export an environment to a file
conda env export > environment.yml

# Deactivate an environment
conda deactivate

# Remove an environment
conda env remove -n your_env_name

Conda environment files

Conda environment files (environment.yml) are used to specify the dependencies of a project. They can be used to create an environment from scratch, or to update an existing environment.

# Export an environment to a file
conda env export > environment.yml

# Create an environment from a file
conda env create -f environment.yml

# Update an environment from a file
conda env update -f environment.yml

Virtual Environments (venv/virtualenv)

Python provides venv as a built-in tool for creating virtual environments. virtualenv is a third-party tool that provides similar functionality.

Basic commands

# Creating a virtual environment
# Using venv (Python 3.3+ built-in)
python -m venv your-env-name

# Using virtualenv (must be installed first)
pip install virtualenv
virtualenv your-env-name

#Activating the environment
# Linux/macOS
source your-env-name/bin/activate
# Windows
your-env-name\Scripts\activate

# Installing a library (package)
pip install lib_name

# Uninstalling a library (package)
pip uninstall lib_name

# To deactivate
deactivate

Managing dependencies with pip

A requirements.txt file lists all dependencies with their specific versions.

# Export requirements.txt from an activated environment
pip freeze > requirements.txt

# Install dependencies from requirements.txt
pip install -r requirements.txt
Tip Tip

Use pip-chill or pipreqs instead of pip freeze to exclude unnecessary dependencies. pip-chill lists only packages you installed, while pipreqs lists packages your code actually uses.

Dependency Management Tools

Consider using tools that offer more sophisticated dependency management by integrating virtual environment creation and dependency resolution. They maintain a project manifest (e.g., pyproject.toml for Poetry) that specifies primary dependencies and generate lockfiles to pin exact versions for reproducibility.

  • Pipenv: Combines pip and virtualenv into a single tool, with a focus on simplicity and ease of use.
  • Poetry: Manages dependencies, environments, and package building in a streamlined way.
  • Pixi: A new tool that aims to provide a more user-friendly experience for managing Python environments and dependencies.

Using uv for environments and dependencies

Besides the aforementioned tools, uv is becoming increasingly adopted because it provides fast, reproducible Python dependency management built around pyproject.toml and a lockfile (uv.lock), and can create and manage virtual environments as well as download and select Python versions.

In practice, uv can replace pip, and often virtualenv, while also covering much of what tools like Poetry are used for but with a clearer separation of responsibilities.

Tip uv excels at Python-level dependencies
  • uv does not replace system or distribution-level package managers (such as conda, apt, or brew)
  • It is best suited for managing Python-level dependencies on top of an existing Python interpreter
  • The Python interpreter can come from the system, a virtual environment, or a conda environment

Getting started with uv

uv manages Python dependencies, not your operating system or system libraries. Before starting, decide where your Python interpreter comes from in your project:

  1. Use venv + uv. Use this when all dependencies are available from PyPI wheels
  • Create a new project
mkdir my_project
cd my_project
uv init
  • Create a virtual environment
uv venv --python 3.12 --seed

Now you should have a .venv/ directory and pip installed into it

  • Add dependencies
uv add numpy pandas

The command above will update the pyproject.toml file, install packages into .venv, and create a lockfile uv.lock

  • Run commands inside the environment
uv run python script.py
uv run pytest

Activating the virtual environment is optional, since the commands with uv are by default run inside the environment.

source .venv/bin/activate
  1. Use conda + uv. Use this when you need non-Python libraries managed by conda
  • Create and activate a conda environment
conda create -n myenv python=3.12
conda activate myenv
  • Install uv into the conda environment (unless you already have uv installed system-wide)
conda install -c conda-forge uv
  • Initialize the project
uv init
  • Add dependencies
uv add numpy pandas

This time, packages will be installed into the active conda environment

  • Recreate the environment later
uv sync

This installs exactly what is declared in pyproject.toml and uv.lock

Tip Some useful commands to make the most out of uv
  • uv add --dev <package>: add a development dependency
  • uv pip list: list installed Python packages
  • uv pip tree: show dependency tree
  • uv run <command>: run a command in the environment

What if you already have a requirements.txt file?

  • You can migrate your project to uv in a straightforward manner so that pyproject.toml and uv.lock become the core pieces for reproducing your environment
# Initialize uv
uv init

# Add everything from requirements.txt
uv add -r requirements.txt
  • After running the above commands, you should have a pyproject.toml file with the dependencies, where the versions are resolved and everything is installed into the environment
  • With your uv.lock file, the requirements.txt file becomes obsolete. You can still keep it around for reference, but ideally you stop updating it manually
Note Learn more