Recipes
Copy-paste solutions for tasks you actually do. Each recipe is self-contained — no prose, just the config and the command.
Jump to a recipe:
- Build a binary for every mainstream platform
- Smallest possible binary (Brotli + Standard mode)
- Reproducible builds (no bytecode, same hash every time)
- Bundle a native SQLite addon
- Ship an ESM project with top-level await
- Build all targets in CI
- Programmatic build with the Node.js API
- Bake V8 heap limit into the binary
- Cross-compile to Linux arm64 without QEMU
- Exclude test and doc directories from dependencies
- Use a glob to bundle all SQL migrations
- Debug a missing asset
- Pin the base binary cache path (CI / enterprise)
Build a binary for every mainstream platform
pkg -t node22-linux-x64,node22-linux-arm64,node22-macos-x64,node22-macos-arm64,node22-win-x64 --out-path dist .{
"pkg": {
"targets": [
"node22-linux-x64",
"node22-linux-arm64",
"node22-macos-x64",
"node22-macos-arm64",
"node22-win-x64"
],
"outputPath": "dist"
}
}Smallest possible binary (Brotli + Standard mode)
pkg -C Brotli -t node22-linux-x64 --out-path dist .Combine with --no-dict * to drop dictionary/ patches and shave a few more KB:
pkg -C Brotli --no-dict '*' -t node22-linux-x64 --out-path dist .Reproducible builds (no bytecode, same hash every time)
pkg --no-bytecode --public-packages '*' --public -t node22-linux-x64 -o dist/app .
sha256sum dist/appSee Bytecode → Reproducible builds.
Bundle a native SQLite addon
{
"pkg": {
"targets": ["node22-linux-x64", "node22-win-x64"],
"assets": ["node_modules/better-sqlite3/build/Release/better_sqlite3.node"],
"outputPath": "dist"
}
}pkg .The .node file is extracted to $HOME/.cache/pkg-native/ on first launch — change the destination with PKG_NATIVE_CACHE_PATH. See Native addons.
Ship an ESM project with top-level await
package.json:
{
"type": "module",
"bin": "src/main.js",
"pkg": {
"targets": ["node22-linux-x64"],
"sea": true
}
}pkg .Enhanced SEA mode handles ESM entrypoints + top-level await natively. No async-IIFE transform.
Build all targets in CI
GitHub Actions:
name: Release binaries
on:
push:
tags: ['v*']
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npx @yao-pkg/pkg . --out-path dist
- uses: actions/upload-artifact@v4
with:
name: binaries
path: dist/Programmatic build with the Node.js API
const { exec } = require('@yao-pkg/pkg');
await exec([
'.',
'--targets',
'node22-linux-x64,node22-macos-arm64,node22-win-x64',
'--out-path',
'dist',
'--compress',
'Brotli',
]);See API for full usage.
Bake V8 heap limit into the binary
pkg --options max-old-space-size=4096,expose-gc .Users can't override — the flags always apply. See CLI options.
Cross-compile to Linux arm64 without QEMU
pkg --no-bytecode --public-packages '*' --public -t node22-linux-arm64 .Skips the bytecode step, so there's no need to run an arm64 interpreter on your x64 host. Trade-off: source is plaintext in the binary. See Targets → Cross-compilation support.
Exclude test and doc directories from dependencies
{
"pkg": {
"ignore": [
"**/node_modules/*/test/**",
"**/node_modules/*/tests/**",
"**/node_modules/*/docs/**",
"**/node_modules/*/example/**",
"**/node_modules/*/examples/**"
]
}
}Typically shaves 10–30 % off the final binary. See Configuration → ignore.
Use a glob to bundle all SQL migrations
{
"pkg": {
"assets": ["migrations/**/*.sql"]
}
}In code:
const path = require('node:path');
const fs = require('node:fs');
const dir = path.join(__dirname, 'migrations');
const files = fs.readdirSync(dir).sort();
for (const f of files) {
console.log('running', f);
// ...
}Works because fs.readdirSync on a /snapshot/... path reads from the virtual filesystem. See Snapshot filesystem.
Debug a missing asset
pkg --debug -o dist/app .
DEBUG_PKG=1 ./dist/app 2>&1 | grep my-missing-fileFull workflow in Debug virtual FS.
Pin the base binary cache path (CI / enterprise)
export PKG_CACHE_PATH=/var/cache/pkg
pkg .Keeps the pkg-fetch downloads outside $HOME, useful in locked-down build environments. See Environment variables.
Next steps
Looking for something that's not here? Open an issue on yao-pkg/pkg and we'll add the recipe.
