TopGit
GitHub Repo Review

pkg: Executable Builder for Node.js Apps

vercel/pkg
PTopGit review image for vercel/pkg
Review by Topgit.dev for vercel/pkg, with GitHub repository stats and README context.
Quick verdict

pkg turned a Node.js project into a standalone executable years before Node itself could do that, but its own README confirms 5.8.1 was the last release before Vercel archived the repo. It still works for builds on Node versions it already supports, but a new project is better served by Node's built-in single executable applications feature. Frozen, not dead — just don't expect fixes.

Stars
★ 24.4k
Forks
⑂ 1.1k
Language
JavaScript
License
MIT
Topic
Developer Tools
Updated
Jan 2024
Homepage
GitHub

What is pkg?

pkg is a command-line tool from Vercel that bundles a Node.js project — its dependencies, assets, and a patched Node binary — into one executable file that runs without Node.js installed. It builds for Linux, macOS, and Windows by default, tracing require() calls from your entry file to work out what to include. Per the README, pkg has been deprecated as of version 5.8.1, and the repository is now archived.

Core capabilities

  • ✓Cross-compilation via --targets: build for node16-win-arm64, node18-linux, and other platform combinations in one invocation, without owning that hardware for most of them.
  • ✓A snapshot filesystem: bundled files land under /snapshot/ inside the binary, and __dirname or require.main.filename resolve there automatically at runtime.
  • ✓V8 bytecode compilation by default, with a --no-bytecode flag to keep plain JS source instead when you need reproducible build hashes.
  • ✓Native addon (.node file) packaging, with pkg writing addons to a temporary file on disk at runtime since Node can't load them straight from a snapshot.
  • ✓Brotli or GZip compression through -C/--compress, which the README says can shrink the embedded filesystem by up to 60%.
  • ✓Baked-in V8/Node runtime options via --options, so flags like expose-gc or max-old-space-size ship pre-set inside the executable.
  • ✓A programmatic API — const { exec } = require('pkg') — for scripting builds instead of shelling out to the CLI.
How this repository's GitHub stars have grown over time. Source: star-history.com.View the star history ↗

When to package Node.js as an executable

  • •Shipping a commercial build of your app without handing over its source files.
  • •Producing a demo or trial version that hides the underlying code.
  • •Cross-compiling executables for platforms you don't have a machine for.
  • •Deploying as a single file instead of npm install-ing hundreds of files on the target server.
  • •Building a self-extracting installer or archive around your app's assets.
  • •Testing your codebase against a new Node.js version without installing it system-wide.

Installing pkg

Install pkg globally with npm install -g pkg, then confirm it's on your PATH by running pkg --help, which lists every available flag. There's no separate config step required: point pkg at your entry file (or a package.json/directory containing one) and it walks require() calls to figure out the rest on its own. The one thing worth deciding upfront is your --targets list, since pkg defaults to building linux, macos, and win for your current Node version and architecture if you leave it unspecified.

Creating your first executable

Point pkg straight at an entry file — pkg index.js — and it produces executables for Linux, macOS, and Windows by default. Run pkg . instead and it reads the bin field from package.json in the current directory. Need one specific build? pkg -t node16-win-arm64 index.js narrows it to a single target. Anything pkg can't trace automatically — a require(variable) call with a non-literal argument, or non-JS assets like views or images — has to be listed manually under a pkg block in package.json, using scripts and assets glob patterns plus an optional outputPath. The API mirrors the CLI: await exec(['app.js', '--target', 'host', '--output', 'app.exe']) returns a promise you can chain into your own build pipeline.

Key advantages

  • ✓Turns a whole Node project — dependencies, assets, and base binary — into one file, so deployment stops being an npm install on the target machine.
  • ✓--targets lets you cross-compile for platforms you don't own hardware for, in a single command.
  • ✓V8 bytecode compilation by default adds a layer of source obscurity beyond plain minification.
  • ✓Brotli/GZip compression trims the embedded filesystem, which the README says can be by up to 60%.
  • ✓The programmatic exec() API folds packaging into your own build scripts instead of shelling out.

