Skip to main content

Build and publish Zig-powered Python extensions with native cross-compilation

Project description

zig-maturin

Build and publish Zig-powered Python extensions with native cross-compilation.

zig-maturin is a tool that compiles Zig code into Python native extensions and packages them as .whl (wheel) files — ready for pip install. Think of it as Maturin for Zig.

Why Zig?

Feature Rust + Maturin Zig + zig-maturin
Cross-compilation Complex: needs external linkers, toolchains, or Docker Built-in: zig build -Dtarget=aarch64-macos works out of the box
Toolchain size Gigabytes (rustc + LLVM) A few megabytes (single Zig binary)
C ABI Via #[no_mangle] and extern "C" Native: Zig compiles directly to C-compatible shared libraries

Zig's built-in cross-compilation lets you build wheels for all platforms from a single machine — no Docker, no extra toolchains, no linker setup.

Quick Start

# Install zig-maturin
pip install zig-maturin

# Scaffold a new project
zig-maturin scaffold my_extension
cd my_extension

# Build and install in development mode
zig-maturin develop

# Test it
python -c "import my_extension; print(my_extension.hello())"
# → Hello from Zig!

# Build a wheel for distribution
zig-maturin build
# → dist/my_extension-0.1.0-cp314-cp314-manylinux_2_28_x86_64.whl

# Cross-compile for other platforms (no extra setup needed!)
zig-maturin build --target aarch64-macos --target x86_64-windows
# → dist/my_extension-0.1.0-cp314-cp314-macosx_11_0_arm64.whl
# → dist/my_extension-0.1.0-cp314-cp314-win_amd64.whl

How it Works

  1. Write Zig code — use the zig-maturin Zig package to access the Python C-API
  2. zig-maturin build — compiles with zig build and packages the .so into a wheel
  3. zig-maturin develop — compiles and installs directly into the current Python environment
  4. Cross-compile — pass --target <triple> to build for any supported platform

Writing a Python Extension in Zig

The zig-maturin Zig package provides low-level Python C-API bindings. Functions are exposed via the standard Python C extension pattern:

const zm = @import("zig-maturin");

fn hello(self: ?*zm.PyObject, args: ?*zm.PyObject) callconv(.c) ?*zm.PyObject {
    _ = self;
    _ = args;
    return zm.PyUnicode_FromString("Hello from Zig!");
}

pub export fn PyInit_my_extension() callconv(.c) ?*zm.PyObject {
    const methods = [_]zm.PyMethodDef{
        zm.method("hello", &hello, zm.METH_NOARGS, "Say hello"),
        .{ .ml_name = null, .ml_meth = null, .ml_flags = 0, .ml_doc = null },
    };
    var mod = zm.PyModuleDef{
        .m_base = zm.PyModuleDef_HEAD_INIT,
        .m_name = "my_extension",
        .m_doc = "A Python module written in Zig",
        .m_size = -1,
        .m_methods = @as(?[*]zm.PyMethodDef, @ptrCast(@constCast(&methods))),
        .m_slots = null,
        .m_traverse = null,
        .m_clear = null,
        .m_free = null,
    };
    return zm.PyModule_Create(&mod);
}

Note: The zig-maturin package exposes the raw Python C-API as Zig extern functions. A higher-level "PyO3 for Zig" layer is planned for future releases.

Available C-API Bindings

The Zig package wraps a comprehensive subset of the Python C-API:

Category Functions
Module PyModule_Create, PyModule_New, PyModule_AddObject, PyModule_AddIntConstant, PyModule_AddStringConstant
Ref counting Py_INCREF, Py_DECREF, Py_XINCREF, Py_XDECREF, Py_NewRef, Py_IncRef, Py_DecRef
Strings PyUnicode_FromString, PyUnicode_FromStringAndSize, PyUnicode_AsUTF8, PyUnicode_Check
Integers PyLong_FromLong, PyLong_FromLongLong, PyLong_FromUnsignedLongLong, PyLong_AsLong, PyLong_AsLongLong, PyLong_Check
Floats PyFloat_FromDouble, PyFloat_AsDouble, PyFloat_Check
Booleans PyBool_FromLong, PyBool_Check
Exceptions PyErr_SetString, PyErr_SetObject, PyErr_Occurred, PyErr_Clear
Objects PyObject_GetAttrString, PyObject_SetAttrString, PyObject_CallObject, PyObject_Str, PyObject_IsTrue
Args PyArg_ParseTuple, Py_BuildValue
Lists PyList_New, PyList_Size, PyList_GetItem, PyList_SetItem, PyList_Append, PyList_Check
Dicts PyDict_New, PyDict_SetItemString, PyDict_GetItemString, PyDict_Size, PyDict_Check
Tuples PyTuple_New, PyTuple_Size, PyTuple_GetItem, PyTuple_SetItem

