Bytecode
By default, your source code is precompiled to V8 bytecode before being written to the output file. This strips the original JavaScript source from the binary, making it harder (though not impossible) to recover. Disable with --no-bytecode.
pkg --no-bytecode index.jsDefault behavior
- Source obscurity. With
--no-bytecode, raw JavaScript is embedded directly — running GNUstringson the output will surface your source. Bytecode isn't encryption, but it adds friction that deters casual reverse engineering. - Faster startup. V8 can skip parsing and directly execute the bytecode.
When to disable bytecode
Reproducible builds
V8 bytecode compilation is not deterministic (see this paper and this post) — different runs produce different bytecode for the same input. If you need reproducible executable hashes (md5, sha256, …) across builds, disable bytecode:
pkg --no-bytecode --public-packages "*" index.jsCross-compiling without QEMU
Bytecode generation requires running the target architecture's Node.js to compile the code. On Linux that means binfmt + QEMU for foreign arches. If you don't want to set that up, disabling bytecode avoids the requirement entirely:
pkg --no-bytecode --public-packages "*" --public -t node22-linux-arm64 index.jsSee Targets → Cross-compilation support.
Licenses and --public-packages
Disabling bytecode fails if any package in your project isn't explicitly marked as public via license in its package.json. pkg checks the license of each package and makes sure that non-public code is only included as bytecode — this is a legal safety net for proprietary dependencies.
Override this behaviour by whitelisting packages:
pkg --no-bytecode --public-packages "packageA,packageB" index.jsOr mark all packages as public:
pkg --no-bytecode --public-packages "*" --public index.js--public additionally exposes the top-level project sources (i.e. your own code) as plain text.
Fallback to source on failure
When bytecode generation fails for a specific file (e.g. during cross-compilation without QEMU), pkg logs a warning and skips the file — it won't be available at runtime. If you'd rather ship the affected files as plain source instead of skipping them, pass --fallback-to-source:
pkg --fallback-to-source -t node22-linux-arm64 index.jsFiles that compile successfully still ship as bytecode; only the ones that fail are included as plain JavaScript. A warning is emitted for each file that falls back.
SEA mode
SEA mode never uses bytecode — source is always plaintext in a SEA binary. See SEA vs Standard for the trade-off.
