Skip to main content

Zero-friction Python app compiler: ship any Python project as a self-bootstrapping single-file binary.

Project description

Axe

Axe ships your Python app as a fully self-contained single-file binary — for every major platform, from any machine, with zero extra toolchain.

  • App developers need no Go, no cross-compilers, no Docker. Axe's wheel ships precompiled runtime stubs; axe build glues your app onto them.
  • App users need no Python, no uv, and no network. The binary embeds uv, CPython, and every dependency wheel; the first run unpacks them into a cached environment and every run after is instant. Corporate proxy, air-gap, TLS-intercepting middlebox — none of it matters.

Quick start

Your project needs to be an installable package with a console script — a project created with uv init --package is already set up correctly (a bare uv init app is not packaged; axe build will tell you what to add):

$ uv init --package mycli
$ cd mycli
$ uv add --dev axe
$ uv run axe build --all-platforms
built dist/bin/mycli-0.1.0-linux-amd64 (52 MB, python 3.12.13, 0 dependency wheels)
built dist/bin/mycli-0.1.0-linux-arm64 (50 MB, python 3.12.13, 0 dependency wheels)
built dist/bin/mycli-0.1.0-darwin-amd64 (48 MB, python 3.12.13, 0 dependency wheels)
built dist/bin/mycli-0.1.0-darwin-arm64 (47 MB, python 3.12.13, 0 dependency wheels)
built dist/bin/mycli-0.1.0-windows-amd64.exe (55 MB, python 3.12.13, 0 dependency wheels)

Hand the binary to anyone — nothing to install, nothing to download:

$ ./dist/bin/mycli-0.1.0-darwin-arm64
setting up mycli 0.1.0 (first run)...
done.
Hello from mycli!

$ ./dist/bin/mycli-0.1.0-darwin-arm64   # instant from now on
Hello from mycli!

A fuller example lives in examples/cowsay.

How it works

axe build assembles, per target platform, a payload containing everything a machine needs to run your app:

  • your project's wheel (built with uv),
  • every dependency wheel, resolved for that platform (uv pip compile --python-platform + pip download),
  • a pinned CPython from python-build-standalone,
  • a pinned uv,

and appends it to a small precompiled Go runtime stub. All artifacts are fetched once on the build machine (checksum-verified, cached), so builds after the first are seconds.

At first run the stub unpacks the embedded Python and uv, creates a venv, and installs the embedded wheels with --offline --no-index — the runtime contains no network code at all. Installations live in a per-app directory keyed by payload fingerprint, so a new binary version gets a fresh environment automatically. Subsequent runs are a single existence check, then execvp straight into your app.

Because dependencies are shipped as wheels, every dependency must publish a wheel for each target platform (pure-Python wheels cover all of them). Binaries weigh roughly 45–60 MB — that's a complete CPython plus uv; disk is cheap, broken installs are not.

Configuration

Everything is optional; defaults come from [project]:

[tool.axe]
entrypoint = "mycli"          # default: the sole [project.scripts] entry
                              # also accepts "-m pkg" or "pkg.mod:func"
python = "3.12"               # "3.X" picks the newest 3.X.*; "3.X.Y" pins
                              # default: lower bound of requires-python
uv-version = "0.10.6"         # uv embedded into the binary
python-release = "20260623"   # python-build-standalone release tag
expose = ["metadata"]         # extra `self` commands: python, python-path,
                              # cache, metadata — or "all"

CLI

$ axe build [PROJECT] [-o DIR] [-p OS/ARCH]... [--all-platforms] [-q | -v]
$ axe platforms

-q/--quiet prints nothing but errors; -v/--verbose streams the output of the underlying tools (useful behind corporate proxies — if downloads fail or stall there, set UV_NATIVE_TLS=1 so uv uses the system trust store).

Targets: linux/amd64, linux/arm64, darwin/amd64, darwin/arm64, windows/amd64.

Runtime management commands

Built binaries reserve one command group, self; everything else goes to your app:

$ myapp self remove    # wipe the installation
$ myapp self restore   # wipe and reinstall
$ myapp self update    # reinstall from the embedded payload

AXE=1 is set in your app's environment so it can detect axe installs, and AXE_DEBUG=1 makes the stub verbose.

Developing axe itself

This is the one place a Go toolchain is required:

$ python scripts/build_stubs.py   # cross-compile runtime stubs (needs go)
$ uv run pytest                   # unit + end-to-end tests (offline-verified)
$ cd runtime && go test ./...     # runtime unit tests
$ uv build                        # the wheel, stubs included

Design doc: docs/superpowers/specs/2026-07-07-axe-design.md.

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

axe-0.2.1.tar.gz (5.3 MB view details)

Uploaded Source

Built Distribution

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

axe-0.2.1-py3-none-any.whl (5.4 MB view details)

Uploaded Python 3

File details

Details for the file axe-0.2.1.tar.gz.

File metadata

  • Download URL: axe-0.2.1.tar.gz
  • Upload date:
  • Size: 5.3 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for axe-0.2.1.tar.gz
Algorithm Hash digest
SHA256 eb711624f336cc0510e55f53f4357d39670537ba723d4270f93618c28f481ff8
MD5 551cb1670710cc93e9502dcfdcea8ee8
BLAKE2b-256 b107d769ab137942ea4fd82a2b030741c3eb546772a10fc2d17d39f5f0fbd4fe

See more details on using hashes here.

Provenance

The following attestation bundles were made for axe-0.2.1.tar.gz:

Publisher: publish.yml on soasme/axe

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

File details

Details for the file axe-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: axe-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 5.4 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for axe-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 48483805935fa604180d77e491e5f33e4abf67c403fbff8d72979cb9a2ae7107
MD5 b1f0c7d3da8f967601e1b609937828e7
BLAKE2b-256 eb904ec6bcc2b7fa00d2f72616802a96b5c29551c8100c65f3c6f5b05f38484b

See more details on using hashes here.

Provenance

The following attestation bundles were made for axe-0.2.1-py3-none-any.whl:

Publisher: publish.yml on soasme/axe

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