pip and conda are both package managers for Python, but they operate on fundamentally different principles, leading to distinct strengths and weaknesses.

Imagine you’re building a complex Python application. You need specific libraries, say numpy and pandas, and maybe an older version of tensorflow for a legacy project.

Here’s what pip does:

import subprocess

# Install a package
subprocess.run(["pip", "install", "numpy"], check=True)

# Install a specific version
subprocess.run(["pip", "install", "tensorflow==1.15.0"], check=True)

# Uninstall a package
subprocess.run(["pip", "uninstall", "pandas", "-y"], check=True)

pip is the standard Python package installer. It downloads packages from the Python Package Index (PyPI) and installs them into your Python environment. It’s excellent at managing Python packages and their dependencies within a single Python installation. However, it primarily deals with Python code and doesn’t inherently understand or manage non-Python dependencies (like C libraries, compilers, or system-level tools). This is where it can get tricky.

Now, consider conda:

import subprocess

# Create a new environment with Python 3.8 and specific packages
subprocess.run([
    "conda", "create", "-n", "myenv", "python=3.8", "numpy", "pandas", "tensorflow=1.15.0", "-y"
], check=True)

# Activate the environment
# On Linux/macOS:
# subprocess.run(["source", "myenv/bin/activate"], shell=True, check=True)
# On Windows:
# subprocess.run(["conda", "activate", "myenv"], check=True)

# Install a package into the active environment
subprocess.run(["conda", "install", "scipy"], check=True)

# Deactivate the environment
subprocess.run(["conda", "deactivate"], check=True)

conda is a cross-platform package and environment manager. It’s not just for Python; it can install and manage packages written in any language. Crucially, conda environments are isolated from each other and from your system’s Python installation. This means you can have multiple Python versions and different sets of packages installed on the same machine without conflicts. conda also handles non-Python dependencies seamlessly. If a Python package requires a specific C library, conda will install that library too. This is its superpower.

The core problem conda solves is dependency hell, especially when dealing with complex scientific computing stacks or when you need to manage different Python versions. pip, while powerful for Python packages, relies on your system having the necessary build tools and libraries already in place, or it can’t resolve dependencies that aren’t pure Python.

Let’s look at a common scenario: installing numpy with a specific BLAS/LAPACK implementation. pip will try to compile numpy against whatever BLAS/LAPACK it finds on your system. If it’s not compatible or missing, you’ll get cryptic compilation errors. conda, on the other hand, will install a numpy package that’s pre-compiled against known-good, compatible versions of BLAS/LAPACK (like OpenBLAS or MKL) that it manages itself.

Here’s a concrete example of conda’s power: suppose you need Python 2.7 for an old project and Python 3.9 for a new one.

With pip, this is a nightmare. You’d have to install one Python version system-wide and then try to manage the other, likely leading to path conflicts and broken installations.

With conda, it’s trivial:

conda create -n py27 python=2.7 anaconda  # Installs Python 2.7 and common scientific packages
conda create -n py39 python=3.9 pandas numpy scipy

You then simply conda activate py27 or conda activate py39 to switch between completely independent environments.

The mental model to build is that pip manages packages within a Python interpreter, while conda manages both interpreters and packages (Python and non-Python) in isolated environments. conda environments are self-contained universes.

The single most important piece of information most people miss is that conda can install pip itself into any of its environments. This means you can leverage conda for environment and non-Python dependency management and then use pip for any packages that might only be available on PyPI. To do this, you’d first create your conda environment, activate it, and then run pip install <package_name>. This hybrid approach is incredibly robust.

The next concept you’ll likely grapple with is how to manage conda environments across different machines or share them with collaborators.

Want structured learning?

Take the full Pip course →