Skip to main content

UVBOX

Fast, simple and cross-platform Python application packaging

Package your Python apps as self-bootstrapping executables for every platforms.

Go Python

Linux MacOS Windows

Features • Comparison • Quick Start • Configuration • How It Works • Advanced Usage • Examples


What is uvbox?

uvbox generates standalone executables that bootstrap an embedded uv installation to automatically setup and run your Python application in a fully isolated environment — for any platform, from any platform.

Python is not required on the target system to run your application. The binary handles everything: downloads the right Python version, creates a virtual environment, installs dependencies, and runs your application.

uvbox demo

Features

  • Package from PyPI or Wheels — Install your application from package indexes or choose to bundle local wheel files
  • True Cross-Compilation — Build binaries for Linux, macOS, and Windows (AMD64/ARM64) from any platform in seconds
  • Auto-Updates — Built-in version checking and self-update/fallback capabilities for your binaries
  • Dependency Freezing — Use constraints files to ensure reproducible installations
  • Enterprise-Friendly — Support for custom registries, mirrors, and CA certificates
  • Fast — Powered by Go, builds complete in very few seconds
  • Simple Integration — Add as a dev dependency to your Python project

Comparison

Feature uvbox pyapp PyInstaller
Build Time ~1s ~30s ~1-5min
Cross-Compilation ✅ All platforms from any platform ⚠️ Requires target toolchains ❌ Native only
macOS from Linux/Windows ✅ Out of the box ❌ Forbidden by Apple license ❌ Forbidden by Apple license
Updates ✅ Built-in ✅ Built-in ❌ Manual
Fallbacks ✅ Version fallback support ❌ Not supported ❌ Not supported
Distribution ⚠️ Downloads at first run ⚠️ Downloads at first run ✅ Bundles everything (offline-ready)

🎯 Choosing the right tool:

uvbox excels at fast, cross-platform builds with minimal setup, built-in automatic updates, and version fallback mechanisms. It downloads dependencies at first run, making binaries small but requiring internet connectivity initially.

PyInstaller bundles everything into the binary, creating larger files but ensuring complete offline functionality and maximum stability (no runtime network dependencies). However, it requires native builds per platform and lacks built-in update mechanisms.

💡 Use uvbox when: You want fast builds, easy cross-compilation, or when enforced updates/fallbacks may be required, and don't mind first-run downloads.

💡 Use PyInstaller when: You need guaranteed offline functionality, distribute in air-gapped environments, or only target a single platform (especially Linux-only deployments).

Quick Start

Installation

Add uvbox to your project from PyPI:

# With uv
uv add --dev uvbox

# With pip
pip install uvbox

[!NOTE] Installing from PyPI automatically includes Go and nfpm as dependencies, so you don't need to install them separately.

Basic Usage

Create a simple configuration and build:

# Create a minimal config file
cat > uvbox.toml <<EOF
[package]
name = "cowsay"
script = "cowsay"
EOF

# Build for all platforms
uvbox pypi --config uvbox.toml

# Output:
# ✓ DARWIN/AMD64 → cowsay-x86_64-apple-darwin.tar.gz
# ✓ DARWIN/ARM64 → cowsay-aarch64-apple-darwin.tar.gz
# ✓ LINUX/AMD64 → cowsay-x86_64-unknown-linux-gnu.tar.gz
# ✓ LINUX/ARM64 → cowsay-aarch64-unknown-linux-gnu.tar.gz
# ✓ WINDOWS/AMD64 → cowsay-x86_64-pc-windows-msvc.zip

Your executables are now in the dist/ directory!

Build from Wheels

Package local wheel files instead of installing from PyPI:

uvbox wheel --config uvbox.toml ./my-app.whl

Configuration

Using pyproject.toml

Embed configuration directly in your Python project:

[tool.uvbox.package]
name = "my-awesome-app"
script = "main"  # Entry point from your package

[tool.uvbox.package.version]
dynamic = "https://example.com/my-app/version.txt"  # Fetch version from URL
static = "1.0.0"  # Fallback version if dynamic fetch fails
auto-update = true

# Optional: Constrain dependencies
[tool.uvbox.package.constraints]
dynamic = "https://example.com/my-app/<VERSION>/constraints.txt"

