20 July 2026 by Timothy Poon7 minutes
When I recently updated conda to 26.5, I was greeted by the following
message:
Did you know? You can install many PyPI packages with conda
using the conda-pypi beta. Get started:
https://docs.conda.io/projects/conda/en/stable/new-features.htmlA plugin conda-pypi is now available in beta! The message suggests that, can
conda install and pip install finally work together safely? This makes me
excited as mixing conda install and pip install in a conda environment
usually causes confusion when the dependencies are resolved. To find out more
about it, I went to
the documentation of
conda-pypi to see what it is
capable of and how it works.
One of the most popular best practices around the usage of conda has been to
avoid mixing it with pip. However, sometimes you have no choice as the
package you want to install is not available via a conda channel or simply it
is not up-to-date with the corresponding one in PyPI. I frequently helped
scientists in setting standalone conda environments so they can launch a
particular application in an isolated environment. Since a lot of applications
were developed in-house, it is not surprising that they are not available in a
conda channel so I will need to pip install inside a conda environment. This
was what I did:
pip install --dry-run <PKG_TO_INSTALL>.conda install them.conda, run pip install --no-deps <PKG_TO_INSTALL> to install the actual package.One of my colleagues rightly questioned my approach, saying why didn’t you just
pip install <PKG_TO_INSTALL> after creating the conda environment if the
environment will not be touched anymore. Perhaps I was being overly cautious
and wanted to minimise the mixing of conda and pip for the sake of
‘purity’: it is satisfying to see all the installed packages are coming from
the same channel after doing conda list. Other strategies also exist as
documented in this conda-pypi
page.
pip install and conda install is usually badIt is actually worth understanding why mixing conda install and pip install
is generally a bad idea. Perhaps not surprising to know, conda and pip are
two independent package managers and they record dependencies differently:
conda has its own way of resolving dependencies and record those metadata by
JSON files in the conda-meta directory; pip records the metadata of every
installed package in separate directories with the format
<NAME>-<VERSION>.dist-info (see
here
for the detailed specification) in the site-packages directory, e.g.
numpy-2.5.0.dist-info.
A good thing about conda is that it also creates .dist-info directories
in site-packages for each package installed via conda install, so pip can
know what conda has installed because it understands .dist-info. However,
pip install does not put anything in conda-meta so conda has no record
about what pip has installed. This is the reason why touching a conda
environment (e.g. conda install other packages or conda update) after pip install is generally a bad idea as conda only looks at what are inside
conda-meta but not .dist-info, and this often results in a mismatch between
the version reported in conda list and the actual imported one, or even you
can import a ‘ghost’ package that is not shown in conda list!
conda-pypi solves the issueWith the plugin conda-pypi
enabled, conda will resolve
dependencies in all your specified conda channels and the conda-pypi ‘channel’,
which makes packages in PyPI available via conda install. Depending on the
order of your channels and the availability, packages will be installed either
from a conda channel or wheels directly from PyPI.
The important difference from a pure pip install inside a conda environment
is that even if the wheels are coming straight from PyPI, it is conda which
manages the installation and the recording of metadata, i.e. a JSON file will
be created in conda-meta. conda operations afterwards such as conda update, conda install another package or conda remove will respect both
metadata from packages installed from conda install and PyPI. No more manual
dependencies installation or worry about conflicting installation within a
conda environment if I use conda install and pip install!
To understand how the conda-pypi plugin works, I experimented with installing
numpy by pip install inside a conda environment to see if it delivers in
practice. I would like to see how it works if I want to install numpy with
some custom build options that can be specified during pip install and how I
can make use of conda-pypi for a smoother experience of package management.
The default build options of numpy, not surprisingly, target a wide range of
CPU architecture and it is usually quite optimised. However in some situations,
you may want to turn off the optimisation for testing and debugging purposes
(or just to appreciate the effort people put in for optimisation).
As a lot of scientific packages depend on numpy and if you have pip install-ed your own numpy in a conda environment, it will be a nightmare if
you conda install anything after this. So I hope by using conda-pypi, I can
now build my own numpy and then install any package afterwards from various
conda channels.
First, set up your conda environment:
# cython etc. are build dependencies for NumPy
conda create -n npy-pip python=3.13 cython compilers openblas meson-python pkg-configThen build and install numpy by pip:
python -m pip install --no-cache-dir numpy --no-build-isolation --no-binary numpyNow if I inspect the output of numpy.show_config() on my machine (Apple M2):
"SIMD Extensions": {
"baseline": [
"NEON",
"NEON_FP16",
"NEON_VFPV4",
"ASIMD"
],
"found": [
"ASIMDHP",
"ASIMDDP"
],
"not found": [
"ASIMDFHM"
]
}Create another conda environment with the same build dependencies as above,
then build and install numpy by setting disable-optimization to true:
python -m pip install -Csetup-args=-Ddisable-optimization="true" --no-cache-dir numpy --no-build-isolation --no-binary numpyIn this installation, there are no SIMD extensions as shown in
numpy.show_config().
Both of the above approaches used pip install and if you look at
conda-meta, there is no numpy-....json which records the installation and
further conda operations that depend on the records in conda-meta would not
know the existence of numpy with optimisation off, which are installed by
pip.
How about using conda-pypi to build and install numpy with the optimisation
off? After creating a fresh conda environment as above, you can first build the
wheel without installing by pip:
python -m pip wheel -w wheels -Csetup-args=-Ddisable-optimization="true" --no-cache-dir numpy --no-build-isolation --no-binary numpyThe -w wheels puts the numpy wheel inside the wheels directory and you
can use wherever you fancy. One of the features provided by conda-pypi
allows you to
convert wheels into .conda
format
which you can then use it for local installation.
# the name of the NumPy wheel will most likely be different in your case
conda pypi convert wheels/numpy-2.5.0-cp313-cp313-macosx_26_0_arm64.whl
# conda-pypi saves the converted .conda in ./conda-pypi-output by default
conda install conda-pypi-output/numpy-2.5.0-pypi_0.condaAs the installation is performed by conda, you will see something like
numpy-....json inside conda-meta which means further conda operations
will respect the existence of your numpy built with optimisation off! From
now on, if you install packages that depend on numpy via conda install,
such as scipy, it won’t install numpy from any conda channel as conda
knows its existence.
We discussed the new conda-pypi plugin which is available from conda>=26.5
and its motivation, which is to provide a smoother experience when mixing pip install and conda install in a conda environment. We showed a demo that uses
conda-pypi to install a custom built numpy into a conda environment and
illustrated this approach would let conda respect the existence of it.
As of July 2026, conda-pypi is still in beta so I would not recommend using
it in production. I think the best practice about not mixing conda and pip
packages still holds, and whenever possible, one should install packages from a
single conda channel. However, conda-pypi provides a much smoother workflow
if you find yourself installing something via pip in a conda environment and
it is definitely worth keeping an eye on its development.