Configuration¶
Configuration is resolved in three layers, each overriding the one before it.
1. [tool.maturin]¶
Describes what the crate is: manifest-path, module-name, python-source, bindings,
include, and the rest of maturin's own schema. This plugin never reparses that table — it passes
the project root to maturin and lets maturin resolve its own configuration.
The practical consequence is that the table stays valid if you switch back to
build-backend = "maturin", and that maturin build on the command line keeps working unchanged.
2. [tool.hatch.build.targets.<target>.hooks.maturin]¶
Describes how this build target compiles it. These are the knobs that legitimately vary per target or per matrix entry, so hatch owns them.
Options may also be set once for every target under [tool.hatch.build.hooks.maturin]; the
target-specific table wins on conflict.
Crate location¶
| Option | Type | Default | maturin flag |
|---|---|---|---|
manifest-path |
str |
Cargo.toml |
--manifest-path |
target-dir |
str |
cargo default | --target-dir |
manifest-path is resolved relative to the project root.
Compilation¶
| Option | Type | Default | maturin flag |
|---|---|---|---|
profile |
str |
release |
--profile |
target |
str |
host | --target |
jobs |
int |
cargo default | --jobs |
features |
list[str] |
[] |
--features (repeated) |
all-features |
bool |
false |
--all-features |
no-default-features |
bool |
false |
--no-default-features |
config |
list[str] |
[] |
--config (repeated) |
locked |
bool |
false |
--locked |
frozen |
bool |
false |
--frozen |
offline |
bool |
false |
--offline |
profile defaults to release
Bare maturin build produces a debug build, but a PEP 517 build is expected to be optimized.
The default here matches what maturin's own backend does in pep517.rs.
Packaging¶
| Option | Type | Default | maturin flag |
|---|---|---|---|
bindings |
str |
auto | --bindings |
compatibility |
list[str] |
auto | --compatibility (repeated) |
auditwheel |
str |
maturin default | --auditwheel |
generate-stubs |
bool |
false |
--generate-stubs |
include-debuginfo |
bool |
false |
--include-debuginfo |
strip |
bool |
false |
--strip |
zig |
bool |
false |
--zig |
Setting zig = true makes the hook declare ziglang as a build dependency through
BuildHookInterface.dependencies(), so it is installed into the build environment automatically.
Leave auditwheel alone unless you know why
On Linux maturin defaults to repair, which is what determines the manylinux/musllinux platform
tag the wheel is given and bundles any external shared libraries. Setting it to skip produces a
wheel whose tag is a guess.
Escape hatches¶
| Option | Type | Default | Effect |
|---|---|---|---|
args |
list[str] |
[] |
appended to the maturin command verbatim |
executable |
str |
auto | path to the maturin binary |
interpreter |
str |
sys.executable |
--interpreter |
sdist-include |
list[str] |
[] |
extra project files to force into the sdist |
Unknown options are an error rather than a silent no-op:
Unknown option(s) for build hook `maturin`: relase
Arbitrary maturin flags go through the `args` option.
3. Environment variables¶
hatchling discards PEP 517 config_settings entirely — every hook in hatchling/build.py marks the
parameter unused — so pip install --config-settings=profile=dev . cannot reach a build hook.
Environment variables are the only channel that works identically through pip, build, and uv.
| Variable | Overrides |
|---|---|
HATCH_MATURIN_PROFILE |
profile |
HATCH_MATURIN_TARGET |
target |
HATCH_MATURIN_BINDINGS |
bindings |
HATCH_MATURIN_FEATURES |
features (comma- or space-separated) |
HATCH_MATURIN_ARGS |
appended flags, shell-split |
HATCH_MATURIN_EXECUTABLE |
path to the maturin binary |
HATCH_MATURIN_PROFILE=dev pip install --no-build-isolation -e .
Cargo's own variables (CARGO_BUILD_TARGET, CARGO_TARGET_DIR, RUSTFLAGS, …) are read by cargo
directly and need no support from this plugin.
Inside hatch, prefer [tool.hatch.envs.<env>.env-vars] over exporting them by hand:
[tool.hatch.envs.dev.env-vars]
HATCH_MATURIN_PROFILE = "dev"
Worked example¶
[build-system]
requires = ["hatchling", "hatch-maturin-build"]
build-backend = "hatchling.build"
[project]
name = "mypkg"
dynamic = ["version"]
requires-python = ">=3.10"
[tool.maturin]
python-source = "python"
module-name = "mypkg.mypkg"
[tool.hatch.version]
path = "python/mypkg/__init__.py"
[tool.hatch.build.targets.wheel]
packages = ["python/mypkg"]
[tool.hatch.build.targets.wheel.hooks.maturin]
features = ["pyo3/abi3-py310"]
generate-stubs = true
[tool.hatch.build.targets.sdist.hooks.maturin]
sdist-include = ["build.rs"]