conda-pypi
conda-pypi is a conda plugin that installs PyPI packages into a conda environment by converting their sdists or wheels into the .conda format at install time. The conda solver tracks every package the plugin installs, which closes the long-standing gap where pip-installed packages were invisible to conda and the two views of the environment would drift apart.
Warning
conda-pypi is in early development. The project README states: “Don’t use it in production (yet).” The latest release is 0.9.0 (May 2026). The plugin is useful for experimentation and for migrating away from the pip-last pattern, but teams running production workloads should track the project and adopt it after a stable release.
Why conda-pypi Exists
Mixing conda and pip in a single environment is a recurring source of broken installs. Conda’s dependency solver only sees packages it installed; pip’s only sees packages it installed. When the two install overlapping dependencies, conda can overwrite pip-installed files, pip can leave conda’s metadata stale, and conda update afterward can produce an environment that no longer matches either tool’s record of it. The conventional workaround is the pip-last pattern: install everything available on conda channels first, run pip install for whatever is left, and never run a conda command in that environment again. The pattern works but is fragile and undocumented in the environment itself.
conda-pypi replaces the pattern with a single tool that records PyPI installs the same way conda records its own. Every PyPI package becomes a .conda artifact with its metadata indexed in the environment, so the solver sees it on subsequent operations. The plugin also installs an EXTERNALLY-MANAGED marker (the PEP 668 mechanism that Debian uses to protect the system Python) so accidental pip install invocations are refused with a message pointing at conda pypi install instead.
Installation
conda-pypi requires conda 26.5 or newer and the rattler solver. On a recent Miniforge, one command pulls in everything:
conda install --name base -y "conda>=26.5"On a fresh Miniforge install (which ships conda 26.3.2 as of May 2026), the upgrade transaction pulls conda-pypi 0.9.0 and conda-rattler-solver 0.1.0 in as dependencies of the new conda. A separate conda install conda-pypi afterward is a no-op. conda --version should report 26.5.0 or newer when the upgrade completes.
After installation, configure the rattler solver:
conda config --set solver rattlerThe conda pypi subcommand becomes available immediately; no shell restart is required.
Caution
The conda-pypi quickstart also instructs conda config --append channels conda-pypi and conda config --set channel_priority flexible. As of conda 26.5.0 + conda-rattler-solver 0.1.0 + conda-pypi 0.9.0 (May 2026), appending the conda-pypi channel to the global config breaks conda create with a 404 on shard fetches against conda.anaconda.org/conda-pypi/noarch/shards/. Skip the channel-append step until that resolves upstream; the conda pypi install subcommand still works without it.
The conda-pypi Channel
The plugin can be paired with the conda-pypi channel hosted by Anaconda. The channel publishes metadata for pure Python wheels that have been pre-validated against the conda packaging conventions, with the wheel artifacts themselves still fetched from pypi.org. The channel is free for all use and is not subject to the licensing requirements that apply to the default Anaconda channel.
Adding the channel to the global config has the trade-off described in the Installation warning above. A safer pattern while the project is alpha is to invoke it explicitly with -c conda-pypi only on commands that need it, rather than appending it globally.
Subcommands
conda pypi install
Installs PyPI packages into the active or named environment using a hybrid resolution strategy. Explicitly requested packages always come from PyPI and are converted to .conda format on the fly. Dependencies follow a conda-first preference: if a dependency exists on a configured conda channel, conda installs that build; otherwise the dependency is also pulled from PyPI and converted.
Common flags:
-n, --name ENV(parent flag onconda pypi) targets a named environment without activating it.-p, --prefix PATHtargets an environment by full path.-i, --index-url URLadds a PyPI index URL; can be repeated for multiple indexes.--ignore-channelsforces every package, including dependencies, to be resolved from PyPI rather than the configured conda channels.-e, --editable PATHinstalls a local project in editable mode by building a.condaartifact from the source tree and linking it into the environment.-d, --dry-run(parent flag onconda pypi) reports the resolved install plan without writing files. Invoked asconda pypi -d install <pkg>.
Package names are translated between PyPI and conda conventions using the Grayskull name-mapping tables.
conda pypi convert
Builds a local Python project, sdist, or wheel into a .conda artifact without installing it. Useful for preparing offline installs, building internal mirrors, or inspecting how the plugin would translate a package before committing to an install.
The positional argument is a path on the local filesystem, not a PyPI package name. Convert a remote package by downloading the wheel first (for example with pip download) and pointing conda pypi convert at the local file.
Common flags:
--output-folder DIRwrites the converted artifacts to a directory rather than the conda package cache.-e, --editablebuilds the project as an editable package.-t, --test-dir DIRinjects a test-files directory into the converted conda package.--name-mapping FILEpoints at a JSON file containing a custom PyPI-to-conda name mapping.
Environment Protection
When conda-pypi is installed into an environment, the plugin places an EXTERNALLY-MANAGED file in the environment’s standard library location. Subsequent pip install calls against that environment fail with the PEP 668 rejection message, which conda-pypi customizes to direct users to conda pypi install instead. See How to fix the externally-managed-environment error for the underlying mechanism.
The warning can be disabled per environment with conda config --set plugins.conda_pypi_pip_warning false, though doing so reintroduces the failure mode the plugin is designed to prevent.
Limits
- Pure Python wheels only. Packages with platform-specific compiled extensions are not supported. Compiled scientific stacks (NumPy, SciPy, PyTorch, CuPy) must come from conda-forge or another conda channel.
- PEP 508 dependency markers are partially handled. The
extra == "..."form is split into per-extra dependency tables in the converted.condaartifact. Other environment markers (python_version,sys_platform,os_name) are dropped during conversion, which can produce a thinner dependency graph than the wheel itself would install via pip. - The wheel-channels feature is experimental. A draft Conda Enhancement Proposal defines how a channel can expose wheels directly in its repodata under a
v3.whlsection. The conda-pypi plugin implements this path, but the specification is still under discussion and the on-disk format is not guaranteed to remain stable. - The rattler solver + conda-pypi channel combination is unstable. As noted in Installation, appending the
conda-pypichannel to the global config currently breaksconda createwith shard-fetch 404s. - Security inherits PyPI’s model. The channel only republishes metadata; the wheel files themselves come from
pypi.orgwithout independent vetting. Supply-chain controls that apply to PyPI (trusted publishing, attestations, package signing) also apply here. Conda-forge’s screened feedstock process does not.
Related Approaches
- pixi resolves conda-forge and PyPI packages together in a single lockfile, using uv internally for the PyPI side. The model is integrated from the start rather than bolted onto conda after the fact; pixi is the alternative to evaluate when both PyPI and compiled-wheel interop matter and a project-local workflow is acceptable. See uv vs pixi vs conda for scientific Python.
- The pip-last convention is the long-standing workaround that conda-pypi replaces. Install every available dependency via conda first, run
pip installonce for the remainder, and avoid further conda operations in the environment. It still works and is appropriate for teams that cannot adopt alpha tooling, but it leaves no record in the environment that pip was used.
Pros
- The conda solver tracks PyPI packages on the same footing as conda packages, eliminating the silent-drift failure mode of mixed environments.
- Hybrid resolution prefers conda-channel builds for dependencies, which keeps compiled libraries on a tested build path even when the requested package is PyPI-only.
EXTERNALLY-MANAGEDenforcement prevents accidentalpip installfrom corrupting environments after the fact.- Editable installs work the same way as
pip install -e, supporting standard development workflows. - The conda-pypi channel is free for all use without Anaconda commercial-license obligations.
Cons
- Alpha software, not recommended for production by its maintainers.
- Pure Python wheels only; compiled extensions require conda-forge or another conda channel.
- Requires conda 26.5 plus the rattler solver, which is newer than many existing installations.
- The documented
conda-pypichannel-append step breaksconda createwith the rattler solver as of 0.9.0. - PEP 508 environment markers other than
extra ==are dropped during conversion. - The wheel-channels feature depends on a CEP still under discussion.
Learn More
Handbook pages
- conda
- conda-forge
- conda package
- pixi
- Understanding the Conda/Anaconda Ecosystem
- uv vs pixi vs conda for scientific Python
- How to fix the externally-managed-environment error