Ship your Python, Node.js, or PHP app as one file. No installers. No runtimes. No surprises.
UBuilder takes your scripting-language project and produces a single
self-contained executable. Hand that file to anyone — your customer,
your CI runner, a fresh VM — and it just runs. They don't need Python.
They don't need Node. They don't need PHP, pip, npm, or
composer. They don't even need to know what language you wrote it in.
cd my-app/ # your project, just main.py and (optionally) requirements.txt
ubuilder # one command. no flags needed.
./dist/my-app # ships anywhere on the same OS — fully standaloneThat's the whole pitch.
- Zero-friction distribution. Email it, drop it on a USB stick, put it in a Docker
FROM scratch— the bundle has no external dependencies. - Hermetic by design. The build pulls pinned interpreter tarballs into a local cache once, then embeds them into every bundle. Your users get the exact runtime you tested against.
- Tiny mental model. A
ubuilder.jsonis two lines. The first build writes it for you. Re-running needs zero flags. - Honest cross-platform. Linux and macOS bundles are fully hermetic, including PHP — the macOS PHP builder walks
otool -Land re-points every non-system dylib to live inside the bundle, so it runs on any Mac with nothing pre-installed. - Fast. Pure C11/C++17. The launcher is a few hundred KB; the bundle layout is
[launcher][runtime][app][SHA-256 trailer]and extraction is a single sequential read.
curl -L https://github.com/developersharif/ubuilder/releases/latest/download/ubuilder-linux-amd64.tar.gz | tar -xz
sudo mv ubuilder /usr/local/bin/
ubuilder --versioncurl -L https://github.com/developersharif/ubuilder/releases/latest/download/ubuilder-macos-amd64.tar.gz | tar -xz
sudo mv ubuilder /usr/local/bin/
xattr -d com.apple.quarantine /usr/local/bin/ubuilder 2>/dev/null || true
ubuilder --version$url = "https://github.com/developersharif/ubuilder/releases/latest/download/ubuilder-windows-amd64.zip"
Invoke-WebRequest -Uri $url -OutFile "$env:TEMP\ubuilder.zip"
Expand-Archive -Path "$env:TEMP\ubuilder.zip" -DestinationPath "$env:USERPROFILE\ubuilder" -Force
$env:Path += ";$env:USERPROFILE\ubuilder"
ubuilder --versionNeeds CMake ≥ 3.16, a C11/C++17 compiler, and zlib headers.
git clone https://github.com/developersharif/ubuilder.git
cd ubuilder && mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release .. && cmake --build . -jPick a runtime. Each example is a complete, runnable session.
mkdir hello && cd hello
echo 'print("Hello from a single-file Python app")' > main.py
ubuilder # auto-writes ubuilder.json on the first run
./dist/helloWith dependencies, just add a requirements.txt — ubuilder will pip install them into the bundle.
mkdir hello && cd hello
echo 'console.log("Hello from a single-file Node app")' > main.js
echo '{"runtime":"node","entry_point":"main.js"}' > ubuilder.json
ubuilder
./dist/helloAdd a package.json and ubuilder will npm install for you.
mkdir hello && cd hello
echo '<?php echo "Hello from a single-file PHP app\n";' > main.php
echo '{"runtime":"php","entry_point":"main.php"}' > ubuilder.json
ubuilder
./dist/helloFor minimal PHP bundles (~50–80 MB instead of 280–400 MB), use the curated static build:
ubuilder --runtime=php --php-runtime=static# Trim files out of the bundle
ubuilder --exclude='tests/**' --exclude='*.md'
# Drop a dependency from the install
ubuilder --exclude=six # Python
ubuilder --exclude=is-number # Node
ubuilder --exclude=ext-curl # PHP
# Pick where the output goes
ubuilder --output=/opt/builds/myapp
# See what it's doing
ubuilder --verbose
# Upgrade yourself
ubuilder --self-updateThe full flag list is in ubuilder --help.
Everything else — full CLI reference, the ubuilder.json schema, guides
per runtime, architecture overview, troubleshooting — lives in
the docs.
| Runtime | Linux | macOS | Windows |
|---|---|---|---|
| Python | Hermetic | Hermetic | Host |
| Node.js | Hermetic | Hermetic | Host |
| PHP | Host-bits hermetic | Fresh-Mac portable | Host |
Hermetic means the bundle ships its own interpreter and runs on a clean machine with nothing pre-installed. Host means the bundle uses the target machine's interpreter — works fine for dev, not yet for distribution. Hermetic Windows is on the roadmap and a great place to contribute.
UBuilder is one C binary that operates in two modes, decided at startup:
- Build mode (no payload attached) parses your project, picks the
right runtime builder, installs your dependencies into a staged
copy, and writes a new executable laid out as
[ubuilder launcher][runtime tree][app tree][V4 trailer with SHA-256]. - Launcher mode (payload present) detects the trailer, verifies
the SHA-256, extracts everything to a temp directory,
execs the embedded interpreter against the embedded entry point, and cleans up on exit.
Successful dependency installs are content-addressed by SHA-256 of your manifest + lockfile and replayed from cache on the next build — so re-running is fast and reproducible.
UBuilder is built by one developer and a small group of contributors who care a lot about making distribution boring. If that sounds fun, jump in.
A typical loop:
git clone https://github.com/developersharif/ubuilder.git
cd ubuilder && mkdir build && cd build
cmake .. && cmake --build . -j
./tests/test_ubuilder # all green before you change anythingGood first issues live on the issue tracker. High-impact areas right now:
- Hermetic Windows runtimes — vendor a portable Python / Node tree the way Linux and macOS already do.
- Fully hermetic PHP on Linux — port the macOS dylib-rewiring trick to ELF (
lddwalk +DT_RUNPATH=$ORIGIN/../lib). - Lockfile reproducibility for Python and PHP.
- More example apps — Flask, Express, Laravel, Discord bots, anything that proves the "one file, ships anywhere" idea.
Setup details, code conventions, and PR workflow are in CONTRIBUTING.md.
MIT — see LICENSE. Use it, fork it, ship it.