# uv index and mirror configuration will be automatically be used
[[tool.uv.index]]
name = "company-pypi"
url = "https://my.artifactory.com/artifactory/api/pypi/pypi-mirror/simple"
default = true

[tool.uv]
python-install-mirror = "https://my.github.remote/astral-sh/python-build-standalone/releases/download"

Then build directly from your project directory:

# uvbox automatically detects pyproject.toml
uvbox pypi

Using Standalone Config Files

Create a dedicated uvbox.toml file:

[package]
name = "my-app"
script = "my_entrypoint"

[package.version]
# Pin to specific version
static = "2.1.0"
# Or use dynamic version from URL
dynamic = "https://example.com/my-app/version.txt"
# Enable automatic updates before each run
auto-update = true

[package.constraints]
# Freeze dependencies with a constraints file
# <VERSION> placeholder is automatically replaced
dynamic = "https://example.com/my-app/<VERSION>/constraints.txt"

# Or use a static constraints file
static = "./constraints.txt"

[certificates]
# Bundle custom CA certificates (useful behind corporate firewalls)
path = "./ca-bundle.crt"

[uv]
# Optional: Specify which uv version to use
version = "0.11.6"
# Optional: Use a mirror for downloading uv itself
mirror = "https://mirror.example.com/uv/releases/download"
# Configure uv runtime behavior with environment variables
environment = [
    "UV_INDEX_URL=https://pypi.example.com/simple",
    "UV_PYTHON=3.12",
    "UV_PYTHON_INSTALL_MIRROR=https://mirror.example.com/python-builds"
]

Configuration Reference

[package]

Core package configuration.

  • name (required) — Package name to install from PyPI
  • script (required) — Entry point script to run (from [project.scripts] in your package)

[package.version]

Version management and updates.

  • static — Pin to a specific version (e.g., "1.2.3")
  • dynamic — URL to a text file containing the version to install
  • auto-update — Check for updates before each run (may slow startup)

[package.constraints]

Dependency freezing for reproducible installs.

  • static — Path to local constraints file
  • dynamic — URL to remote constraints file (supports <VERSION> placeholder)

[certificates]

Bundle custom CA certificates.

  • path — Path to certificate bundle (relative to working directory)

The binary automatically sets REQUESTS_CA_BUNDLE and SSL_CERT_FILE environment variables.

[uv]

Configure uv installation and behavior.

  • version — Specific uv version to download and use (e.g., "0.11.6")
  • mirror — Alternative download URL for uv releases (e.g., "https://mirror.example.com/uv/releases/download")
  • environment — Array of environment variables to set for uv runtime behavior

See uv's documentation for available environment variables.

Config File Discovery

uvbox automatically searches for configuration files:

  1. Explicit path via --config flag
  2. uvbox.toml in current directory or parents
  3. pyproject.toml with [tool.uvbox] section in current directory or parents

How It Works

uvbox leverages Go's powerful cross-compilation to create lightweight executables that:

  1. Embed uv — Each binary contains the uv installation URL and configuration
  2. Bootstrap on First Run — Downloads and extracts uv to an isolated XDG-compliant directory
  3. Install Your App — Uses uv tool install to set up your package and dependencies in complete isolation
  4. Run — Executes your application's entry point with the configured environment

All files are stored in XDG-compliant directories ($XDG_DATA_HOME/uvbox/ or ~/.local/share/uvbox/ by default), ensuring a clean and standardized file system layout.

Why Go?

  • Fast Compilation — ~1 second vs ~30 seconds for Rust-based alternatives
  • Cross-compilation out of the box — Build macOS binaries from Linux/Windows without licenses or complex toolchains
  • No dependencies — Just set GOOS and GOARCH environment variables
  • Compiles into static binary — Just a single executable, with no runtime dependencies

Runtime Behavior

When a user runs your binary:

./my-app --help

The first run automatically:

  1. Extracts embedded uv to $XDG_DATA_HOME/uvbox/<identifier>/uv/ (defaults to ~/.local/share/uvbox/<identifier>/uv/)
  2. Downloads Python if needed to $XDG_DATA_HOME/uvbox/<identifier>/python/ (defaults to ~/.local/share/uvbox/<identifier>/python/)
  3. Installs your package in an isolated environment at $XDG_DATA_HOME/uvbox/<identifier>/tools/ (defaults to ~/.local/share/uvbox/<identifier>/tools/)
  4. Runs your script

