If your project only needs Python packages, use pip inside a virtual environment. Reach for conda the moment something non-Python shows up: a GPU runtime, a BLAS library, a geospatial toolchain, a C library, or a whole compiler. That single question settles most of the pip vs conda which to use debate in about ten seconds.
Everything after that is detail, and the detail matters more than people expect, because the wrong choice costs you an afternoon of “works on my machine” debugging. I have watched a working data pipeline break because someone upgraded NumPy with pip in an environment that conda had pinned to a different build.
Last updated: October 2026
Table of Contents
- pip vs conda which to use at a Glance
- What Is pip?
- What Is conda?
- Package Management and Dependency Resolution
- Environment Management
- Python, Data Science, and System Dependencies
- Which Tool Is Better for Common Workflows?
- Can you use pip inside a conda environment?
- When pip and conda fight each other
- Why conda installs feel faster
- How to Choose Between pip and conda
- pip vs conda which to use for Your Python Project
- Frequently Asked Questions
- Does pip install work in a conda environment?
- Is it better to use conda or pip?
- Is there something better than conda?
- What is the difference between conda-forge and conda?
- Is conda forge still free?
- Is pip always installed with Python?
pip vs conda which to use at a Glance

Here is the whole comparison on one screen. Read the “best for” row first, then check the one or two rows that could actually change your answer.
| Criterion | pip | conda |
|---|---|---|
| What it installs | Python packages only, into an interpreter you already have | Python packages, other languages, and system libraries, plus the interpreter itself |
| Where packages come from | PyPI, plus private indexes you configure | Channels such as conda-forge, the defaults channel, and bioconda |
| Needs a compiler | Yes, whenever no matching wheel exists for your platform and Python version | No, packages ship as pre-compiled binaries |
| Languages covered | Python only | Python, R, C, C++, Fortran, Java, Node, and system executables |
| Creates environments | No, you use venv or virtualenv first | Yes, environment creation is built in |
| Dependency solving | Incremental resolver that walks requirements one at a time | Global solve across the whole environment with a SAT solver (libmamba) |
| Non-Python dependencies | You handle them yourself, usually through a system package manager or a Docker base image | Handles them, including CUDA toolkits, MPI, ffmpeg, and compilers |
| Uninstall behaviour | Removes the package it knows about, orphans are common | Tracks everything in conda-meta, clean removal of full dependency trees |
| Best for | Web apps, APIs, automation, library authoring, Docker images | Data science, ML, bioinformatics, HPC, cross-language stacks |
| Main drawback | Can leave an environment subtly broken with no clear error | Heavier, slower to solve, and confusing folder layout for newcomers |
If one of those rows points at conda and the rest point at pip, you have your answer. The interesting cases are the mixed ones, which come later.
What Is pip?
pip is the installer maintained by the Python Packaging Authority, the same group that maintains the rest of Python’s standard packaging tools. It downloads from PyPI, the public index of Python packages, and puts the files into a Python interpreter that is already on your machine.
Two kinds of downloads matter. A wheel is a pre-built binary archive, tagged with the platform, architecture, and Python version it was built for, and installing one is a file copy with no compilation. A source distribution, or sdist, is the package author’s Python source, and pip has to build it on your machine, which means a working compiler, headers, and a few minutes per package.
That fallback is the single most important thing to understand about pip. If a wheel exists for your combination, install is fast and boring. If it does not, pip will try to compile, and that is where a two-minute install turns into a two-hour debugging session with a compiler error about a missing header.
You pin what you installed in a text file, and anyone can rebuild the same set:
pip install pandas==2.2.3
pip freeze > requirements.txt
pip install -r requirements.txt
pip does not create environments. That job belongs to venv, which ships with Python itself, or to virtualenv, which is older and works on versions that predate venv.
python3 -m venv .venv
source .venv/bin/activate
On Windows the activation line is .venvScriptsactivate instead.
There is one more modern wrinkle that trips up a lot of new users. Under PEP 668, a system Python is marked as externally managed, so a plain pip install into it fails with an externally-managed-environment error rather than quietly corrupting the OS. That is good behaviour, and the fix is to use a virtual environment. On Debian and Ubuntu you can also pass --break-system-packages, which you should think about twice before typing.
What Is conda?
conda is a package manager and an environment manager that operates outside Python. It ships pre-compiled binaries that bundle a package together with the non-Python libraries it needs, and it will install CPython itself rather than expecting one to exist first.
Packages come from channels. The defaults channel is maintained by Anaconda, conda-forge is the large community channel and the one most projects should use today, and bioconda covers bioinformatics tools. Channel priority is strict, so mixing channels without thinking about order is how you end up with a library built against a different version of a system library than the one next to it.
conda create -n analysis python=3.11
conda activate analysis
conda install -c conda-forge numpy pandas scipy
An environment is described in one file, which is where conda earns its keep for teams:
conda env create -f environment.yml
conda env export --from-history > environment.yml
conda list --explicit > linux-64.lock
That last line matters more than people expect. It writes every package with its exact URL and hash, so you can rebuild the identical environment later on a cluster or in CI without asking the solver to make the same choices again.
As for the installer itself, there are three common choices. Anaconda bundles conda, Python, and several hundred packages, which is convenient and heavy. Miniconda gives you conda and Python only, so you add what you actually need. micromamba is a single small static binary that uses the same libmamba solver with no installer UI at all, which makes it a good fit for containers and CI. On a Windows laptop, conda putting compilers and tools inside the environment is often the reason people stay with it at all.
Package Management and Dependency Resolution
This is the deepest technical difference, and it explains the confusing symptoms people report about the two tools fighting each other.
pip resolves incrementally. It walks the dependency graph, picks a version for each requirement as it reaches it, installs it, then continues. Newer pip versions backtrack when a choice turns out to be wrong, which is better than the old behaviour, but the solver still only knows about Python packages and only reasons about version numbers.
conda takes every constraint in the request and solves for the whole environment at once, using a SAT-based solver, libmamba in current versions. The solve includes virtual packages such as the system glibc version and the CPU’s instruction set, so it can refuse a combination that would technically resolve but would not run.
That global solve is slower on large environments, and users notice. It is also the reason conda environments tend to be coherent, and the reason pip environments sometimes are not.
The failure rarely arrives as a clean error. You get an import error deep inside a compiled extension, a numpy.core.multiarray failed to import that started after a routine upgrade, or a package that installs cleanly and then behaves oddly. A pip list shows one version of a library and conda list shows another, which is the exact confusion behind the most common forum question on this topic.
There is a straightforward diagnosis. Compare the two listings:
conda list
pip list --format=freeze
Anything both tools can install should be owned by conda. Anything only pip could install shows up in the pip listing. When the same library appears in both at different versions, the fix is to recreate the environment rather than try to untangle it in place.
Environment Management
pip and conda are often compared as if they were rivals, but they sit at different layers. conda manages environments and packages; pip installs packages into whatever environment is active. The fair comparison for most developers is venv plus pip against a conda environment.
A venv is a folder containing a bin directory, a lib directory, and a small pyvenv.cfg file pointing back at the base interpreter. Creating one takes a second and it contains almost nothing until you install into it. Activating it sets your PATH so the right python and python scripts resolve first. That is the whole trick, and it is easy to reason about once you know it.
A conda environment is a self-contained prefix with its own bin, lib, include, and share directories, its own interpreter, and a conda-meta folder recording exactly what was installed and from where. Activation sets a CONDA_PREFIX variable and runs activation scripts that some packages use. It does more work, and that is precisely why an environment can carry CUDA libraries or a Fortran runtime that a venv simply cannot.
Interpreter selection is a real difference too. With venv you pick the interpreter yourself and create the environment with it, so a project pinned to 3.11 is pinned through whichever Python you launch. With conda the interpreter is a solved dependency, so conda create -n app python=3.11 also brings a compatible pip and a compatible build of anything that cares about the ABI.
Portability is the next question. A venv is not portable: scripts inside it contain absolute paths, and a venv built on macOS will not work on Linux. Conda environments are relocatable within the same platform, and the explicit lock file gives you something rebuildable anywhere conda runs. For truly portable builds, teams still reach for Docker or Nix, and conda is usually the layer inside the container rather than a replacement for it.
For a team, the artefact that matters is the environment file. A requirements.txt is a list of packages; an environment.yml plus a generated lock file describes the whole environment including the interpreter and the non-Python pieces. If your onboarding problem is “works on my machine”, the second form solves more of it.
Python, Data Science, and System Dependencies
It used to be that pip could not install NumPy or SciPy without a compiler. That is no longer true for mainstream platforms, because projects publish manylinux wheels carrying their own pre-built binaries. For NumPy, SciPy, and pandas on Windows, macOS, or Linux, pip is genuinely fine.
The gap shows up elsewhere. Ask what the package actually needs beyond Python: a specific BLAS implementation, a CUDA runtime matching your driver, GDAL and PROJ for geospatial work, ffmpeg for media, graphviz for diagram rendering, an MPI implementation for a cluster, or a compiler because the project has no wheel at all.
Each of those is a separate system-level problem for a pip user, and the usual answers are a system package manager, a Docker base image, or a prebuilt wheel from somebody else. With conda they are all just packages in the same channel:
conda install -c conda-forge cudatoolkit mkl openmpi ffmpeg graphviz
Bioinformatics is the cleanest illustration. r/bioinformatics threads are strongly conda-positive, and the reason is not preference: tools like bwa, samtools, and GATK are distributed as binaries through bioconda for Windows and macOS, where a pip install means a source build or nothing at all.
For GPU work the logic is the same. A PyTorch install pulls a specific CUDA runtime, and matching that runtime to a driver is a solved problem for conda and a research project for pip on Linux. The honest summary is that modern wheels closed the gap for pure scientific Python and left it wide open for system software.
Which Tool Is Better for Common Workflows?
Here is the same comparison turned into a verdict per task, with the reasoning kept short enough to argue about in a code review.
| Workflow | Verdict | Why |
|---|---|---|
| Web apps and APIs | venv plus pip | Docker images and hosting platforms expect this, and nothing non-Python is needed |
| Scripts and automation | venv plus pip | Lightest setup, fewest files, easiest to run in CI |
| Library and package authoring | venv plus pip | Your users install from PyPI, so you should test exactly that path |
| Data science notebooks | Either, conda if the team already standardises on it | NumPy, pandas, and SciPy have wheels, so pip works; consistency matters more than capability |
| Deep learning on GPUs | conda, or a container plus pip | CUDA runtime matching is much easier to get right through a channel |
| Bioinformatics and geospatial | conda | Binaries exist in bioconda and conda-forge; pip offers a source build |
| Cross-language projects with R, C, or Java | conda | One environment file can describe the whole stack |
| HPC and clusters | conda with an explicit lock file | One module, one specification, rebuilt identically on every node |
Can you use pip inside a conda environment?
Yes, and most working conda environments contain both tools. What matters is the order. Install everything conda can provide with conda first, then use pip for whatever is left, and never run pip against a package conda already owns. Pip does not update the conda record of that package, so conda keeps believing the old version is installed and the next solve may quietly undo your work.
A workable pattern looks like this: create the environment, install the scientific and system packages with conda, then run one pip install for the rest, and record that last command in a text file in the repository. If the environment ever becomes inconsistent, throw it away and rebuild from the two files rather than debugging in place.
When pip and conda fight each other
The symptoms show up as import errors that appear after an unrelated install, mismatched versions in the two listings, and a conda solve that wants to “fix” packages you never touched. There is one more trap: pip uninstall inside a conda environment can remove shared files that other packages in the same environment still link against, and conda has no record of the removal, so it will not restore them.
Nothing here is a reason to avoid mixing. It is a reason to keep the ownership line clear: conda owns the system-level and compiled core, pip owns the long tail, and each package has exactly one owner.
Why conda installs feel faster
Mostly because conda downloads a binary built for your platform, while pip sometimes compiles from source. That is a real difference, though smaller than it used to be, because most popular Python projects now ship manylinux wheels and pip installs are close to a download and a copy. The gap is widest for large compiled stacks like PyTorch with CUDA, and narrowest for pure-Python packages where the download dominates either way.
How to Choose Between pip and conda
Five questions settle it, in this order. The first one that gets a yes decides the tool.
- Does the project need anything that is not a Python package? A compiler, a CUDA runtime, a BLAS library, a geospatial stack, ffmpeg, an MPI library, or a non-Python tool in the same environment. Yes means conda.
- Do wheels exist for everything on your platform and Python version? Check before you start. If the answer is no, or you cannot check, conda removes the guesswork.
- How does this ship? Docker images, serverless platforms, and most hosting providers assume venv plus pip. If deployment is the hard part, match it.
- What does the rest of the team already use? Consistency beats the technically superior option. A working convention is worth more than a better tool.
- Do you need one file to describe the whole environment? If yes, conda. A requirements.txt records packages, not the interpreter and the system libraries around them.
If every answer is no, use venv plus pip. That is the default for web work, and it is the smaller surface area.
pip vs conda which to use for Your Python Project
Category by category, here is what I would actually tell someone setting up today.
Web development, APIs, backend services: venv plus pip. The whole ecosystem is built this way, from local development to the production image, and you gain nothing by adding an environment manager on top.
Automation and internal scripts: venv plus pip. Small, fast, and the dependency list is short enough that drift rarely bites.
Data science on a laptop: either one works. Pick conda if your colleagues or your field already uses it, pick pip if you want the smaller footprint and the wheels are all there.
Scientific computing and reproducibility on a team: conda with an explicit lock file, or a container built from one. The file that rebuilds the environment identically is the deliverable that matters for published results.
GPU and deep learning: conda, or a container plus pip if your team already standardises on containers. The CUDA runtime is the deciding factor, not preference.
Bioinformatics, geospatial, R, or any cross-language work: conda without hesitation. The binaries exist; the pip path does not.
Publishing a library: test with pip in a venv, because that is how your users will install it. If a heavy dependency makes that impossible, ship conda instructions alongside the pip ones rather than choosing for everyone.
Frequently Asked Questions
Does pip install work in a conda environment?
Yes. Both tools belong to the same environment once conda has created it. The rule that keeps environments healthy is install order: use conda for every package a channel provides, then run pip once for whatever remains, and never pip-install over something conda already owns. Pip does not update the environment record, so conda keeps thinking the old version is installed.
Is it better to use conda or pip?
Use pip inside a virtual environment for pure Python work such as web apps, APIs, scripts, and library development. Use conda when a dependency is not a Python package, or when no matching wheel exists for your platform, which covers CUDA, BLAS, geospatial stacks, ffmpeg, MPI, compilers, and most bioinformatics tools.
Is there something better than conda?
For most Python projects, yes: venv plus pip, now joined by uv, a fast installer and resolver that works the same way and supports lockfiles. For system-level and cross-language dependencies, conda remains hard to replace because it installs binaries and non-Python software into one prefix. Many teams settle on both, with uv or pip inside a conda environment.
What is the difference between conda-forge and conda?
conda is the package and environment manager. conda-forge is one of the channels it installs from, a community-built and free collection with broad platform coverage. The defaults channel, maintained by Anaconda, is the other common source. For new projects, installing with -c conda-forge is the safer habit.
Is conda forge still free?
Yes, conda-forge is free to use, including commercially. The licensing question usually comes from Anaconda’s own defaults channel and its commercial terms, not from conda-forge. Teams that want to avoid those terms point their channels at conda-forge, or install micromamba and use that channel instead.
Is pip always installed with Python?
In most modern installations, yes: pip comes with CPython, and virtual environments created by venv include it. It can still be absent from a stripped-down system package or a container base image, in which case python -m ensurepip installs it. Under PEP 668 the system interpreter also refuses global installs, so a virtual environment is the path that works.
Start with venv plus pip and change nothing until a real non-Python dependency appears. When it does, recreate the project as a conda environment, put the compiled and system-level packages in conda’s hands, and let pip handle the long tail. That sequence keeps your first setup boring and your future debugging short.