Known limitations

  • △The project is archived — the README states 5.8.1 is the last release, so no new fixes or newer Node version support are coming from vercel/pkg itself.
  • △Cross-arch builds need extra setup: QEMU/binfmt on Linux, Rosetta 2 on macOS, or x64 emulation on Windows, unless you disable bytecode generation.
  • △macos-arm64 builds are marked experimental, and macOS code-signing is mandatory or the OS kills the binary outright.
  • △Non-literal require() calls and non-JS assets aren't auto-detected — you have to hand-list them in the package.json pkg config or the build silently misses files.
  • △Native addons only get bundled as raw files pkg writes to a temp path at runtime, and linuxstatic targets can't load native bindings at all.
View on GitHub ↗Homepage ↗

Alternatives to pkg

Node.js single executable applications (SEA) — the built-in feature the pkg README itself points to as the reason the project was deprecated.nexe — another CLI that compiles a Node.js app plus a Node binary into one executable, with a similar require-tracing approach to pkg.caxa — a simpler packager that zips your app and a Node binary together rather than compiling bytecode, trading pkg's obscurity for less build complexity.deno — its deno compile command bundles a script into a single binary natively, useful if you're open to switching runtimes instead of packaging Node. ↗

Frequently asked questions

Is pkg still maintained in 2024?

pkg is not actively maintained: the README states version 5.8.1 was the last release and Vercel archived the repository. Several community forks continue adding features, but the original vercel/pkg project itself receives no further updates.

How does pkg compare to Node.js 21 single executable applications?

pkg is a third-party CLI that has to download and patch Node base binaries to produce an executable, while Node.js 21's built-in single executable applications feature does the same job natively inside Node itself. The pkg README points to this native feature as the reason the project was deprecated.

Can pkg bundle native Node.js addons (.node files)?

pkg can bundle native addons: when it finds a .node file in a require call, it packages it like any other asset. Because Node needs addons on disk to load them, pkg writes a temporary copy to disk at runtime, and that file stays there between runs.

How do I include non-JavaScript assets in a pkg executable?

Non-JavaScript assets need to be listed under the assets glob pattern in the pkg block of package.json, or referenced with a two-argument path.join(__dirname, 'file') call that pkg can detect automatically. Anything pkg can't trace either way gets left out of the build silently.

Why am I getting ERR_INSPECTOR_NOT_AVAILABLE with my packaged app?

ERR_INSPECTOR_NOT_AVAILABLE happens because pkg executables disallow Node's debug/inspector mode by default, since pkg targets production deployments. It's usually triggered by a NODE_OPTIONS environment variable forcing debug mode; using the inspector with pkg requires building a custom debuggable Node.js yourself.

How do I reduce executable size with pkg compression options?

Pass --compress Brotli or --compress GZip (or the -C shortcut) to pkg to compress the embedded file store inside the executable. The README says this can shrink the packed filesystem by up to 60%, though startup time may drop slightly as a trade-off.

The problem it solves

Before Node.js could ship single executable applications on its own, getting a Node.js app onto a machine without Node installed meant either asking the user to install Node and run npm install first, or hand-rolling binary packaging around V8's snapshot and bytecode internals yourself. pkg wrapped that packaging problem — walking require() calls, compiling to bytecode, embedding a snapshot filesystem, cross-compiling for other platforms — into one CLI command, which is why projects built before Node 21 still depend on it even though development on pkg itself has stopped.

Who should try it — and who should skip

Reach for pkg if you're maintaining an existing project that already depends on it, your target Node version is one pkg still supports, or you need a demo/trial build without exposing source. Skip it for a brand-new project: Node 21+ ships its own single executable applications feature, and since pkg is archived at 5.8.1 you won't get support for newer Node runtimes or any further bug fixes.

Related repositories

Source & attribution

Based on the vercel/pkg GitHub repository and its README.

GitHub data · last synced Aug 15, 2026Reviewed by Henry
← Back to TopGit

Is pkg worth your time?

ChatGPT, Claude and Perplexity can all read this page. Ask one of them what it makes of pkg.

GitHub