cibuildwheel

Documentation
Python wheels are great. Building them across Mac, Linux, Windows, on multiple versions of Python, is not.
cibuildwheel
is here to help. cibuildwheel
runs on your CI server - currently it supports GitHub Actions, Azure Pipelines, Travis CI, AppVeyor, CircleCI, and GitLab CI - and it builds and tests your wheels across all of your platforms.
What does it do?
While cibuildwheel itself requires a recent Python version to run (we support the last three releases), it can target the following versions to build wheels:
CPythonΒ 3.6 | β
| N/A | β
| β
| N/A | β
| β
| β
| β
| β
| β
β΅ | N/A |
CPythonΒ 3.7 | β
| N/A | β
| β
| N/A | β
| β
| β
| β
| β
| β
β΅ | N/A |
CPythonΒ 3.8 | β
| β
| β
| β
| N/A | β
| β
| β
| β
| β
| β
β΅ | N/A |
CPythonΒ 3.9 | β
| β
| β
| β
| β
Β² | β
| β
| β
| β
| β
| β
β΅ | N/A |
CPythonΒ 3.10 | β
| β
| β
| β
| β
Β² | β
| β
| β
| β
| β
| β
β΅ | N/A |
CPythonΒ 3.11 | β
| β
| β
| β
| β
Β² | β
| β
| β
| β
| β
| β
β΅ | N/A |
CPythonΒ 3.12 | β
| β
| β
| β
| β
Β² | β
| β
| β
| β
| β
| β
β΅ | β
β΄ |
CPythonΒ 3.13Β³ | β
| β
| β
| β
| β
Β² | β
| β
| β
| β
| β
| β
β΅ | N/A |
PyPyΒ 3.7 v7.3 | β
| N/A | β
| N/A | N/A | β
ΒΉ | β
ΒΉ | β
ΒΉ | N/A | N/A | N/A | N/A |
PyPyΒ 3.8 v7.3 | β
| β
| β
| N/A | N/A | β
ΒΉ | β
ΒΉ | β
ΒΉ | N/A | N/A | N/A | N/A |
PyPyΒ 3.9 v7.3 | β
| β
| β
| N/A | N/A | β
ΒΉ | β
ΒΉ | β
ΒΉ | N/A | N/A | N/A | N/A |
PyPyΒ 3.10 v7.3 | β
| β
| β
| N/A | N/A | β
ΒΉ | β
ΒΉ | β
ΒΉ | N/A | N/A | N/A | N/A |
PyPyΒ 3.11 v7.3 | β
| β
| β
| N/A | N/A | β
ΒΉ | β
ΒΉ | β
ΒΉ | N/A | N/A | N/A | N/A |
ΒΉ PyPy is only supported for manylinux wheels.
Β² Windows arm64 support is experimental.
Β³ Free-threaded mode requires opt-in using CIBW_FREE_THREADED_SUPPORT
.
β΄ Experimental, not yet supported on PyPI, but can be used directly in web deployment. Use --platform pyodide
to build.
β΅ manylinux armv7l support is experimental. As there are no RHEL based image for this architecture, it's using an Ubuntu based image instead.
- Builds manylinux, musllinux, macOS 10.9+ (10.13+ for Python 3.12+), and Windows wheels for CPython and PyPy
- Works on GitHub Actions, Azure Pipelines, Travis CI, AppVeyor, CircleCI, GitLab CI, and Cirrus CI
- Bundles shared library dependencies on Linux and macOS through auditwheel and delocate
- Runs your library's tests against the wheel-installed version of your library
See the cibuildwheel 1 documentation if you need to build unsupported versions of Python, such as Python 2.
Usage
cibuildwheel
runs inside a CI service. Supported platforms depend on which service you're using:
GitHub Actions | β
| β
| β
| β
| β
| β
Β² |
Azure Pipelines | β
| β
| β
| | β
| β
Β² |
Travis CI | β
| | β
| β
| | |
AppVeyor | β
| β
| β
| | β
| β
Β² |
CircleCI | β
| β
| | β
| β
| |
Gitlab CI | β
| β
| β
| β
ΒΉ | β
| |
Cirrus CI | β
| β
| β
| β
| β
| |
ΒΉ Requires emulation, distributed separately. Other services may also support Linux ARM through emulation or third-party build hosts, but these are not tested in our CI.
Β² Uses cross-compilation. It is not possible to test arm64
on this CI platform.
Example setup
To build manylinux, musllinux, macOS, and Windows wheels on GitHub Actions, you could use this .github/workflows/wheels.yml
:
name: Build
on: [push, pull_request]
jobs:
build_wheels:
name: Build wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest, macos-13, macos-latest]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- name: Install cibuildwheel
run: python -m pip install cibuildwheel==2.23.2
- name: Build wheels
run: python -m cibuildwheel --output-dir wheelhouse
- uses: actions/upload-artifact@v4
with:
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
path: ./wheelhouse/*.whl
For more information, including PyPI deployment, and the use of other CI services or the dedicated GitHub Action, check out the documentation and the examples.
How it works
The following diagram summarises the steps that cibuildwheel takes on each platform.

Explore an interactive version of this diagram in the docs.
Options
These options can be specified in a pyproject.toml file, as well; see configuration.
Working examples
Here are some repos that use cibuildwheel.
scikit-learn |  |  | The machine learning library. A complex but clean config using many of cibuildwheel's features to build a large project with Cython and C++ extensions. |
pytorch-fairseq |  |  | Facebook AI Research Sequence-to-Sequence Toolkit written in Python. |
NumPy |  |  | The fundamental package for scientific computing with Python. |
duckdb |  |  | DuckDB is an analytical in-process SQL database management system |
Tornado |  |  | Tornado is a Python web framework and asynchronous networking library. Uses stable ABI for a small C extension. |
NCNN |  |  | ncnn is a high-performance neural network inference framework optimized for the mobile platform |
Matplotlib |  |  | The venerable Matplotlib, a Python library with C++ portions |
Prophet |  |  | Tool for producing high quality forecasts for time series data that has multiple seasonality with linear or non-linear growth. |
MyPy |  |  | The compiled version of MyPy using MyPyC. |
Kivy |  |  | Open source UI framework written in Python, running on Windows, Linux, macOS, Android and iOS |
βΉοΈ That's just a handful, there are many more! Check out the Working Examples page in the docs.
Legal note
Since cibuildwheel
repairs the wheel with delocate
or auditwheel
, it might automatically bundle dynamically linked libraries from the build machine.
It helps ensure that the library can run without any dependencies outside of the pip toolchain.
This is similar to static linking, so it might have some license implications. Check the license for any code you're pulling in to make sure that's allowed.
Changelog
v2.23.2
24 March 2025
- π Workaround an issue with pyodide builds when running cibuildwheel with a Python that was installed via UV (#2328 via #2331)
- π Dependency updates, including a manylinux update that fixes an 'undefined symbol' error in gcc-toolset (#2334)
v2.23.1
15 March 2025
- β οΈ Added warnings when the shorthand values
manylinux1
, manylinux2010
, manylinux_2_24
, and musllinux_1_1
are used to specify the images in linux builds. The shorthand to these (unmaintainted) images will be removed in v3.0. If you want to keep using these images, explicitly opt-in using the full image URL, which can be found in this file. (#2312)
- π Dependency updates, including a manylinux update which fixes an issue with rustup. (#2315)
v2.23.0
1 March 2025
- β¨ Adds official support for the new GitHub Actions Arm runners. In fact these worked out-of-the-box, now we include them in our tests and example configs. (#2135 via #2281)
- β¨ Adds support for building PyPy 3.11 wheels (#2268 via #2281)
- π Adopts the beta pypa/manylinux image for armv7l builds (#2269 via #2281)
- π Dependency updates, including Pyodide 0.27 (#2117 and #2281)
v2.22.0
23 November 2024
- π Added a new
CIBW_ENABLE
/enable
feature that replaces CIBW_FREETHREADED_SUPPORT
/free-threaded-support
and CIBW_PRERELEASE_PYTHONS
with a system that supports both. In cibuildwheel 3, this will also include a PyPy setting and the deprecated options will be removed. (#2048)
- π Dependency groups are now supported for tests. Use
CIBW_TEST_GROUPS
/test-groups
to specify groups in [dependency-groups]
for testing. (#2063)
- π Support for the experimental Ubuntu-based ARMv7l manylinux image (#2052)
- β¨ Show a warning when cibuildwheel is run from Python 3.10 or older; cibuildwheel 3.0 will require Python 3.11 or newer as host (#2050)
- π Fix issue with stderr interfering with checking the docker version (#2074)
- π Python 3.9 is now used in
CIBW_BEFORE_ALL
/before-all
on linux, replacing 3.8, which is now EoL (#2043)
- π Error messages for producing a pure-Python wheel are slightly more informative (#2044)
- π Better error when
uname -m
fails on ARM (#2049)
- π Better error when repair fails and docs for abi3audit on Windows (#2058)
- π Better error when
manylinux-interpreters ensure
fails (#2066)
- π Update Pyodide to 0.26.4, and adapt to the unbundled pyodide-build (now 0.29) (#2090)
- π Now cibuildwheel uses dependency-groups for development dependencies (#2064, #2085)
- π Docs updates and tidy ups (#2061, #2067, #2072)
v2.21.3
9 October 2024
- π Update CPython 3.13 to 3.13.0 final release (#2032)
- π Docs updates and tidy ups (#2035)
That's the last few versions.
βΉοΈ Want more changelog? Head over to the changelog page in the docs.
Contributing
For more info on how to contribute to cibuildwheel, see the docs.
Everyone interacting with the cibuildwheel project via codebase, issue tracker, chat rooms, or otherwise is expected to follow the PSF Code of Conduct.
Maintainers
Credits
cibuildwheel
stands on the shoulders of giants.
Massive props also to-
- @zfrenchee for help debugging many issues
- @lelit for some great bug reports and contributions
- @mayeut for a phenomenal PR patching Python itself for better compatibility!
- @czaki for being a super-contributor over many PRs and helping out with countless issues!
- @mattip for his help with adding PyPy support to cibuildwheel
See also
Another very similar tool to consider is matthew-brett/multibuild. multibuild
is a shell script toolbox for building a wheel on various platforms. It is used as a basis to build some of the big data science tools, like SciPy.
If you are building Rust wheels, you can get by without some of the tricks required to make GLIBC work via manylinux; this is especially relevant for cross-compiling, which is easy with Rust. See maturin-action for a tool that is optimized for building Rust wheels and cross-compiling.