Skip to content

Build Output

By default pure build writes the downloaded binary to the current directory, named after the entry file without its extension:

| Entry file | Default output | |---|---| | server.ts | ./server | | src/main.ts | ./main | | cli/index.js | ./index |

Pass -o/--out to choose an exact path:

Terminal window
pure build src/main.ts --out dist/myapp

The binary is written with mode 0755, so it’s immediately executable:

Terminal window
./dist/myapp

If a file already exists at the target path (the default -o or an explicit one), pure doesn’t overwrite it — it appends a " (n)" suffix before the extension, the same convention Windows Explorer uses for a pasted duplicate file: hello → hello (1) → hello (2), and so on. The final message tells you which path it actually wrote to:

Wrote ./hello (1) (3 work units) (./hello already existed)

Pass -f/--force to overwrite the target path instead, for scripts/CI that want the same fixed path every run:

Terminal window
pure build src/main.ts --out dist/myapp --force

Builds run in the cloud, so the machine you run pure build from doesn’t determine the output by itself — pass --platform to choose, or let it default to your own machine’s OS and architecture. Linux (x86_64 or arm64) is the default and most battle-tested target; macOS output Experimental is available too. Windows isn’t available yet.

By default, a Linux binary is a fully static musl build with no runtime dependency on the host’s C library — it runs unmodified on Alpine, inside a FROM scratch container, or on any Linux host. Pass --libc glibc if you need a dynamically-linked glibc binary instead. See Language → OS support for the full platform matrix and macOS caveats.

Release binaries include the Pure runtime. Typical sizes:

| Workload | Approximate size | |---|---| | Hello world | ~2 MB | | HTTP server | ~4–6 MB | | Complex CLI with deps | ~10–20 MB |

Every build is an optimised release build and is already stripped of debug symbols automatically — no extra step needed.

Pure binaries start fast because there is no module resolution, cache warm-up, or JIT compilation at startup. Typical cold start times:

| Workload | Approximate cold start | |---|---| | Hello world | < 5 ms | | HTTP server (first request) | < 20 ms | | CLI with heavy initialization | 30–100 ms |

These are wall-clock measurements on commodity hardware. Actual times depend on binary size, filesystem speed, and system load.

Standard POSIX signals work: SIGINT, SIGTERM, SIGHUP, SIGUSR1, SIGUSR2. Register handlers via process.on('SIGTERM', ...) as you would in Node.

Passing --target node-addon produces a Node.js native addon instead of a standalone executable. The downloaded artifact (written to --out) is an installable npm tarball that you install like any other package:

Terminal window
pure build src/index.ts --target node-addon --out ./mypkg.tgz
npm install ./mypkg.tgz

The tarball contains the compiled .node addon, a small index.js shim, the preserved TypeScript types, and a package.json whose name and version are inherited from your project. --target node-addon therefore requires a package.json at or above your entry file.

Once installed, consumers require() it as usual:

const mypkg = require('mypkg');