Subsequent runs skip straight to execution (unless updates are configured).

[!NOTE] The <identifier> is a hash computed from your package name, script, and configuration to ensure complete isolation between different applications.

Built-in Commands

Every generated binary includes these self commands:

  • <app> self update — Update the package to the latest available version
  • <app> self remove — Remove installation (clean up installed files and virtual environment)
  • <app> self path — Display paths related to the installation
  • <app> self cache — Manage cache
  • <app> self uv — Run installation uv executable inside the isolated environment

Advanced Usage

Linux Package Generation

Generate .deb and .rpm packages alongside binaries:

# Create nfpm.yaml configuration
cat > nfpm.yaml <<EOF
name: my-app
maintainer: "Your Name <you@example.com>"
description: "My awesome application"
homepage: "https://github.com/you/my-app"
license: "MIT"

# Template variables
arch: ${UVBOX_ARCH}
platform: ${UVBOX_PLATFORM}
version: ${UVBOX_VERSION}

# Copy executable to target folder
contents:
  - src: ${UVBOX_BUILT_EXECUTABLE}
    dst: /usr/bin/my-app

# Built-in pre-remove script that ensures application data are removed
scripts:
  preremove: ./pre_remove.sh
EOF

# Build with packaging
uvbox pypi --nfpm nfpm.yaml --release-version 1.0.0

Available Template Variables:

uvbox provides environment variables for use in your nfpm configuration:

  • UVBOX_BUILT_EXECUTABLE — Absolute path to the compiled executable
  • UVBOX_NAME — Executable name (from script configuration)
  • UVBOX_PLATFORM — Target platform (linux, darwin, windows)
  • UVBOX_ARCH — Target architecture (amd64, arm64)
  • UVBOX_VERSION — Version from --release-version flag

Use them with ${VARIABLE_NAME} syntax in your nfpm.yaml.

[!TIP] The preremove: ./pre_remove.sh script is optional. If you include it in your nfpm configuration, uvbox automatically generates it to call <executable> self remove, which cleans up application data (virtual environments, cached Python installations) when the package is uninstalled.

Custom Registry Example

[package]
name = "internal-tool"
script = "tool"

[uv]
environment = [
    "UV_INDEX_URL=https://artifactory.company.com/api/pypi/pypi-mirror/simple",
    "UV_EXTRA_INDEX_URL=https://artifactory.company.com/api/pypi/internal-packages/simple",
    "UV_PYTHON_INSTALL_MIRROR=https://internal-mirror.company.com/python-builds"
]

[certificates]
path = "./company-ca-bundle.crt"

Version Fallback Strategy

Use dynamic versioning with fallback:

[package.version]
# Try to fetch latest version from URL
dynamic = "https://cdn.example.com/my-app/latest.txt"
# Fallback to this version if URL is unreachable
static = "1.0.0"
# Check for updates before each run
auto-update = true

Examples

See the examples/ directory for complete working examples:

Requirements

Build Time

  • Go 1.21+ (automatically fetched if installed via PyPI package)
  • nfpm (optional, only if generating .deb/.rpm packages)

Runtime (Generated Binaries)

  • libc (standard C library, required by Python itself)

License

MIT © 2025 Amadeus

Contributing

We welcome contributions!

Acknowledgments

Heavily inspired by the excellent pyapp project. Built with:

  • uv — Blazing fast Python package installer
  • Go — Enabling true cross-compilation magic
  • pyapp — Inspiration and reference implementation

Metadata

