mrkeyoor.com_
Sun 20 Sept 07:00 UTC
PyPICLI & Toolingupdated 20 Sept 2026

build review

`build` 1.5.0 is PyPA's focused frontend for producing a source distribution and wheel from a Python project. It reads `[build-system]` in `pyproject.toml`, installs that backend's requirements in an isolated environment, and invokes the PEP 517 hooks. The backend still does the packaging work. Our Python 3.12 sandbox needed three installed packages and 1 MB for the tool, so it is a modest CI addition when Hatch, Poetry, PDM, or another project manager does not already own the release command. The 1.5.0 Python API also fixes handling of build requirements that are already installed.

Verdict

`build` 1.5.0 installed in 0.2 seconds and occupied 1 MB across three packages in our sandbox, with 0 pip-audit findings. Add it for a backend-neutral artifact step; leave it out when your existing Python project manager already produces and publishes the release files.

We installed it

Lab card: what happened when we installed buildScreenshot of build documentation
Install✓ · 0.2s3 packages on disk · 1 MB
Importimport build in 0.25s · pure Python · py.typed · requires Python >= 3.10
Known vulns0(pip-audit)

Answers from our run

Does build install cleanly?

Yes. In a fresh container with an empty cache, pip install build finished in 0.2s, leaving 3 packages and 1 MB on disk. pip-audit reported no known vulnerabilities.

What does build need to run?

Python >= 3.10, and nothing compiled: it is pure Python. In our run import build succeeded in 0.25s, and the package ships py.typed for type checkers.

build or hatch: which should you use?

hatch: Use it when environments, versioning, builds, and publishing should share one project tool. build 1.5.0 installed in 0.2 seconds and occupied 1 MB across three packages in our sandbox, with 0 pip-audit findings.

When should you not use build?

Hatch, Flit, Poetry, PDM, or uv already builds the same artifacts in your established workflow; another frontend adds no useful boundary.

API stability4/5Release 1.5.0 keeps the established `python -m build`, `pyproject-build`, `ProjectBuilder`, isolation, and backend-setting interfaces. The concrete upgrade boundary is Python itself: the supported floor moved to 3.10. The release also changes Python API behavior around requirements already present in an environment, which is a fix but still deserves a check in custom release wrappers.
Docs4/5The official documentation gives separate references for the CLI, `ProjectBuilder`, isolated environments, backend configuration, and the changelog. Its README states that the default wheel comes from the sdist and explains pipx, uv, cibuildwheel, and conda-forge commands. It expects readers to know the difference between a PEP 517 frontend and backend, so first-time packagers need the packaging guide beside it.
Maintenance5/5The unarchived PyPA repository was pushed on 2026-08-24, GitHub currently reports seven open issues and pull requests, and PyPI serves version 1.5.0. That release moved the interpreter floor to Python 3.10 and corrected installed-requirement handling in the API. The small queue and recent repository activity are strong signals, though GitHub's combined count is not a count of unresolved bugs.
Ecosystem5/5The package recorded 30,403,064 weekly downloads in the supplied registry snapshot, and GitHub reports 854 stars. More relevant than either popularity figure, it delegates to the PEP 517 backend selected by each project, so one frontend works with setuptools, Hatchling, Flit, and other compliant backends. Official recipes cover pipx, uv, cibuildwheel 3.0+, and the python-build conda-forge package.

Use it if

  • CI needs one command that works across setuptools, Hatchling, Flit, and other PEP 517 backends.
  • You want the release wheel built from the sdist so missing files in the source archive fail before upload.
  • Build requirements should be isolated from whatever happens to be installed in a developer or runner environment.
  • A release script needs `ProjectBuilder` to choose artifact type, destination, and backend settings programmatically.
Skip it if

Setup reality

We installed build 1.5.0 in a fresh Python 3.12 Bookworm container. Installation succeeded in 0.2 seconds, and the environment held three packages using 1 MB afterward. pip-audit found 0 known vulnerabilities. Our package inspection counted nine direct dependency declarations, confirmed pure Python code and py.typed, and loaded import build in 0.25 seconds. The measured metadata did not identify a license.

The command has no credentials file. Your project needs a valid [build-system] table in pyproject.toml, including the backend and its requirements. python -m build creates an isolated environment, installs those requirements, then writes an sdist and a wheel to dist/. The pyproject-build console command reaches the same frontend. Version 1.5.0 now lets Python API callers account correctly for requirements already installed in their chosen environment.

Isolation can trigger network access after the frontend itself is present. For an offline runner, provision every backend requirement first and use --no-isolation. Dependency checking remains useful there because it reports absent or incompatible requirements before a backend hook runs. --skip-dependency-check suppresses that early warning. The optional uv installer works only when uv is on PATH or supplied through the uv extra.

A normal invocation builds the wheel from the newly created sdist, which catches packages that forgot to include source files. --wheel instead builds directly from the working tree. Settings supplied with -C or --config-json pass untouched to the backend, and setuptools accepts only some of them. No command here tests, signs, or uploads the artifacts, so release automation still needs those explicit stages.

Patterns

Build an sdist and wheel build-release-artifacts

python -m build

The default creates both files and deliberately builds the wheel from the generated sdist.

Build only a wheel build-wheel-only

python -m build --wheel

This skips the sdist check and builds the wheel straight from the source directory.

Build only an sdist build-sdist-only

python -m build --sdist

The result is only the source archive; no wheel appears unless a later step builds one.

Write artifacts to a CI directory choose-output-directory

python -m build --outdir build-artifacts/ .

The trailing dot names the source tree, while `--outdir` changes the artifact destination.

Run without a persistent install run-with-pipx

pipx run build

pipx gives the frontend its own temporary tool environment instead of adding it to application dependencies.

Use uv inside the isolated build use-uv-installer

pipx run 'build[uv]' --installer uv

The `uv` extra makes uv available, and `--installer uv` applies only to isolated requirement installation.

Use preinstalled build requirements disable-isolation

python -m build --no-isolation

Every backend requirement must already exist in the active Python environment.

Bypass the non-isolated requirement check skip-dependency-check

python -m build --no-isolation --skip-dependency-check

A missing backend package can then appear later as an import or hook failure.

Send a setting to the backend pass-backend-setting

python -m build -Cbuild-option=--verbose

`build` forwards this value unchanged; only the selected backend can define or accept it.

Send structured backend settings pass-json-settings

python -m build --config-json '{"setup-args":["-Dfeature=true"]}'

Version 1.5.0 rejects using `--config-json` together with any `-C` option.

Print build metadata as JSON read-project-metadata

python -m build --metadata | jq -r .version

Metadata mode emits JSON and cannot be combined with `--sdist` or `--wheel`.

Create a wheel through ProjectBuilder build-with-python-api

from build import ProjectBuilder

builder = ProjectBuilder('.')
missing = builder.check_dependencies('wheel')
if missing:
    raise RuntimeError(missing)
wheel = builder.build('wheel', 'dist')
print(wheel)

`ProjectBuilder` here uses the current environment, so satisfy the wheel requirements before calling `build()`.

Alternatives

PackageRegistryPick it when
hatchPyPIUse it when environments, versioning, builds, and publishing should share one project tool.
flitPyPIUse it for a small pure-Python package with a short build and publish path.
poetryPyPIUse it when dependency locking and publishing already run through Poetry.
pdmPyPIUse it when PDM already manages dependencies, scripts, environments, and releases.

More cli & tooling guides

commander · chalk · typescript · esbuild · yargs · click · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.