| title | Custom Node.js binary |
|---|---|
| description | Use your own Node.js binary as the base for a pkg build — useful for custom metadata, security patches, or unusual architectures. |
By default pkg downloads a pre-compiled, patched Node.js binary from pkg-fetch and uses it as the base for every executable it creates. For most projects this is exactly what you want.
If you need a custom base binary — for an architecture not covered by pkg-fetch, a build with specific V8 flags, or a Node.js you've already patched for Windows metadata or corporate compliance — set PKG_NODE_PATH to point at it:
PKG_NODE_PATH=/path/to/node pkg app.jspkg will use that binary as the base instead of fetching one.
- Unsupported architectures —
pkg-fetchcovers Linux / macOS / Windows on x64 + arm64. For anything else (RISC-V, armv6, BSD), compile Node.js yourself or use apkg-binariesbuild. - Pre-embedded metadata — on Windows, you can compile a Node.js binary that already has your product name, icon, and version baked in. Then
pkg-ing your JS on top preserves it. See Windows metadata for an alternative post-processing approach. - Security policy — enterprises that pin Node.js to a specific internal build can feed it into
pkg. - Debug builds — a debug-enabled Node.js lets you attach a debugger to the packaged app in development.
- The binary must be a compatible Node.js version —
pkgstill injects its bootstrap prelude and payload, and depends on specific symbol offsets. Use a version supported bypkg-fetchunless you know what you're doing. PKG_NODE_PATHaffects a single target. In standard mode, multi-target builds still fetch the other platforms frompkg-fetchunless you set it per-run.- SEA mode honours
PKG_NODE_PATHtoo. Because SEA injects the payload into the supplied binary directly (there is no per-platform fetch fallback), a custom base binary there is restricted to a single target, and pkg validates the binary against it rather than baking a mismatched binary into the output: it runs the binary and checks what it reports —process.platformandprocess.archmust match the target (a macOS binary for alinuxtarget, or an x64 binary for anarm64target, is rejected), and its major version must match the target's. This means the custom base binary must be runnable on the build host (pkg already runs it to read its version). It also rejects targets that span more than oneplatform/arch(one binary can't be several at once — includinglinuxvsalpinevslinuxstatic, which all reportprocess.platformlinuxbut clearly can't all be meant simultaneously). The glibc/musl/static flavor isn't reported by Node, so matching that tolinux/alpine/linuxstaticremains your responsibility. You can point at the binary with the--sea-node-pathCLI flag or theseaNodePathpkg-config key (both overridePKG_NODE_PATH). To embed the Node.js you're currently running, passPKG_NODE_PATH="$(command -v node)"(or--sea-node-path "$(command -v node)").