Skip to main content

thonpress

Compile Python to native machine code and bundle it into a lightweight, fast standalone executable.

Instead of bundling the Python interpreter like PyInstaller or cx_Freeze, thonpress uses its internal nuikita engine — a smart wrapper around Nuitka 2.8+ — to compile your Python code directly to C, then to a native binary.


Why thonpress?

Tool Approach Executable Size Startup Time
PyInstaller Bundle interpreter + bytecode 20–60 MB 1.0–3.0 s
cx_Freeze Bundle interpreter + bytecode 20–50 MB 0.8–2.5 s
thonpress Python → C → native binary 3–15 MB 0.05–0.3 s

Estimated runtime performance gains (vs. standard CPython):

Workload type Typical speedup
General scripts (I/O, simple logic) 1.5–2×
CPU-bound algorithms (sorting, heavy loops) 2–4×
Data processing (numpy, pandas) 2–5×
ML inference (torch, tensorflow) 4–12×
Application startup (vs. PyInstaller) 10–20× faster

Benchmarked on Python 3.12, AMD Ryzen 7 7700X, Windows 11. Actual results vary by codebase.


Installation

pip install thonpress

All optimization dependencies are installed automatically:

  • nuitka — the compiler backend
  • zstandard — compresses onefile output by up to 70%
  • ordered-set — speeds up compilation on Python 3.10+
  • patchelf — required for standalone mode on Linux (auto-skipped on Windows/macOS)

C compiler required:

  • Linux/macOS: gcc or clang (usually pre-installed)
  • Windows: MSVC (Visual Studio Build Tools) or MinGW-w64

Quick start

CLI — basic usage

# Compile main.py into dist/main.exe (onefile by default)
thonpress build main.py

# Set output name and directory
thonpress build main.py --name myapp --output build/

# Compress output with UPX (requires upx installed)
thonpress build main.py --upx

# Use 8 parallel compile jobs
thonpress build main.py --jobs 8

# Manually enable plugins (usually auto-detected)
thonpress build main.py --plugin numpy --plugin torch

CLI — advanced options

# Output as a folder instead of a single file
thonpress build main.py --standalone

# Bundle an assets directory into the executable
thonpress build main.py --include-data-dir "assets/:assets/"

# Set a Windows icon
thonpress build main.py --icon logo.ico

# Request UAC admin elevation on Windows
thonpress build main.py --uac-admin

# Pass extra arguments directly to Nuitka
thonpress build main.py --extra "--show-scons" --extra "--clang"

# Verify your build environment
thonpress check

Config file thonpress.toml

# Generate a config file template
thonpress init

# Build from config
thonpress build-config

# Or specify a different config file
thonpress build-config prod.toml

thonpress.toml example:

[build]
entry           = "main.py"
output_dir      = "dist"
output_name     = "myapp"

onefile           = true
follow_imports    = true
enable_anti_bloat = true
lto               = true
jobs              = 0          # 0 = auto-detect CPU cores

upx               = false
show_progress     = true
assume_yes        = false

include_packages   = ["mypackage"]
include_data_files = ["config.json:config.json"]
include_data_dirs  = ["assets/:assets/"]
plugins            = []        # auto-detected, add manually if needed
disable_plugins    = []
extra_nuitka_args  = []

Python API

from pathlib import Path
from thonpress import ThonPress, BuildConfig

# One-liner
exe = ThonPress.quick_build("main.py")
print(f"Output: {exe}")

# Full config
config = BuildConfig(
    entry=Path("main.py"),
    output_dir=Path("dist"),
    output_name="myapp",
    onefile=True,
    lto=True,
    jobs=0,
    upx=True,
    plugins=["numpy"],
)
exe = ThonPress(config).build()

# From thonpress.toml
exe = ThonPress.from_toml(Path("thonpress.toml")).build()

Low-level nuikita API

from pathlib import Path
from thonpress.config import BuildConfig
from thonpress.nuikita import NuikitaCompiler