Commands

zig-maturin scaffold <name>

Creates a new project with:

  • pyproject.toml — Python project configuration
  • build.zig / build.zig.zon — Zig build configuration with zig-maturin dependency
  • src/main.zig — Template module with a hello function

zig-maturin build

Builds the extension and creates a .whl file.

  • --target <triple> — cross-compile target (can be specified multiple times for multi-platform builds)
  • --release — build in release mode
  • --out <dir> — output directory (default: dist)

zig-maturin develop

Builds the extension and installs it into the current Python environment's site-packages.

  • --target <triple> — cross-compilation target (default: host native)
  • --release — build in release mode

Configuration

zig-maturin reads [tool.zig-maturin] from pyproject.toml:

[tool.zig-maturin]
module-name = "my_extension"      # Python module name (default: project name)
zig-source = "src/main.zig"       # Path to Zig source file

Cross-Compilation Targets

zig-maturin maps Zig targets to Python wheel platform tags:

Zig Target Wheel Tag
x86_64-linux-gnu manylinux_2_28_x86_64
aarch64-linux-gnu manylinux_2_28_aarch64
x86_64-linux-musl musllinux_1_2_x86_64
aarch64-macos macosx_11_0_arm64
x86_64-macos macosx_11_0_x86_64
x86_64-windows win_amd64
aarch64-windows win_arm64

Project Structure

my_extension/
├── pyproject.toml       # Python project config with [tool.zig-maturin]
├── build.zig            # Zig build file
├── build.zig.zon        # Zig package manifest
├── src/
│   └── main.zig         # Your Zig extension code
└── dist/                # Built wheels (after zig-maturin build)

Requirements

  • Python 3.12+
  • Zig 0.14+ (tested with 0.16.0)
  • Linux, macOS, or Windows

License

MIT — Ricardo Robles Fernández

Related Projects

  • Maturin — Build and publish Rust-powered Python extensions
  • PyO3 — Rust bindings for Python
  • zig-python — Python C-API bindings for Zig

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

zig_maturin-0.1.0.tar.gz (11.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

zig_maturin-0.1.0-py3-none-any.whl (14.7 kB view details)

Uploaded Python 3

File details

Details for the file zig_maturin-0.1.0.tar.gz.

File metadata

  • Download URL: zig_maturin-0.1.0.tar.gz
  • Upload date:
  • Size: 11.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for zig_maturin-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c14161c690925946dd694310749fbeda4aac5de9a300c82a2467746d5afdb427
MD5 294777f6b2fc30f7ecab434b11dada03
BLAKE2b-256 791438b53907dfa43368af24afdf27d04bb640ecb9192fc4100b39b803ef007b

See more details on using hashes here.

Provenance

The following attestation bundles were made for zig_maturin-0.1.0.tar.gz:

Publisher: release.yml on rroblf01/zig-maturin

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file zig_maturin-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: zig_maturin-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 14.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for zig_maturin-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 410d982a73c7f9ef47bee3ae879dbbb2912aa83e5a37675fd87c3b051aeddf31
MD5 a0e11de83799b180154e99be8bfc0d55
BLAKE2b-256 c5c5a3d12a260d7403bb1fa73ef14628591a091a2866f354bf8bfb150f300b69

See more details on using hashes here.

Provenance

The following attestation bundles were made for zig_maturin-0.1.0-py3-none-any.whl:

Publisher: release.yml on rroblf01/zig-maturin

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page