“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 files

No setup.py, no compiler, no surprises. That 30‑second source build of lxml? → 0.3 s wheel install.

Heuristics I keep handy

  1. Ship wheels or don’t ship at all. A mature package publishes at least the “big three”: macOS + manylinux + win32/64 for each supported Python minor.

  2. Manylinux is your friend. Audit‑wheel your build, pin GLIBC ≤ 2.17, and suddenly 95 % of Linux installs are green.

  3. Pure‑Python? Tag py3‑none‑any. One wheel, zero recompiles, infinite happiness.

  4. Cache wheels in CI. Your tests will finish before you find the next meme on Slack.

  5. Never sudo apt install python3-dev in 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.0 might import on a box with numpy 1.26 but segfault later. Pin build‑time deps and encode them in Requires-Dist.
  • Platform tag ≠ CPU architecture. manylinux handles GLIBC, not AVX. If you squeeze every FLOP, publish a separate +cuda or +avx2 wheel.
  • 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.