conda
pip3
package management
Python
requirements.txt

From conda create requirements.txt for pip3

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Moving between conda and pip environments is a common need when deploying applications or collaborating with developers who do not use Anaconda. Conda tracks packages from its own channels alongside pip-installed packages, and exporting that environment into a pip-compatible requirements.txt requires careful handling. This article covers several approaches, from quick one-liners to more robust filtering strategies.

Using pip freeze Inside a Conda Environment

The simplest method is activating the conda environment and running pip freeze. This outputs every pip-visible package in the standard package==version format.

bash
conda activate myenv
pip freeze > requirements.txt

The resulting file looks like this.

text
1numpy==1.26.4
2pandas==2.2.1
3requests==2.31.0
4scikit-learn==1.4.2

This works because conda environments include a pip installation. Any package installed through either conda install or pip install within the environment will appear in the output. However, pip freeze may miss packages installed exclusively through conda channels that have no PyPI equivalent.

Using conda list --export

The conda list --export command outputs all packages in the environment, including their conda channel information.

bash
conda list --export > conda_packages.txt

The output uses a conda-specific format.

text
1# This file may be used to create an environment using:
2# $ conda create --name <env> --file <this file>
3numpy=1.26.4=py312h7e1e356_0
4pandas=2.2.1=py312h526ad5a_0
5python=3.12.2=h2628c08_0

This format is not pip-compatible because it uses single = signs and includes build strings. To convert it into a pip-friendly format, you can filter and reformat.

bash
conda list --export | grep -v "^#" | grep -v "^_" | sed 's/=\(.*\)=.*/==\1/' > requirements.txt

This command strips comment lines, removes internal conda packages (those starting with _), and converts the version separator from conda's =version=build to pip's ==version.

Using conda env export

For a full environment specification including the conda channel and any pip-installed packages, use conda env export.

bash
conda env export > environment.yml

The YAML output separates conda packages from pip packages.

yaml
1name: myenv
2channels:
3  - defaults
4  - conda-forge
5dependencies:
6  - numpy=1.26.4
7  - pandas=2.2.1
8  - pip:
9    - flask==3.0.2
10    - gunicorn==21.2.0

To extract only the pip section into a requirements.txt, you can parse the YAML file.

python
1import yaml
2
3with open("environment.yml") as f:
4    env = yaml.safe_load(f)
5
6pip_packages = []
7for dep in env.get("dependencies", []):
8    if isinstance(dep, dict) and "pip" in dep:
9        pip_packages.extend(dep["pip"])
10    elif isinstance(dep, str):
11        # Convert conda format to pip format
12        name_version = dep.replace("=", "==", 1).split("==")
13        if len(name_version) == 2:
14            pip_packages.append(f"{name_version[0]}=={name_version[1]}")
15
16with open("requirements.txt", "w") as f:
17    f.write("\n".join(pip_packages))

Filtering Out Conda-only Packages

Some packages in a conda environment exist only in conda channels and have no PyPI equivalent. These include low-level libraries like libffi, openssl, readline, and zlib. Including them in a requirements.txt causes pip install to fail.

bash
1# Common conda-only packages to exclude
2conda list --export | grep -v "^#" | \
3  grep -v "^_" | \
4  grep -v "^libffi" | \
5  grep -v "^openssl" | \
6  grep -v "^readline" | \
7  grep -v "^zlib" | \
8  grep -v "^xz" | \
9  grep -v "^tk" | \
10  grep -v "^ncurses" | \
11  grep -v "^sqlite" | \
12  grep -v "^ca-certificates" | \
13  sed 's/=\(.*\)=.*/==\1/' > requirements.txt

A more reliable alternative is to cross-reference against PyPI. The pip install command will simply skip packages it cannot find, but this produces error messages. A cleaner approach uses a script.

python
1import subprocess
2import json
3
4result = subprocess.run(
5    ["conda", "list", "--json"],
6    capture_output=True, text=True
7)
8packages = json.loads(result.stdout)
9
10pip_packages = []
11for pkg in packages:
12    channel = pkg.get("channel", "")
13    # Keep packages from pypi or those commonly available on PyPI
14    if channel == "pypi" or pkg["name"] in ("numpy", "pandas", "requests"):
15        pip_packages.append(f"{pkg['name']}=={pkg['version']}")
16
17with open("requirements.txt", "w") as f:
18    f.write("\n".join(pip_packages))

Handling Channel-specific Package Names

Some packages have different names between conda and PyPI. For example, pillow on conda may appear as pil or pillow depending on the channel, while PyPI uses Pillow. A mapping dictionary handles these cases.

python
1CONDA_TO_PIP_NAMES = {
2    "pytorch": "torch",
3    "pillow": "Pillow",
4    "opencv": "opencv-python",
5    "yaml": "pyyaml",
6}
7
8def convert_name(conda_name):
9    return CONDA_TO_PIP_NAMES.get(conda_name, conda_name)

Apply this mapping during the export process to prevent pip install -r requirements.txt failures caused by unrecognized package names.

Quick Reference for Export Commands

bash
1# Method 1: Direct pip freeze (simplest)
2conda activate myenv && pip freeze > requirements.txt
3
4# Method 2: Conda export with format conversion
5conda list --export | grep -v "^#" | sed 's/=\(.*\)=.*/==\1/' > requirements.txt
6
7# Method 3: Full environment YAML (preserves channels)
8conda env export --no-builds > environment.yml
9
10# Method 4: Pip-only packages from the environment
11conda env export | grep -A 9999 "pip:" | grep "==" > requirements.txt

The --no-builds flag in method 3 omits build hashes, producing cleaner output that is easier to read and more portable across platforms.

Common Pitfalls

  • Including conda system libraries - Packages like libffi, openssl, and zlib exist only in conda channels. Adding them to requirements.txt causes pip installation failures because they have no PyPI equivalent.
  • Confusing version separators - Conda uses single = between name, version, and build string, while pip uses ==. Forgetting to convert the separator produces an invalid requirements file.
  • Missing pip-installed packages in conda export - If you install packages with pip inside a conda environment without the --no-deps flag, conda may not track them. Always check both conda list and pip freeze outputs.
  • Platform-specific packages - Conda environments often include OS-specific packages (such as mkl on Intel systems). These packages may not be available on the target platform and should be removed from the requirements file.
  • Ignoring package name differences - Package names sometimes differ between conda and PyPI (for example, pytorch versus torch). Failing to translate these names causes silent installation of wrong packages or outright failures.

Summary

  • pip freeze inside an activated conda environment is the quickest way to generate a pip-compatible requirements.txt.
  • conda list --export includes all packages but requires format conversion from conda's =version=build to pip's ==version.
  • conda env export produces a full YAML specification that separates conda and pip dependencies.
  • Filter out conda-only system libraries like libffi, openssl, and zlib that have no PyPI counterparts.
  • Map package names that differ between conda and PyPI, such as pytorch to torch, to prevent installation failures.
  • Use --no-builds with conda env export for cleaner, more portable output without platform-specific build hashes.

Course illustration
Course illustration

All Rights Reserved.