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 backendzstandard— 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:
gccorclang(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)
| File | Size | Uploaded | |
|---|---|---|---|
| thonpress-1.1.2.tar.gz | 46.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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
|