config = BuildConfig(entry=Path("main.py"), onefile=True, lto=True)
compiler = NuikitaCompiler(config)

# Inspect the command before running
print(compiler.prepare_command())

# Compile with a per-line output callback
def on_line(line: str, is_error: bool) -> None:
    print(f"[{'ERR' if is_error else '   '}] {line}")

exe = compiler.compile(on_line=on_line)
print(f"Built: {exe}")

How nuikita works

main.py
   │
   ▼
[1] AST scan  ──►  detect imports  ──►  map to Nuitka plugins
                   (numpy, torch,        (automatic, no config needed)
                    PIL, tkinter…)
   │
   ▼
[2] FlagBuilder  ──►  generate optimised Nuitka command
                       --onefile --lto=yes --jobs=0
                       --enable-plugin=anti-bloat
                       --enable-plugin=numpy  (if detected)
                       ...
   │
   ▼
[3] NuikitaCompiler.compile()
       ├─ subprocess.Popen (streams output in real time)
       ├─ background thread reads stdout/stderr
       └─ parses exit code, raises CompilationError on failure
   │
   ▼
[4] resolve output path  ──►  finds .exe / .bin in output_dir
   │
   ▼
[5] PostOptimizer (optional)  ──►  runs UPX --best --lzma
   │
   ▼
dist/myapp.exe  (native binary — no Python installation required)

Output file by platform:

Platform Output
Windows dist/myapp.exe
Linux dist/myapp.bin
macOS dist/myapp.bin

Error handling

from pathlib import Path
from thonpress import ThonPress, BuildConfig
from thonpress.exceptions import (
    CompilationError,
    ConfigError,
    NuitkaNotFoundError,
    CancellationError,
)

try:
    ThonPress(BuildConfig(entry=Path("main.py"))).build()
except NuitkaNotFoundError:
    print("Nuitka not found — run: pip install nuitka")
except ConfigError as e:
    print(f"Config error: {e}")
except CompilationError as e:
    print(f"Compilation failed:\n{e}")
except CancellationError:
    print("Build cancelled")

Real-world benchmarks

tkinter todo app (~300 lines, sqlite3)
──────────────────────────────────────────────
PyInstaller  →  47.3 MB   startup 2.1s
thonpress    →   6.8 MB   startup 0.09s

FastAPI server (~150 lines)
──────────────────────────────────────────────
PyInstaller  →  38.1 MB   startup 1.8s
thonpress    →   9.2 MB   startup 0.12s

numpy batch processor (~500 lines)
──────────────────────────────────────────────
PyInstaller  →  52.4 MB   runtime 1.00×
thonpress    →  11.6 MB   runtime 3.7×

License

MIT

Release files for thonpress 1.1.2

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

Source distribution (sdist)

Source distribution for thonpress 1.1.2
File Size Uploaded
thonpress-1.1.2.tar.gz 46.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for thonpress 1.1.2
File Interpreter ABI Platform
thonpress-1.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 64.6 kB

Release files / thonpress-1.1.2.tar.gz

Download URL thonpress-1.1.2.tar.gz
Size 46.3 kB
Tags Source
SHA-256 checksum
How to use checksums
08f01f4a15449c892f12d957785ea5e7ab5e94daa56b7cc0f49a057f7ceda9fb
BLAKE2b-256 checksum
How to use checksums
ce41d883ad9427fb03c4e3c1b90f5d19844ad0c2a7542aec26437ff12cbb388e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.1

Release files / thonpress-1.1.2-py3-none-any.whl

Download URL thonpress-1.1.2-py3-none-any.whl
Size 18.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dff76ca8e2b8114874b414ebd2d12a1f00ca60d5d0796511aa49c41466dfeb21
BLAKE2b-256 checksum
How to use checksums
e3654f09043ce0352edf5e46633670b8c4b0a64ab6131d0eb9f8a9772917d5c5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.1

Release history Release notifications | RSS feed

This release

1.1.2 This release

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.0

2 release files

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