“Don’t make your users compile; they have better things to do.”
The pain
Compiling C/C++ extensions for a Python package is like making every diner at a restaurant cook their own meal. It wastes time, assumes a working tool‑chain, and fails in the places you care most about (CI, Windows laptops, raspberry‑pi kiosks).
The shortcut
A wheel (.whl) is just a zip archive whose internal layout already matches the target site‑packages/ tree.
If the filename tags (cp311‑abi3‑manylinux_2_17_x86_64.whl) match your interpreter and OS, installation degenerates to:
unzip wheel && move filesNo setup.py, no compiler, no surprises.
That 30‑second source build of lxml? → 0.3 s wheel install.
Heuristics I keep handy
-
Ship wheels or don’t ship at all. A mature package publishes at least the “big three”:
macOS + manylinux + win32/64for each supported Python minor. -
Manylinux is your friend. Audit‑wheel your build, pin
GLIBC≤ 2.17, and suddenly 95 % of Linux installs are green. -
Pure‑Python? Tag
py3‑none‑any. One wheel, zero recompiles, infinite happiness. -
Cache wheels in CI. Your tests will finish before you find the next meme on Slack.
-
Never
sudo apt install python3-devin prod. If you need system headers‑at‑runtime, you missed a wheel at build time.
Subtleties & gotchas
- ABI leaks. A wheel built against
numpy 2.0might import on a box withnumpy 1.26but segfault later. Pin build‑time deps and encode them inRequires-Dist. - Platform tag ≠ CPU architecture.
manylinuxhandles GLIBC, not AVX. If you squeeze every FLOP, publish a separate+cudaor+avx2wheel. - Security upside. Wheels are inert archives; nothing executes during install. Hash them (
--require-hashes) and you have a reproducible supply chain.
Mental model
Think of a wheel as potential energy: heavy work done once, stored, ready to be released instantly on every install. The bigger the library, the larger the win. For tiny pure‑Python libs wheels are still worth it because they simplify the install story to a single code path.
Closing loop
If your library takes more than a second to install, you owe the world a wheel.
Future‑you, running pip install your‑pkg in a fresh container at 3 AM, will thank present‑you.