Manylinux is a standard platform tag for Linux wheels that contain compiled code, so one wheel can run on most Linux distributions. You need it only if your library ships compiled extensions. A pure Python library uses the any platform tag and never touches manylinux.
The problem it solves
A compiled extension links against system libraries, mainly the C library. Linux distributions differ in those details. The Python Packaging User Guide says the plain platform tag is insufficient for public distribution of wheels to Linux because of the large ecosystem of platforms and subtle differences between them.
Manylinux defines a common subset of Linux platforms. A wheel built against that subset and tagged manylinux can be used across most common distributions.
How the tag is written
The current standard uses the form manylinux, then the glibc major and minor version, then the CPU architecture. For example, the guide says a tag with glibc 2.24 should work on any distribution using glibc 2.24 or newer. The older named tags remain supported for backward compatibility.
| Older tag | glibc version supported | Architectures listed |
|---|---|---|
| manylinux1 | 2.5 | x86_64, i686 |
| manylinux2010 | 2.12 | x86_64, i686 |
| manylinux2014 | 2.17 | x86_64, i686, aarch64, armv7l, ppc64, ppc64le, s390x |
The guide notes that wheels built for older versions are forward compatible, meaning they keep working on modern systems, but not backward compatible. It also says the build environments for manylinux1 and manylinux2010 have reached end of life and no longer receive security updates. Package maintainers are told to target the most compatible specification possible, with that caveat in mind.
What about Alpine and musl
Distributions that use the musl C library, a prime example being Alpine Linux, are covered by a separate family called musllinux. Its tags follow the same shape, naming the musl version and the architecture. If you want your compiled wheel to install quickly on those systems, build musllinux wheels as well. Otherwise those users fall back to your sdist and a local build.
When you do not need any of this
- Your library is pure Python. Publish one py3-none-any wheel.
- You only ship an sdist. Users build locally, which works but is slower and needs a compiler.
- Your package targets only macOS or Windows.
Practical steps for a library with compiled code
- Decide which platforms you promise to support, and write them in your README.
- Build wheels inside a manylinux compatible build environment, not on a random developer machine.
- Run a repair tool that checks the wheel for external library dependencies. The guide refers to auditwheel for this and lists minimum versions for each standard.
- Build musllinux wheels if you want Alpine users covered.
- Upload the sdist alongside every wheel.
- Install each wheel in a matching clean environment and run your tests.
A security angle
Compiled wheels are binaries. Users cannot read them the way they can read a pure Python source tree. Build them in CI from a tagged commit, publish through a trusted publisher so tokens are short lived, and keep the build job separate from the publish job. We cover that in why to separate build and publish jobs.
Safeguard's dependency scanning and SBOM generation can inventory which native libraries and packages a product pulls in. A free scan is a quick way to look.
Quick check
Does a pure Python wheel need a manylinux tag?
No. Pure Python wheels use the any platform tag and run everywhere Python runs.
What does the glibc number in the tag mean?
It is the minimum glibc version the wheel supports. A wheel built for an older glibc runs on newer systems, not the reverse.
Is manylinux the same as musllinux?
No. Manylinux targets glibc systems. Musllinux targets systems using musl, such as Alpine.
Sources
- Platform compatibility tags, Python Packaging User Guide
- The Packaging Flow, Python Packaging User Guide
- Binary distribution format, Python Packaging User Guide
Last reviewed: 19 October 2026.