ITK is organized into modules. Modules for ITK can be developed outside the ITK source tree as remote modules. The remote module can be made available in ITK’s CMake configuration by contributing it as a remote module. Python packages can also be generated for remote modules and uploaded to the Python Package Index (PyPI)

This section describes how to create, build, and upload ITK remote module Python packages to PyPI.


Building wheels requires:

  • CMake
  • Git
  • C++ Compiler - Platform specific requirements are summarized in scikit-build documentation.
  • Python

Create the module

To create an ITK module with Python wrapping, first run cookiecutter:

python -m pip install cookiecutter
python -m cookiecutter gh:InsightSoftwareConsortium/ITKModuleTemplate
# Fill in the information requested at the prompts

Then, add your classes. Reference documentation on how to populate the module can be found in the ITK Software Guide.

GitHub automated CI package builds

Freely available GitHub Actions continous integration (CI) build and test services for open source repositories are provided by GitHub. These services will build and test the C++ code for your module and also generate Linux, macOS, and Windows Python packages for your module.

For every pull request and push to the GitHub repository, a GitHub Action will run that builds and runs the repository’s C++ tests and reports the results to the ITK CDash Dashboard. Python packages are also generated for every commit. Packages for a commit’s build can be downloaded from the GitHub Action result page in the Artifacts Section.

GitHub Action Artifacts

Reusable workflows available in [ITKRemoteModuleBuildTestPackageAction]( can be used to handle the build-test-package process for a majority of ITK external modules with minimal extra development.

Upload the packages to PyPI

First, register for an account on PyPI.

Next, create a ~/.pypirc file with your login credentials:

index-servers =



where <your-username> and <your-password> correspond to your PyPI account.

Then, upload wheels to the testing server. The wheels of dist/* are those that you have built locally or have downloaded from a recent build listed at<your-long-module-name>/actions.

python -m pip install twine
python -m twine upload -r pypitest dist/*

Check out the packages on the testing server.

Finally, upload the wheel packages to the production PyPI server:

python -m twine upload dist/*

Congratulations! Your packages can be installed with the commands:

python -m pip install --upgrade pip
python -m pip install itk-<your-short-module-name>

where itk-<your-short-module-name> is the short name for your module that is specified in your file.

Automate PyPI Package Uploads

Automated uploads of Python packages to the Python package index, PyPI will occur after adding a PyPI upload token to GitHub and creating a Git tag. Create a PyPI API token by logging in to Generally, for the token name use:


and for the scope use:


where <your-short-module-name> is the short name for your module that is specified in your file. That scope will be available if you have already uploaded a first set of wheels via twine as described above; and that is the recommended approach. Otherwise, if you are creating the project at this time, choose an unlimited scope, but be careful with the created token.

PyPI Token

Then, add the API token to the GitHub repository<your-long-module-name>. Choose the Settings -> Secrets page and add a key called pypi_password, setting the password to be the token string that begins with pypi-. Note that this will be a token instead of a password. Limit the scope of the token to the individual package as a best practice.

GitHub PyPI token secret

To push packages to PyPI, first, make sure to update the version for your package in the file. The initial version might be 0.1.0 or 1.0.0. Subsequent versions should follow semantic versioning.

Then, create a Git tag corresponding to the version. A Git tag can be created in the GitHub user interface via Releases -> Draft a new release.

GitHub Release Tag

Automated platform scripts

Automated scripts are available in this repository to build Python packages that are binary compatible with the Python distributions provided by, Anaconda, and package managers like apt or Homebrew. The following sections outline how to use the associated scripts for Linux, macOS, and Windows.

Once the builds are complete, Python packages will be available in the dist directory.


To build portable Python packages on Linux, first install Docker.

For the first local build, clone the ITKPythonPackage repository inside your and download the required ITK binary builds:

cd ~/ITKMyModule
git clone

For subsequent builds, just call the build script:



First, install the macOS Python distributions. This step requires sudo:

cd ~/ITKMyModule
git clone

Then, build the wheels:



First, install Microsoft Visual Studio 2022, Git, and CMake, which should be added to the system PATH environmental variable.

Open a PowerShell terminal as Administrator, and install Python:

PS C:\> Set-ExecutionPolicy Unrestricted
PS C:\> $pythonArch = "64"
PS C:\> iex ((new-object net.webclient).DownloadString(''))

In a PowerShell prompt, run the windows-build-wheels.ps1 script:

PS C:\Windows> cd C:\ITKMyModule
PS C:\ITKMyModule> git clone IPP
PS C:\ITKMyModule> .\ITKPythonPackage\scripts\windows-download-cache-and-build-module-wheels.ps1

Other Notes

ITK modules sometimes depend on third-party libraries. To include third-party libraries in development wheels for distribution, first add the library path to LD_LIBRARY_PATH on Linux, DYLD_LIBRARY_PATH on MacOS, or PATH on Windows. Then, run the platform build script.

ITK modules sometimes depend on other ITK modules. For instance, to build [ITKBSplineGradient]( the user must first build ITK and then [ITKMeshToPolyData]( ITKPythonPackage scripts support iterative prerequisite ITK module dependencies with the ITK_MODULE_PREQ environment variable.

For Python build scripts, the ordered list of ITK module dependencies must be formatted as follows:

` ITK_MODULE_PREQ=<module_org>/<module_name>@<module_tag>:<module_org>/<module_name>@<module_tag>:... `

Where - module_org is the name of a Github organization to use to fetch the module, i.e. “InsightSoftwareConsortium”; - module_name is the name of the module, i.e. “ITKMeshToPolyData”; - module_tag is the git tag or commit hash to use to fetch the module, i.e. “v1.0.0”

Module names must be provided in order of dependencies for the build to succeed.

For more information see the [build scripts directory](