Getting started
Prerequisites
- Node.js >= 22 on the build host (check with
node -v) - npm or any Node.js package manager (pnpm, yarn, bun all work)
- ~500 MB free disk for cached base binaries on first run (
~/.pkg-cache/)
Cross-compiling Linux / macOS / Windows binaries (and x64 / arm64) from a single host is supported on Node 20 and Node 24. Node 22 has a known Standard-mode regression — see Targets → Cross-compilation support.
Install
npm install -g @yao-pkg/pkgpnpm add -g @yao-pkg/pkgyarn global add @yao-pkg/pkgnpx @yao-pkg/pkg .Verify the install:
pkg --versionBuild your first binary
Create a tiny project:
mkdir hello-pkg && cd hello-pkg
echo 'console.log("hello from a single binary!");' > index.jsPackage it:
pkg index.jsYou should now see three executables in the current directory:
index-linux
index-macos
index-win.exeEach is a fully self-contained binary — no Node.js required on the target machine. Run the one for your host:
./index-linux
# → hello from a single binary!./index-macos
# → hello from a single binary!.\index-win.exe
# → hello from a single binary!Package a whole project
With a package.json in place, pkg follows its bin entry and walks your dependencies automatically:
{
"name": "hello-pkg",
"version": "1.0.0",
"bin": "index.js",
"pkg": {
"targets": ["node22-linux-x64", "node22-macos-arm64", "node22-win-x64"],
"outputPath": "dist"
}
}Then:
pkg .pkg reads the pkg property in package.json, targets just the three platforms listed, and drops the output into dist/. See Configuration for the full config schema and Targets for the target triple syntax.
CLI reference
| Flag | Short | Description |
|---|---|---|
--help | -h | Show usage |
--version | -v | Print pkg version |
--targets <list> | -t | Comma-separated target list, e.g. node22-linux-x64 — see Targets |
--config <path> | -c | Path to package.json or any JSON file with a top-level pkg config |
--output <path> | -o | Output file name (single-target builds only) |
--out-path <dir> | Output directory for multi-target builds | |
--debug | -d | Verbose packaging log — see Output & debug |
--build | -b | Compile base binaries from source instead of downloading — see Build |
--public | Speed up packaging and disclose top-level sources | |
--public-packages <list> | Force listed packages to be treated as public — see Bytecode | |
--no-bytecode | Skip V8 bytecode compilation, embed source as plain JS — see Bytecode | |
--no-native-build | Skip building native addons | |
--no-dict <list> | Ignore bundled dictionaries for listed packages (* disables all) | |
--options <list> | Bake V8 options into the executable — see CLI options | |
--compress <algo> | -C | Compress the embedded filesystem with Brotli or GZip — see Compression |
--sea | Use Node.js SEA instead of the patched base binary — see SEA mode |
Run pkg --help at any time for the live list of options.
Next steps
- Targets — cross-compile for other platforms
- Configuration —
pkgproperty, assets, scripts, ignore - SEA vs Standard — which packaging mode to pick
- Recipes — copy-paste solutions for common tasks
- Troubleshooting — if something breaks