Release files for uvbox 1.0.9

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for uvbox 1.0.9
File Actions
uvbox-1.0.9-py3-none-win_arm64.whl Python 3 none Windows ARM64 Details for uvbox-1.0.9-py3-none-win_arm64.whl
uvbox-1.0.9-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details for uvbox-1.0.9-py3-none-win_amd64.whl
uvbox-1.0.9-py3-none-manylinux2014_x86_64.whl Python 3 none Linux glibc 2.17+ x86-64 Details for uvbox-1.0.9-py3-none-manylinux2014_x86_64.whl
uvbox-1.0.9-py3-none-manylinux2014_aarch64.whl Python 3 none Linux glibc 2.17+ ARM64 Details for uvbox-1.0.9-py3-none-manylinux2014_aarch64.whl
uvbox-1.0.9-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details for uvbox-1.0.9-py3-none-macosx_11_0_arm64.whl
uvbox-1.0.9-py3-none-macosx_10_9_x86_64.whl Python 3 none macOS 10.9+ x86-64 Details for uvbox-1.0.9-py3-none-macosx_10_9_x86_64.whl

Total release size: 23.9 MB

Release files / uvbox-1.0.9-py3-none-win_arm64.whl

Download URL uvbox-1.0.9-py3-none-win_arm64.whl
Size 3.8 MB
Tags Python 3 Windows ARM64
SHA-256 checksum
How to use checksums
4af7d1a24a4c52fce58015b2d0ee4af8ed4a4cce51044a26946a52dcdfff373c
BLAKE2b-256 checksum
How to use checksums
24c164a10ca751292e52404abebf932baee462881136c1c15d83bc143c4c3472
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 20, 2026.

Transparency log

Release files / uvbox-1.0.9-py3-none-win_amd64.whl

Download URL uvbox-1.0.9-py3-none-win_amd64.whl
Size 4.2 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
d1cc9757612aef48b186bf10e25293a42dc1c463d9bac1ae8bff4f446871da11
BLAKE2b-256 checksum
How to use checksums
015468af6620c373dd1246c10eeae89756ef74364490347b03b8798828fcdaf2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 20, 2026.

Transparency log

Release files / uvbox-1.0.9-py3-none-manylinux2014_x86_64.whl

Download URL uvbox-1.0.9-py3-none-manylinux2014_x86_64.whl
Size 4.1 MB
Tags Linux glibc 2.17+ x86-64 Python 3
SHA-256 checksum
How to use checksums
e667daef8ddf0df25ab5745a27347cf63baed16717afcda3d3b9a8c4072fbc4c
BLAKE2b-256 checksum
How to use checksums
2027f513d6dfe5999fed42bbd48c1f8a7c021f791581d28aa5e29dd85b7efc44
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 20, 2026.

Transparency log

Release files / uvbox-1.0.9-py3-none-manylinux2014_aarch64.whl

Download URL uvbox-1.0.9-py3-none-manylinux2014_aarch64.whl
Size 3.7 MB
Tags Linux glibc 2.17+ ARM64 Python 3
SHA-256 checksum
How to use checksums
328a76768cffa5e63c90432d564f92ef254c62eacf10f9e4a1992f4f90bf76c0
BLAKE2b-256 checksum
How to use checksums
00403d67b88b64e74459f87f6da0eba8cc6c3fe2cc5af008b9514c37742c6d07
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 20, 2026.

Transparency log

Release files / uvbox-1.0.9-py3-none-macosx_11_0_arm64.whl

Download URL uvbox-1.0.9-py3-none-macosx_11_0_arm64.whl
Size 3.8 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
6a940c1a97b9f6c03cfa49c0e8b1c443cef7cebbb5cc4caef346a8cb3c8755f8
BLAKE2b-256 checksum
How to use checksums
9378d2d72bf2ede1f4121e43e5becaadc655a89af0c470b149d43867587927f5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 20, 2026.

Transparency log

Release files / uvbox-1.0.9-py3-none-macosx_10_9_x86_64.whl

Download URL uvbox-1.0.9-py3-none-macosx_10_9_x86_64.whl
Size 4.2 MB
Tags Python 3 macOS 10.9+ x86-64
SHA-256 checksum
How to use checksums
e94fb7f77bc6fbdf9aa9f0287a2bb6a8ecc28cd1a7e268c22be5d251a3ac9cbc
BLAKE2b-256 checksum
How to use checksums
f2c13c3a26b800fdb23aa1964ce6b7b31802ad127a88caab1f3e074a385b6cc2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 20, 2026.

Transparency log

Security for uvbox 1.0.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 6 files in this release have been uploaded with provenance metadata.

Select from 6 files

Attestation for uvbox-1.0.9-py3-none-win_arm64.whl

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 20, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page