pkg

Important

pkg has been deprecated with 5.8.1 as the last release. There are a number of successful forked versions of pkg already with various feature additions. Further, we’re excited about Node.js 21’s support for single executable applications. Thank you for the support and contributions over the years. The repository will remain open and archived.

This command line interface enables you to package your Node.js project into an executable that can be run even on devices without Node.js installed.

Use Cases

  • Make a commercial version of your application without sources
  • Make a demo/evaluation/trial version of your app without sources
  • Instantly make executables for other platforms (cross-compilation)
  • Make some kind of self-extracting archive or installer
  • No need to install Node.js and npm to run the packaged application
  • No need to download hundreds of files via npm install to deploy your application. Deploy it as a single file
  • Put your assets inside the executable to make it even more portable
  • Test your app against new Node.js version without installing it

Usage

npm install -g pkg

After installing it, run pkg --help without arguments to see list of options:

pkg [options] <input>

  Options:

    -h, --help           output usage information
    -v, --version        output pkg version
    -t, --targets        comma-separated list of targets (see examples)
    -c, --config         package.json or any json file with top-level config
    --options            bake v8 options into executable to run with them on
    -o, --output         output file name or template for several files
    --out-path           path to save output one or more executables
    -d, --debug          show more information during packaging process [off]
    -b, --build          don't download prebuilt base binaries, build them
    --public             speed up and disclose the sources of top-level project
    --public-packages    force specified packages to be considered public
    --no-bytecode        skip bytecode generation and include source files as plain js
    --no-native-build    skip native addons build
    --no-signature       skip signature of the final executable on macos
    --no-dict            comma-separated list of packages names to ignore dictionaries. Use --no-dict * to disable all dictionaries
    -C, --compress       [default=None] compression algorithm = Brotli or GZip

  Examples:

  – Makes executables for Linux, macOS and Windows
    $ pkg index.js
  – Takes package.json from cwd and follows 'bin' entry
    $ pkg .
  – Makes executable for particular target machine
    $ pkg -t node16-win-arm64 index.js
  – Makes executables for target machines of your choice
    $ pkg -t node16-linux,node18-linux,node16-win index.js
  – Bakes '--expose-gc' and '--max-heap-size=34' into executable
    $ pkg --options "expose-gc,max-heap-size=34" index.js
  – Consider packageA and packageB to be public
    $ pkg --public-packages "packageA,packageB" index.js
  – Consider all packages to be public
    $ pkg --public-packages "*" index.js
  – Bakes '--expose-gc' into executable
    $ pkg --options expose-gc index.js
  – reduce size of the data packed inside the executable with GZip
    $ pkg --compress GZip index.js

The entrypoint of your project is a mandatory CLI argument. It may be:

  • Path to entry file. Suppose it is /path/app.js, then packaged app will work the same way as node /path/app.js
  • Path to package.json. Pkg will follow bin property of the specified package.json and use it as entry file.
  • Path to directory. Pkg will look for package.json in the specified directory. See above.

Targets

pkg can generate executables for several target machines at a time. You can specify a comma-separated list of targets via --targets option. A canonical target consists of 3 elements, separated by dashes, for example node18-macos-x64 or node14-linux-arm64:

  • nodeRange (node8), node10, node12, node14, node16 or latest
  • platform alpine, linux, linuxstatic, win, macos, (freebsd)
  • arch x64, arm64, (armv6, armv7)

(element) is unsupported, but you may try to compile yourself.

You may omit any element (and specify just node14 for example). The omitted elements will be taken from current platform or system-wide Node.js installation (its version and arch). There is also an alias host, that means that all 3 elements are taken from current platform/Node.js. By default targets are linux,macos,win for current Node.js version and arch.

If you want to generate executable for different architectures, note that by default pkg has to run the executable of the target arch to generate bytecodes:

  • Linux: configure binfmt with QEMU.
  • macOS: possible to build x64 on arm64 with Rosetta 2 but not opposite.
  • Windows: possible to build x64 on arm64 with x64 emulation but not opposite.
  • or, disable bytecode generation with --no-bytecode --public-packages "*" --public.

macos-arm64 is experimental. Be careful about the mandatory code signing requirement. The final executable has to be signed (ad-hoc signature is sufficient) with codesign utility of macOS (or ldid utility on Linux). Otherwise, the executable will be killed by kernel and the end-user has no way to permit it to run at all. pkg tries to ad-hoc sign the final executable. If necessary, you can replace this signature with your own trusted Apple Developer ID.

To be able to generate executables for all supported architectures and platforms, run pkg on a Linux host with binfmt (QEMU emulation) configured and ldid installed.

Config

During packaging process pkg parses your sources, detects calls to require, traverses the dependencies of your project and includes them into executable. In most cases you don't need to specify anything manually.

However your code may have require(variable) calls (so called non-literal argument to require) or use non-javascript files (for example views, css, images etc).

require('./build/' + cmd + '.js');
path.join(__dirname, 'views/' + viewName);

Such cases are not handled by pkg. So you must specify the files - scripts and assets - manually in pkg property of your package.json file.

  "pkg": {
    "scripts": "build/**/*.js",
    "assets": "views/**/*",
    "targets": [ "node14-linux-arm64" ],
    "outputPath": "dist"
  }

The above example will include everything in assets/ and every .js file in build/, build only for node14-linux-arm64, and place the executable inside dist/.

You may also specify arrays of globs:

    "assets": [ "assets/**/*", "images/**/*" ]

Just be sure to call pkg package.json or pkg . to make use of package.json configuration.

Scripts

scripts is a glob or list of globs. Files specified as scripts will be compiled using v8::ScriptCompiler and placed into executable without sources. They must conform to the JS standards of those Node.js versions you target (see Targets), i.e. be already transpiled.

Assets

assets is a glob or list of globs. Files specified as assets will be packaged into executable as raw content without modifications. Javascript files may also be specified as assets. Their sources will not be stripped as it improves execution performance of the files and simplifies debugging.

See also Detecting assets in source code and Snapshot filesystem.

Options

Node.js application can be called with runtime options (belonging to Node.js or V8). To list them type node --help or node --v8-options.

You can "bake" these runtime options into packaged application. The app will always run with the options turned on. Just remove -- from option name.

You can specify multiple options by joining them in a single string, comma (,) separated:

pkg app.js --options expose-gc
pkg app.js --options max_old_space_size=4096
pkg app.js --options max-old-space-size=1024,tls-min-v1.0,expose-gc

Output

You may specify --output if you create only one executable or --out-path to place executables for multiple targets.

Debug

Pass --debug to pkg to get a log of packaging process. If you have issues with some particular file (seems not packaged into executable), it may be useful to look through the log.

Bytecode (reproducibility)

By default, your source code is precompiled to v8 bytecode before being written to the output file. To disable this feature, pass --no-bytecode to pkg.

Why would you want to do this?

If you need a reproducible build process where your executable hashes (e.g. md5, sha1, sha256, etc.) are the same value between builds. Because compiling bytecode is not deterministic (see here or here) it results in executables with differing hashed values. Disabling bytecode compilation allows a given input to always have the same output.

Why would you NOT want to do this?

While compiling to bytecode does not make your source code 100% secure, it does add a small layer of security/privacy/obscurity to your source code. Turning off bytecode compilation causes the raw source code to be written directly to the executable file. If you're on *nix machine and would like an example, run pkg with the --no-bytecode flag, and use the GNU strings tool on the output. You then should be able to grep your source code.

Other considerations

Specifying --no-bytecode will fail if there are any packages in your project that aren't explicitly marked as public by the license in their package.json. By default, pkg will check the license of each package and make sure that stuff that isn't meant for the public will only be included as bytecode.

If you do require building pkg binaries for other architectures and/or depend on a package with a broken license in its package.json, you can override this behaviour by either explicitly whitelisting packages to be public using --public-packages "packageA,packageB" or setting all packages to public using --public-packages "*"

Build

pkg has so called "base binaries" - they are actually same node executables but with some patches applied. They are used as a base for every executable pkg creates. pkg downloads precompiled base binaries before packaging your application. If you prefer to compile base binaries from source instead of downloading them, you may pass --build option to pkg. First ensure your computer meets the requirements to compile original Node.js: BUILDING.md

See pkg-fetch for more info.

Compression

Pass --compress Brotli or --compress GZip to pkg to compress further the content of the files store in the exectable.

This option can reduce the size of the embedded file system by up to 60%.

The startup time of the application might be reduced slightly.

-C can be used as a shortcut for --compress .

Environment

Var Description
PKG_CACHE_PATH Used to specify a custom path for node binaries cache folder. Default is ~/.pkg-cache
PKG_IGNORE_TAG Allows to ignore additional folder created on PKG_CACHE_PATH matching pkg-fetch version
MAKE_JOB_COUNT Allow configuring number of processes used for compiling

Examples

# 1 - Using export
export PKG_CACHE_PATH=/my/cache
pkg app.js

# 2 - Passing it before the script
PKG_CACHE_PATH=/my/cache pkg app.js

Usage of packaged app

Command line call to packaged app ./app a b is equivalent to node app.js a b

Snapshot filesystem

During packaging process pkg collects project files and places them into executable. It is called a snapshot. At run time the packaged application has access to snapshot filesystem where all that files reside.

Packaged files have /snapshot/ prefix in their paths (or C:\snapshot\ in Windows). If you used pkg /path/app.js command line, then __filename value will be likely /snapshot/path/app.js at run time. __dirname will be /snapshot/path as well. Here is the comparison table of path-related values:

value with node packaged comments
__filename /project/app.js /snapshot/project/app.js
__dirname /project /snapshot/project
process.cwd() /project /deploy suppose the app is called ...
process.execPath /usr/bin/nodejs /deploy/app-x64 app-x64 and run in /deploy
process.argv[0] /usr/bin/nodejs /deploy/app-x64
process.argv[1] /project/app.js /snapshot/project/app.js
process.pkg.entrypoint undefined /snapshot/project/app.js
process.pkg.defaultEntrypoint undefined /snapshot/project/app.js
require.main.filename /project/app.js /snapshot/project/app.js

Hence, in order to make use of a file collected at packaging time (require a javascript file or serve an asset) you should take __filename, __dirname, process.pkg.defaultEntrypoint or require.main.filename as a base for your path calculations. For javascript files you can just require or require.resolve because they use current __dirname by default. For assets use path.join(__dirname, '../path/to/asset'). Learn more about path.join in Detecting assets in source code.

On the other hand, in order to access real file system at run time (pick up a user's external javascript plugin, json configuration or even get a list of user's directory) you should take process.cwd() or path.dirname(process.execPath).

Detecting assets in source code

When pkg encounters path.join(__dirname, '../path/to/asset'), it automatically packages the file specified as an asset. See Assets. Pay attention that path.join must have two arguments and the last one must be a string literal.

This way you may even avoid creating pkg config for your project.

Native addons

Native addons (.node files) use is supported. When pkg encounters a .node file in a require call, it will package this like an asset. In some cases (like with the bindings package), the module path is generated dynamicaly and pkg won't be able to detect it. In this case, you should add the .node file directly in the assets field in package.json.

The way Node.js requires native addon is different from a classic JS file. It needs to have a file on disk to load it, but pkg only generates one file. To circumvent this, pkg will create a temporary file on the disk. These files will stay on the disk after the process has exited and will be used again on the next process launch.

When a package, that contains a native module, is being installed, the native module is compiled against current system-wide Node.js version. Then, when you compile your project with pkg, pay attention to --target option. You should specify the same Node.js version as your system-wide Node.js to make compiled executable compatible with .node files.

Note that fully static Node binaries are not capable of loading native bindings, so you may not use Node bindings with linuxstatic.

API

const { exec } = require('pkg')

exec(args) takes an array of command line arguments and returns a promise. For example:

await exec(['app.js', '--target', 'host', '--output', 'app.exe']);
// do something with app.exe, run, test, upload, deploy, etc

Troubleshooting

Error: ENOENT: no such file or directory, uv_chdir

This error can be caused by deleting the directory the application is run from. Or, generally, deleting process.cwd() directory when the application is running.

Error: ERR_INSPECTOR_NOT_AVAILABLE

This error can be caused by using NODE_OPTIONS variable to force to run node with the debug mode enabled. Debugging options are disallowed , as pkg executables are usually used for production environments. If you do need to use inspector, you can build a debuggable Node.js yourself.

Error: require(...).internalModuleStat is not a function

This error can be caused by using NODE_OPTIONS variable with some bootstrap or node options causing conflicts with pkg. Some IDEs, such as VS Code, may add this env variable automatically.

You could check on Unix systems (Linux/macOS) in bash:

$ printenv | grep NODE

Advanced

exploring virtual file system embedded in debug mode

When you are using the --debug flag when building your executable, pkg add the ability to display the content of the virtual file system and the symlink table on the console, when the application starts, providing that the environement variable DEBUG_PKG is set. This feature can be useful to inspect if symlinks are correctly handled, and check that all the required files for your application are properly incorporated to the final executable.

$ pkg --debug app.js -o output
$ DEBUG_PKG=1 output

or

C:\> pkg --debug app.js -o output.exe
C:\> set DEBUG_PKG=1
C:\> output.exe

Note: make sure not to use --debug flag in production.

vercel/pkg

{
"props": {
"initialPayload": {
"allShortcutsEnabled": false,
"path": "/",
"repo": {
"id": 65233633,
"defaultBranch": "main",
"name": "pkg",
"ownerLogin": "vercel",
"currentUserCanPush": false,
"isFork": false,
"isEmpty": false,
"createdAt": "2016-08-08T19:41:59.000Z",
"ownerAvatar": "https://avatars.githubusercontent.com/u/14985020?v=4",
"public": true,
"private": false,
"isOrgOwned": true
},
"currentUser": null,
"refInfo": {
"name": "main",
"listCacheKey": "v0:1704245896.0",
"canEdit": false,
"refType": "branch",
"currentOid": "9066ceeb391d9c7ba6aba650109c2fa3f8e088eb"
},
"tree": {
"items": [
{
"name": ".github",
"path": ".github",
"contentType": "directory"
},
{
"name": "dictionary",
"path": "dictionary",
"contentType": "directory"
},
{
"name": "examples",
"path": "examples",
"contentType": "directory"
},
{
"name": "lib",
"path": "lib",
"contentType": "directory"
},
{
"name": "prelude",
"path": "prelude",
"contentType": "directory"
},
{
"name": "test",
"path": "test",
"contentType": "directory"
},
{
"name": ".eslintignore",
"path": ".eslintignore",
"contentType": "file"
},
{
"name": ".eslintrc",
"path": ".eslintrc",
"contentType": "file"
},
{
"name": ".gitignore",
"path": ".gitignore",
"contentType": "file"
},
{
"name": ".prettierignore",
"path": ".prettierignore",
"contentType": "file"
},
{
"name": ".yarnrc",
"path": ".yarnrc",
"contentType": "file"
},
{
"name": "LICENSE",
"path": "LICENSE",
"contentType": "file"
},
{
"name": "README.md",
"path": "README.md",
"contentType": "file"
},
{
"name": "package.json",
"path": "package.json",
"contentType": "file"
},
{
"name": "tsconfig.json",
"path": "tsconfig.json",
"contentType": "file"
},
{
"name": "yarn.lock",
"path": "yarn.lock",
"contentType": "file"
}
],
"templateDirectorySuggestionUrl": null,
"readme": null,
"totalCount": 16,
"showBranchInfobar": false
},
"fileTree": null,
"fileTreeProcessingTime": null,
"foldersToFetch": [],
"treeExpanded": false,
"symbolsExpanded": false,
"isOverview": true,
"overview": {
"banners": {
"shouldRecommendReadme": false,
"isPersonalRepo": false,
"showUseActionBanner": false,
"actionSlug": null,
"actionId": null,
"showProtectBranchBanner": false,
"publishBannersInfo": {
"dismissActionNoticePath": "/settings/dismiss-notice/publish_action_from_repo",
"releasePath": "/vercel/pkg/releases/new?marketplace=true",
"showPublishActionBanner": false
},
"interactionLimitBanner": null,
"showInvitationBanner": false,
"inviterName": null
},
"codeButton": {
"contactPath": "/contact",
"isEnterprise": false,
"local": {
"protocolInfo": {
"httpAvailable": true,
"sshAvailable": null,
"httpUrl": "https://github.com/vercel/pkg.git",
"showCloneWarning": null,
"sshUrl": null,
"sshCertificatesRequired": null,
"sshCertificatesAvailable": null,
"ghCliUrl": "gh repo clone vercel/pkg",
"defaultProtocol": "http",
"newSshKeyUrl": "/settings/ssh/new",
"setProtocolPath": "/users/set_protocol"
},
"platformInfo": {
"cloneUrl": "https://desktop.github.com",
"showVisualStudioCloneButton": false,
"visualStudioCloneUrl": "https://windows.github.com",
"showXcodeCloneButton": false,
"xcodeCloneUrl": "https://developer.apple.com",
"zipballUrl": "/vercel/pkg/archive/refs/heads/main.zip"
}
},
"newCodespacePath": "/codespaces/new?hide_repo_select=true&repo=65233633"
},
"popovers": {
"rename": null,
"renamedParentRepo": null
},
"commitCount": "1,139",
"overviewFiles": [
{
"displayName": "README.md",
"repoName": "pkg",
"refName": "main",
"path": "README.md",
"preferredFileType": "readme",
"tabName": "README",
"richText": "<article class=\"markdown-body entry-content container-lg\" itemprop=\"text\"><div class=\"markdown-heading\" dir=\"auto\"><h1 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"><code>pkg</code></h1><a id=\"user-content-pkg\" class=\"anchor\" aria-label=\"Permalink: pkg\" href=\"#pkg\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<div class=\"markdown-alert markdown-alert-important\" dir=\"auto\"><p class=\"markdown-alert-title\" dir=\"auto\"><svg class=\"octicon octicon-report mr-2\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v9.5A1.75 1.75 0 0 1 14.25 13H8.06l-2.573 2.573A1.458 1.458 0 0 1 3 14.543V13H1.75A1.75 1.75 0 0 1 0 11.25Zm1.75-.25a.25.25 0 0 0-.25.25v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25Zm7 2.25v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\"></path></svg>Important</p><p dir=\"auto\"><code>pkg</code> has been deprecated with <code>5.8.1</code> as the last release. There are a number of successful forked versions of <code>pkg</code> already with various feature additions. Further, we’re excited about Node.js 21’s support for <a href=\"https://nodejs.org/api/single-executable-applications.html\" rel=\"nofollow\">single executable applications</a>. Thank you for the support and contributions over the years. The repository will remain open and archived.</p>\n</div>\n<p dir=\"auto\">This command line interface enables you to package your Node.js project into an executable that can be run even on devices without Node.js installed.</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Use Cases</h2><a id=\"user-content-use-cases\" class=\"anchor\" aria-label=\"Permalink: Use Cases\" href=\"#use-cases\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<ul dir=\"auto\">\n<li>Make a commercial version of your application without sources</li>\n<li>Make a demo/evaluation/trial version of your app without sources</li>\n<li>Instantly make executables for other platforms (cross-compilation)</li>\n<li>Make some kind of self-extracting archive or installer</li>\n<li>No need to install Node.js and npm to run the packaged application</li>\n<li>No need to download hundreds of files via <code>npm install</code> to deploy\nyour application. Deploy it as a single file</li>\n<li>Put your assets inside the executable to make it even more portable</li>\n<li>Test your app against new Node.js version without installing it</li>\n</ul>\n<div class=\"markdown-heading\" dir=\"auto\"><h2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Usage</h2><a id=\"user-content-usage\" class=\"anchor\" aria-label=\"Permalink: Usage\" href=\"#usage\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"npm install -g pkg\"><pre>npm install -g pkg</pre></div>\n<p dir=\"auto\">After installing it, run <code>pkg --help</code> without arguments to see list of options:</p>\n<div class=\"highlight highlight-text-shell-session notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"pkg [options] &lt;input&gt;\n\n Options:\n\n -h, --help output usage information\n -v, --version output pkg version\n -t, --targets comma-separated list of targets (see examples)\n -c, --config package.json or any json file with top-level config\n --options bake v8 options into executable to run with them on\n -o, --output output file name or template for several files\n --out-path path to save output one or more executables\n -d, --debug show more information during packaging process [off]\n -b, --build don't download prebuilt base binaries, build them\n --public speed up and disclose the sources of top-level project\n --public-packages force specified packages to be considered public\n --no-bytecode skip bytecode generation and include source files as plain js\n --no-native-build skip native addons build\n --no-signature skip signature of the final executable on macos\n --no-dict comma-separated list of packages names to ignore dictionaries. Use --no-dict * to disable all dictionaries\n -C, --compress [default=None] compression algorithm = Brotli or GZip\n\n Examples:\n\n – Makes executables for Linux, macOS and Windows\n $ pkg index.js\n – Takes package.json from cwd and follows 'bin' entry\n $ pkg .\n – Makes executable for particular target machine\n $ pkg -t node16-win-arm64 index.js\n – Makes executables for target machines of your choice\n $ pkg -t node16-linux,node18-linux,node16-win index.js\n – Bakes '--expose-gc' and '--max-heap-size=34' into executable\n $ pkg --options &quot;expose-gc,max-heap-size=34&quot; index.js\n – Consider packageA and packageB to be public\n $ pkg --public-packages &quot;packageA,packageB&quot; index.js\n – Consider all packages to be public\n $ pkg --public-packages &quot;*&quot; index.js\n – Bakes '--expose-gc' into executable\n $ pkg --options expose-gc index.js\n – reduce size of the data packed inside the executable with GZip\n $ pkg --compress GZip index.js\"><pre><span class=\"pl-c1\">pkg [options] &lt;input&gt;</span>\n\n<span class=\"pl-c1\"> Options:</span>\n\n<span class=\"pl-c1\"> -h, --help output usage information</span>\n<span class=\"pl-c1\"> -v, --version output pkg version</span>\n<span class=\"pl-c1\"> -t, --targets comma-separated list of targets (see examples)</span>\n<span class=\"pl-c1\"> -c, --config package.json or any json file with top-level config</span>\n<span class=\"pl-c1\"> --options bake v8 options into executable to run with them on</span>\n<span class=\"pl-c1\"> -o, --output output file name or template for several files</span>\n<span class=\"pl-c1\"> --out-path path to save output one or more executables</span>\n<span class=\"pl-c1\"> -d, --debug show more information during packaging process [off]</span>\n<span class=\"pl-c1\"> -b, --build don't download prebuilt base binaries, build them</span>\n<span class=\"pl-c1\"> --public speed up and disclose the sources of top-level project</span>\n<span class=\"pl-c1\"> --public-packages force specified packages to be considered public</span>\n<span class=\"pl-c1\"> --no-bytecode skip bytecode generation and include source files as plain js</span>\n<span class=\"pl-c1\"> --no-native-build skip native addons build</span>\n<span class=\"pl-c1\"> --no-signature skip signature of the final executable on macos</span>\n<span class=\"pl-c1\"> --no-dict comma-separated list of packages names to ignore dictionaries. Use --no-dict * to disable all dictionaries</span>\n<span class=\"pl-c1\"> -C, --compress [default=None] compression algorithm = Brotli or GZip</span>\n\n<span class=\"pl-c1\"> Examples:</span>\n\n<span class=\"pl-c1\"> – Makes executables for Linux, macOS and Windows</span>\n<span class=\"pl-c1\"> $ pkg index.js</span>\n<span class=\"pl-c1\"> – Takes package.json from cwd and follows 'bin' entry</span>\n<span class=\"pl-c1\"> $ pkg .</span>\n<span class=\"pl-c1\"> – Makes executable for particular target machine</span>\n<span class=\"pl-c1\"> $ pkg -t node16-win-arm64 index.js</span>\n<span class=\"pl-c1\"> – Makes executables for target machines of your choice</span>\n<span class=\"pl-c1\"> $ pkg -t node16-linux,node18-linux,node16-win index.js</span>\n<span class=\"pl-c1\"> – Bakes '--expose-gc' and '--max-heap-size=34' into executable</span>\n<span class=\"pl-c1\"> $ pkg --options \"expose-gc,max-heap-size=34\" index.js</span>\n<span class=\"pl-c1\"> – Consider packageA and packageB to be public</span>\n<span class=\"pl-c1\"> $ pkg --public-packages \"packageA,packageB\" index.js</span>\n<span class=\"pl-c1\"> – Consider all packages to be public</span>\n<span class=\"pl-c1\"> $ pkg --public-packages \"*\" index.js</span>\n<span class=\"pl-c1\"> – Bakes '--expose-gc' into executable</span>\n<span class=\"pl-c1\"> $ pkg --options expose-gc index.js</span>\n<span class=\"pl-c1\"> – reduce size of the data packed inside the executable with GZip</span>\n<span class=\"pl-c1\"> $ pkg --compress GZip index.js</span></pre></div>\n<p dir=\"auto\">The entrypoint of your project is a mandatory CLI argument. It may be:</p>\n<ul dir=\"auto\">\n<li>Path to entry file. Suppose it is <code>/path/app.js</code>, then\npackaged app will work the same way as <code>node /path/app.js</code></li>\n<li>Path to <code>package.json</code>. <code>Pkg</code> will follow <code>bin</code> property of\nthe specified <code>package.json</code> and use it as entry file.</li>\n<li>Path to directory. <code>Pkg</code> will look for <code>package.json</code> in\nthe specified directory. See above.</li>\n</ul>\n<div class=\"markdown-heading\" dir=\"auto\"><h3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Targets</h3><a id=\"user-content-targets\" class=\"anchor\" aria-label=\"Permalink: Targets\" href=\"#targets\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\"><code>pkg</code> can generate executables for several target machines at a\ntime. You can specify a comma-separated list of targets via <code>--targets</code>\noption. A canonical target consists of 3 elements, separated by\ndashes, for example <code>node18-macos-x64</code> or <code>node14-linux-arm64</code>:</p>\n<ul dir=\"auto\">\n<li><strong>nodeRange</strong> (node8), node10, node12, node14, node16 or latest</li>\n<li><strong>platform</strong> alpine, linux, linuxstatic, win, macos, (freebsd)</li>\n<li><strong>arch</strong> x64, arm64, (armv6, armv7)</li>\n</ul>\n<p dir=\"auto\">(element) is unsupported, but you may try to compile yourself.</p>\n<p dir=\"auto\">You may omit any element (and specify just <code>node14</code> for example).\nThe omitted elements will be taken from current platform or\nsystem-wide Node.js installation (its version and arch).\nThere is also an alias <code>host</code>, that means that all 3 elements\nare taken from current platform/Node.js. By default targets are\n<code>linux,macos,win</code> for current Node.js version and arch.</p>\n<p dir=\"auto\">If you want to generate executable for different architectures,\nnote that by default <code>pkg</code> has to run the executable of the\n<strong>target</strong> arch to generate bytecodes:</p>\n<ul dir=\"auto\">\n<li>Linux: configure binfmt with <a href=\"https://wiki.debian.org/QemuUserEmulation\" rel=\"nofollow\">QEMU</a>.</li>\n<li>macOS: possible to build <code>x64</code> on <code>arm64</code> with <code>Rosetta 2</code> but not opposite.</li>\n<li>Windows: possible to build <code>x64</code> on <code>arm64</code> with <code>x64 emulation</code> but not opposite.</li>\n<li>or, disable bytecode generation with <code>--no-bytecode --public-packages \"*\" --public</code>.</li>\n</ul>\n<p dir=\"auto\"><code>macos-arm64</code> is experimental. Be careful about the <a href=\"https://developer.apple.com/documentation/macos-release-notes/macos-big-sur-11_0_1-universal-apps-release-notes\" rel=\"nofollow\">mandatory code signing requirement</a>.\nThe final executable has to be signed (ad-hoc signature is sufficient) with <code>codesign</code>\nutility of macOS (or <code>ldid</code> utility on Linux). Otherwise, the executable will be killed\nby kernel and the end-user has no way to permit it to run at all. <code>pkg</code> tries to ad-hoc\nsign the final executable. If necessary, you can replace this signature with your own\ntrusted Apple Developer ID.</p>\n<p dir=\"auto\">To be able to generate executables for all supported architectures and platforms, run\n<code>pkg</code> on a Linux host with binfmt (<code>QEMU</code> emulation) configured and <code>ldid</code> installed.</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Config</h3><a id=\"user-content-config\" class=\"anchor\" aria-label=\"Permalink: Config\" href=\"#config\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\">During packaging process <code>pkg</code> parses your sources, detects\ncalls to <code>require</code>, traverses the dependencies of your project\nand includes them into executable. In most cases you\ndon't need to specify anything manually.</p>\n<p dir=\"auto\">However your code may have <code>require(variable)</code> calls (so called non-literal\nargument to <code>require</code>) or use non-javascript files (for\nexample views, css, images etc).</p>\n<div class=\"highlight highlight-source-js notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"require('./build/' + cmd + '.js');\npath.join(__dirname, 'views/' + viewName);\"><pre><span class=\"pl-en\">require</span><span class=\"pl-kos\">(</span><span class=\"pl-s\">'./build/'</span> <span class=\"pl-c1\">+</span> <span class=\"pl-s1\">cmd</span> <span class=\"pl-c1\">+</span> <span class=\"pl-s\">'.js'</span><span class=\"pl-kos\">)</span><span class=\"pl-kos\">;</span>\n<span class=\"pl-s1\">path</span><span class=\"pl-kos\">.</span><span class=\"pl-en\">join</span><span class=\"pl-kos\">(</span><span class=\"pl-s1\">__dirname</span><span class=\"pl-kos\">,</span> <span class=\"pl-s\">'views/'</span> <span class=\"pl-c1\">+</span> <span class=\"pl-s1\">viewName</span><span class=\"pl-kos\">)</span><span class=\"pl-kos\">;</span></pre></div>\n<p dir=\"auto\">Such cases are not handled by <code>pkg</code>. So you must specify the\nfiles - scripts and assets - manually in <code>pkg</code> property of\nyour <code>package.json</code> file.</p>\n<div class=\"highlight highlight-source-json notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\" &quot;pkg&quot;: {\n &quot;scripts&quot;: &quot;build/**/*.js&quot;,\n &quot;assets&quot;: &quot;views/**/*&quot;,\n &quot;targets&quot;: [ &quot;node14-linux-arm64&quot; ],\n &quot;outputPath&quot;: &quot;dist&quot;\n }\"><pre> <span class=\"pl-ent\">\"pkg\"</span>: {\n <span class=\"pl-ent\">\"scripts\"</span>: <span class=\"pl-s\"><span class=\"pl-pds\">\"</span>build/**/*.js<span class=\"pl-pds\">\"</span></span>,\n <span class=\"pl-ent\">\"assets\"</span>: <span class=\"pl-s\"><span class=\"pl-pds\">\"</span>views/**/*<span class=\"pl-pds\">\"</span></span>,\n <span class=\"pl-ent\">\"targets\"</span>: [ <span class=\"pl-s\"><span class=\"pl-pds\">\"</span>node14-linux-arm64<span class=\"pl-pds\">\"</span></span> ],\n <span class=\"pl-ent\">\"outputPath\"</span>: <span class=\"pl-s\"><span class=\"pl-pds\">\"</span>dist<span class=\"pl-pds\">\"</span></span>\n }</pre></div>\n<p dir=\"auto\">The above example will include everything in <code>assets/</code> and\nevery .js file in <code>build/</code>, build only for <code>node14-linux-arm64</code>,\nand place the executable inside <code>dist/</code>.</p>\n<p dir=\"auto\">You may also specify arrays of globs:</p>\n<div class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\" &quot;assets&quot;: [ &quot;assets/**/*&quot;, &quot;images/**/*&quot; ]\"><pre class=\"notranslate\"><code> \"assets\": [ \"assets/**/*\", \"images/**/*\" ]\n</code></pre></div>\n<p dir=\"auto\">Just be sure to call <code>pkg package.json</code> or <code>pkg .</code> to make\nuse of <code>package.json</code> configuration.</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Scripts</h3><a id=\"user-content-scripts\" class=\"anchor\" aria-label=\"Permalink: Scripts\" href=\"#scripts\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\"><code>scripts</code> is a <a href=\"https://github.com/sindresorhus/globby\">glob</a>\nor list of globs. Files specified as <code>scripts</code> will be compiled\nusing <code>v8::ScriptCompiler</code> and placed into executable without\nsources. They must conform to the JS standards of those Node.js versions\nyou target (see <a href=\"#targets\">Targets</a>), i.e. be already transpiled.</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Assets</h3><a id=\"user-content-assets\" class=\"anchor\" aria-label=\"Permalink: Assets\" href=\"#assets\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\"><code>assets</code> is a <a href=\"https://github.com/sindresorhus/globby\">glob</a>\nor list of globs. Files specified as <code>assets</code> will be packaged\ninto executable as raw content without modifications. Javascript\nfiles may also be specified as <code>assets</code>. Their sources will\nnot be stripped as it improves execution performance of the\nfiles and simplifies debugging.</p>\n<p dir=\"auto\">See also\n<a href=\"#detecting-assets-in-source-code\">Detecting assets in source code</a> and\n<a href=\"#snapshot-filesystem\">Snapshot filesystem</a>.</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Options</h3><a id=\"user-content-options\" class=\"anchor\" aria-label=\"Permalink: Options\" href=\"#options\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\">Node.js application can be called with runtime options\n(belonging to Node.js or V8). To list them type <code>node --help</code> or <code>node --v8-options</code>.</p>\n<p dir=\"auto\">You can \"bake\" these runtime options into packaged application. The app will always run with the options\nturned on. Just remove <code>--</code> from option name.</p>\n<p dir=\"auto\">You can specify multiple options by joining them in a single string, comma (<code>,</code>) separated:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"pkg app.js --options expose-gc\npkg app.js --options max_old_space_size=4096\npkg app.js --options max-old-space-size=1024,tls-min-v1.0,expose-gc\"><pre>pkg app.js --options expose-gc\npkg app.js --options max_old_space_size=4096\npkg app.js --options max-old-space-size=1024,tls-min-v1.0,expose-gc</pre></div>\n<div class=\"markdown-heading\" dir=\"auto\"><h3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Output</h3><a id=\"user-content-output\" class=\"anchor\" aria-label=\"Permalink: Output\" href=\"#output\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\">You may specify <code>--output</code> if you create only one executable\nor <code>--out-path</code> to place executables for multiple targets.</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Debug</h3><a id=\"user-content-debug\" class=\"anchor\" aria-label=\"Permalink: Debug\" href=\"#debug\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\">Pass <code>--debug</code> to <code>pkg</code> to get a log of packaging process.\nIf you have issues with some particular file (seems not packaged\ninto executable), it may be useful to look through the log.</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Bytecode (reproducibility)</h3><a id=\"user-content-bytecode-reproducibility\" class=\"anchor\" aria-label=\"Permalink: Bytecode (reproducibility)\" href=\"#bytecode-reproducibility\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\">By default, your source code is precompiled to v8 bytecode before being written\nto the output file. To disable this feature, pass <code>--no-bytecode</code> to <code>pkg</code>.</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Why would you want to do this?</h4><a id=\"user-content-why-would-you-want-to-do-this\" class=\"anchor\" aria-label=\"Permalink: Why would you want to do this?\" href=\"#why-would-you-want-to-do-this\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\">If you need a reproducible build\nprocess where your executable hashes (e.g. md5, sha1, sha256, etc.) are the\nsame value between builds. Because compiling bytecode is not deterministic\n(see <a href=\"https://ui.adsabs.harvard.edu/abs/2019arXiv191003478C/abstract\" rel=\"nofollow\">here</a> or\n<a href=\"https://medium.com/dailyjs/understanding-v8s-bytecode-317d46c94775\" rel=\"nofollow\">here</a>) it\nresults in executables with differing hashed values. Disabling bytecode\ncompilation allows a given input to always have the same output.</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Why would you NOT want to do this?</h4><a id=\"user-content-why-would-you-not-want-to-do-this\" class=\"anchor\" aria-label=\"Permalink: Why would you NOT want to do this?\" href=\"#why-would-you-not-want-to-do-this\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\">While compiling to bytecode does not make your source code 100% secure, it does\nadd a small layer of security/privacy/obscurity to your source code. Turning\noff bytecode compilation causes the raw source code to be written directly to\nthe executable file. If you're on *nix machine and would like an example, run\n<code>pkg</code> with the <code>--no-bytecode</code> flag, and use the GNU strings tool on the\noutput. You then should be able to grep your source code.</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Other considerations</h4><a id=\"user-content-other-considerations\" class=\"anchor\" aria-label=\"Permalink: Other considerations\" href=\"#other-considerations\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\">Specifying <code>--no-bytecode</code> will fail if there are any packages in your project that aren't explicitly marked\nas public by the <code>license</code> in their <code>package.json</code>.\nBy default, <code>pkg</code> will check the license of each package and make sure that stuff that isn't meant for the public will\nonly be included as bytecode.</p>\n<p dir=\"auto\">If you do require building pkg binaries for other architectures and/or depend on a package with a broken\n<code>license</code> in its <code>package.json</code>, you can override this behaviour by either explicitly whitelisting packages to be public\nusing <code>--public-packages \"packageA,packageB\"</code> or setting all packages to public using <code>--public-packages \"*\"</code></p>\n<div class=\"markdown-heading\" dir=\"auto\"><h3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Build</h3><a id=\"user-content-build\" class=\"anchor\" aria-label=\"Permalink: Build\" href=\"#build\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\"><code>pkg</code> has so called \"base binaries\" - they are actually same\n<code>node</code> executables but with some patches applied. They are\nused as a base for every executable <code>pkg</code> creates. <code>pkg</code>\ndownloads precompiled base binaries before packaging your\napplication. If you prefer to compile base binaries from\nsource instead of downloading them, you may pass <code>--build</code>\noption to <code>pkg</code>. First ensure your computer meets the\nrequirements to compile original Node.js:\n<a href=\"https://github.com/nodejs/node/blob/HEAD/BUILDING.md\">BUILDING.md</a></p>\n<p dir=\"auto\">See <a href=\"https://github.com/vercel/pkg-fetch\">pkg-fetch</a> for more info.</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Compression</h3><a id=\"user-content-compression\" class=\"anchor\" aria-label=\"Permalink: Compression\" href=\"#compression\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\">Pass <code>--compress Brotli</code> or <code>--compress GZip</code> to <code>pkg</code> to compress further the content of the files store in the exectable.</p>\n<p dir=\"auto\">This option can reduce the size of the embedded file system by up to 60%.</p>\n<p dir=\"auto\">The startup time of the application might be reduced slightly.</p>\n<p dir=\"auto\"><code>-C</code> can be used as a shortcut for <code>--compress </code>.</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Environment</h3><a id=\"user-content-environment\" class=\"anchor\" aria-label=\"Permalink: Environment\" href=\"#environment\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<markdown-accessiblity-table><table>\n<thead>\n<tr>\n<th>Var</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>PKG_CACHE_PATH</td>\n<td>Used to specify a custom path for node binaries cache folder. Default is <code>~/.pkg-cache</code></td>\n</tr>\n<tr>\n<td>PKG_IGNORE_TAG</td>\n<td>Allows to ignore additional folder created on <code>PKG_CACHE_PATH</code> matching pkg-fetch version</td>\n</tr>\n<tr>\n<td>MAKE_JOB_COUNT</td>\n<td>Allow configuring number of processes used for compiling</td>\n</tr>\n</tbody>\n</table></markdown-accessiblity-table>\n<p dir=\"auto\">Examples</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# 1 - Using export\nexport PKG_CACHE_PATH=/my/cache\npkg app.js\n\n# 2 - Passing it before the script\nPKG_CACHE_PATH=/my/cache pkg app.js\"><pre><span class=\"pl-c\"><span class=\"pl-c\">#</span> 1 - Using export</span>\n<span class=\"pl-k\">export</span> PKG_CACHE_PATH=/my/cache\npkg app.js\n\n<span class=\"pl-c\"><span class=\"pl-c\">#</span> 2 - Passing it before the script</span>\nPKG_CACHE_PATH=/my/cache pkg app.js</pre></div>\n<div class=\"markdown-heading\" dir=\"auto\"><h2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Usage of packaged app</h2><a id=\"user-content-usage-of-packaged-app\" class=\"anchor\" aria-label=\"Permalink: Usage of packaged app\" href=\"#usage-of-packaged-app\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\">Command line call to packaged app <code>./app a b</code> is equivalent\nto <code>node app.js a b</code></p>\n<div class=\"markdown-heading\" dir=\"auto\"><h2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Snapshot filesystem</h2><a id=\"user-content-snapshot-filesystem\" class=\"anchor\" aria-label=\"Permalink: Snapshot filesystem\" href=\"#snapshot-filesystem\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\">During packaging process <code>pkg</code> collects project files and places\nthem into executable. It is called a snapshot. At run time the\npackaged application has access to snapshot filesystem where all\nthat files reside.</p>\n<p dir=\"auto\">Packaged files have <code>/snapshot/</code> prefix in their paths (or\n<code>C:\\snapshot\\</code> in Windows). If you used <code>pkg /path/app.js</code> command line,\nthen <code>__filename</code> value will be likely <code>/snapshot/path/app.js</code>\nat run time. <code>__dirname</code> will be <code>/snapshot/path</code> as well. Here is\nthe comparison table of path-related values:</p>\n<markdown-accessiblity-table><table>\n<thead>\n<tr>\n<th>value</th>\n<th>with <code>node</code></th>\n<th>packaged</th>\n<th>comments</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>__filename</td>\n<td>/project/app.js</td>\n<td>/snapshot/project/app.js</td>\n<td></td>\n</tr>\n<tr>\n<td>__dirname</td>\n<td>/project</td>\n<td>/snapshot/project</td>\n<td></td>\n</tr>\n<tr>\n<td>process.cwd()</td>\n<td>/project</td>\n<td>/deploy</td>\n<td>suppose the app is called ...</td>\n</tr>\n<tr>\n<td>process.execPath</td>\n<td>/usr/bin/nodejs</td>\n<td>/deploy/app-x64</td>\n<td><code>app-x64</code> and run in <code>/deploy</code></td>\n</tr>\n<tr>\n<td>process.argv[0]</td>\n<td>/usr/bin/nodejs</td>\n<td>/deploy/app-x64</td>\n<td></td>\n</tr>\n<tr>\n<td>process.argv[1]</td>\n<td>/project/app.js</td>\n<td>/snapshot/project/app.js</td>\n<td></td>\n</tr>\n<tr>\n<td>process.pkg.entrypoint</td>\n<td>undefined</td>\n<td>/snapshot/project/app.js</td>\n<td></td>\n</tr>\n<tr>\n<td>process.pkg.defaultEntrypoint</td>\n<td>undefined</td>\n<td>/snapshot/project/app.js</td>\n<td></td>\n</tr>\n<tr>\n<td>require.main.filename</td>\n<td>/project/app.js</td>\n<td>/snapshot/project/app.js</td>\n<td></td>\n</tr>\n</tbody>\n</table></markdown-accessiblity-table>\n<p dir=\"auto\">Hence, in order to make use of a file collected at packaging\ntime (<code>require</code> a javascript file or serve an asset) you should\ntake <code>__filename</code>, <code>__dirname</code>, <code>process.pkg.defaultEntrypoint</code>\nor <code>require.main.filename</code> as a base for your path calculations.\nFor javascript files you can just <code>require</code> or <code>require.resolve</code>\nbecause they use current <code>__dirname</code> by default. For assets use\n<code>path.join(__dirname, '../path/to/asset')</code>. Learn more about\n<code>path.join</code> in\n<a href=\"#detecting-assets-in-source-code\">Detecting assets in source code</a>.</p>\n<p dir=\"auto\">On the other hand, in order to access real file system at run time\n(pick up a user's external javascript plugin, json configuration or\neven get a list of user's directory) you should take <code>process.cwd()</code>\nor <code>path.dirname(process.execPath)</code>.</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Detecting assets in source code</h2><a id=\"user-content-detecting-assets-in-source-code\" class=\"anchor\" aria-label=\"Permalink: Detecting assets in source code\" href=\"#detecting-assets-in-source-code\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\">When <code>pkg</code> encounters <code>path.join(__dirname, '../path/to/asset')</code>,\nit automatically packages the file specified as an asset. See\n<a href=\"#assets\">Assets</a>. Pay attention that <code>path.join</code> must have two\narguments and the last one must be a string literal.</p>\n<p dir=\"auto\">This way you may even avoid creating <code>pkg</code> config for your project.</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Native addons</h2><a id=\"user-content-native-addons\" class=\"anchor\" aria-label=\"Permalink: Native addons\" href=\"#native-addons\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\">Native addons (<code>.node</code> files) use is supported. When <code>pkg</code> encounters\na <code>.node</code> file in a <code>require</code> call, it will package this like an asset.\nIn some cases (like with the <code>bindings</code> package), the module path is generated\ndynamicaly and <code>pkg</code> won't be able to detect it. In this case, you should\nadd the <code>.node</code> file directly in the <code>assets</code> field in <code>package.json</code>.</p>\n<p dir=\"auto\">The way Node.js requires native addon is different from a classic JS\nfile. It needs to have a file on disk to load it, but <code>pkg</code> only generates\none file. To circumvent this, <code>pkg</code> will create a temporary file on the\ndisk. These files will stay on the disk after the process has exited\nand will be used again on the next process launch.</p>\n<p dir=\"auto\">When a package, that contains a native module, is being installed,\nthe native module is compiled against current system-wide Node.js\nversion. Then, when you compile your project with <code>pkg</code>, pay attention\nto <code>--target</code> option. You should specify the same Node.js version\nas your system-wide Node.js to make compiled executable compatible\nwith <code>.node</code> files.</p>\n<p dir=\"auto\">Note that fully static Node binaries are not capable of loading native\nbindings, so you may not use Node bindings with <code>linuxstatic</code>.</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">API</h2><a id=\"user-content-api\" class=\"anchor\" aria-label=\"Permalink: API\" href=\"#api\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\"><code>const { exec } = require('pkg')</code></p>\n<p dir=\"auto\"><code>exec(args)</code> takes an array of command line arguments and returns\na promise. For example:</p>\n<div class=\"highlight highlight-source-js notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"await exec(['app.js', '--target', 'host', '--output', 'app.exe']);\n// do something with app.exe, run, test, upload, deploy, etc\"><pre><span class=\"pl-k\">await</span> <span class=\"pl-en\">exec</span><span class=\"pl-kos\">(</span><span class=\"pl-kos\">[</span><span class=\"pl-s\">'app.js'</span><span class=\"pl-kos\">,</span> <span class=\"pl-s\">'--target'</span><span class=\"pl-kos\">,</span> <span class=\"pl-s\">'host'</span><span class=\"pl-kos\">,</span> <span class=\"pl-s\">'--output'</span><span class=\"pl-kos\">,</span> <span class=\"pl-s\">'app.exe'</span><span class=\"pl-kos\">]</span><span class=\"pl-kos\">)</span><span class=\"pl-kos\">;</span>\n<span class=\"pl-c\">// do something with app.exe, run, test, upload, deploy, etc</span></pre></div>\n<div class=\"markdown-heading\" dir=\"auto\"><h2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Troubleshooting</h2><a id=\"user-content-troubleshooting\" class=\"anchor\" aria-label=\"Permalink: Troubleshooting\" href=\"#troubleshooting\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<div class=\"markdown-heading\" dir=\"auto\"><h3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Error: ENOENT: no such file or directory, uv_chdir</h3><a id=\"user-content-error-enoent-no-such-file-or-directory-uv_chdir\" class=\"anchor\" aria-label=\"Permalink: Error: ENOENT: no such file or directory, uv_chdir\" href=\"#error-enoent-no-such-file-or-directory-uv_chdir\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\">This error can be caused by deleting the directory the application is\nrun from. Or, generally, deleting <code>process.cwd()</code> directory when the\napplication is running.</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Error: ERR_INSPECTOR_NOT_AVAILABLE</h3><a id=\"user-content-error-err_inspector_not_available\" class=\"anchor\" aria-label=\"Permalink: Error: ERR_INSPECTOR_NOT_AVAILABLE\" href=\"#error-err_inspector_not_available\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\">This error can be caused by using <code>NODE_OPTIONS</code> variable to force to\nrun <code>node</code> with the debug mode enabled. Debugging options are disallowed\n, as <strong>pkg</strong> executables are usually used for production environments.\nIf you do need to use inspector, you can <a href=\"https://github.com/vercel/pkg/issues/93#issuecomment-301210543\" data-hovercard-type=\"issue\" data-hovercard-url=\"/vercel/pkg/issues/93/hovercard\">build a debuggable Node.js</a> yourself.</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Error: require(...).internalModuleStat is not a function</h3><a id=\"user-content-error-requireinternalmodulestat-is-not-a-function\" class=\"anchor\" aria-label=\"Permalink: Error: require(...).internalModuleStat is not a function\" href=\"#error-requireinternalmodulestat-is-not-a-function\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\">This error can be caused by using <code>NODE_OPTIONS</code> variable with some\nbootstrap or <code>node</code> options causing conflicts with <strong>pkg</strong>. Some\nIDEs, such as <strong>VS Code</strong>, may add this env variable automatically.</p>\n<p dir=\"auto\">You could check on <strong>Unix systems</strong> (Linux/macOS) in <code>bash</code>:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"$ printenv | grep NODE\"><pre>$ printenv <span class=\"pl-k\">|</span> grep NODE</pre></div>\n<div class=\"markdown-heading\" dir=\"auto\"><h2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Advanced</h2><a id=\"user-content-advanced\" class=\"anchor\" aria-label=\"Permalink: Advanced\" href=\"#advanced\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<div class=\"markdown-heading\" dir=\"auto\"><h3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">exploring virtual file system embedded in debug mode</h3><a id=\"user-content-exploring-virtual-file-system-embedded-in-debug-mode\" class=\"anchor\" aria-label=\"Permalink: exploring virtual file system embedded in debug mode\" href=\"#exploring-virtual-file-system-embedded-in-debug-mode\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\">When you are using the <code>--debug</code> flag when building your executable,\n<code>pkg</code> add the ability to display the content of the virtual file system\nand the symlink table on the console, when the application starts,\nproviding that the environement variable DEBUG_PKG is set.\nThis feature can be useful to inspect if symlinks are correctly handled,\nand check that all the required files for your application are properly\nincorporated to the final executable.</p>\n<div class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"$ pkg --debug app.js -o output\n$ DEBUG_PKG=1 output\"><pre class=\"notranslate\"><code>$ pkg --debug app.js -o output\n$ DEBUG_PKG=1 output\n</code></pre></div>\n<p dir=\"auto\">or</p>\n<div class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"C:\\&gt; pkg --debug app.js -o output.exe\nC:\\&gt; set DEBUG_PKG=1\nC:\\&gt; output.exe\"><pre class=\"notranslate\"><code>C:\\&gt; pkg --debug app.js -o output.exe\nC:\\&gt; set DEBUG_PKG=1\nC:\\&gt; output.exe\n</code></pre></div>\n<p dir=\"auto\">Note: make sure not to use --debug flag in production.</p>\n</article>",
"loaded": true,
"timedOut": false,
"errorMessage": null,
"headerInfo": {
"toc": [
{
"level": 1,
"text": "pkg",
"anchor": "pkg",
"htmlText": "pkg"
},
{
"level": 2,
"text": "Use Cases",
"anchor": "use-cases",
"htmlText": "Use Cases"
},
{
"level": 2,
"text": "Usage",
"anchor": "usage",
"htmlText": "Usage"
},
{
"level": 3,
"text": "Targets",
"anchor": "targets",
"htmlText": "Targets"
},
{
"level": 3,
"text": "Config",
"anchor": "config",
"htmlText": "Config"
},
{
"level": 3,
"text": "Scripts",
"anchor": "scripts",
"htmlText": "Scripts"
},
{
"level": 3,
"text": "Assets",
"anchor": "assets",
"htmlText": "Assets"
},
{
"level": 3,
"text": "Options",
"anchor": "options",
"htmlText": "Options"
},
{
"level": 3,
"text": "Output",
"anchor": "output",
"htmlText": "Output"
},
{
"level": 3,
"text": "Debug",
"anchor": "debug",
"htmlText": "Debug"
},
{
"level": 3,
"text": "Bytecode (reproducibility)",
"anchor": "bytecode-reproducibility",
"htmlText": "Bytecode (reproducibility)"
},
{
"level": 4,
"text": "Why would you want to do this?",
"anchor": "why-would-you-want-to-do-this",
"htmlText": "Why would you want to do this?"
},
{
"level": 4,
"text": "Why would you NOT want to do this?",
"anchor": "why-would-you-not-want-to-do-this",
"htmlText": "Why would you NOT want to do this?"
},
{
"level": 4,
"text": "Other considerations",
"anchor": "other-considerations",
"htmlText": "Other considerations"
},
{
"level": 3,
"text": "Build",
"anchor": "build",
"htmlText": "Build"
},
{
"level": 3,
"text": "Compression",
"anchor": "compression",
"htmlText": "Compression"
},
{
"level": 3,
"text": "Environment",
"anchor": "environment",
"htmlText": "Environment"
},
{
"level": 2,
"text": "Usage of packaged app",
"anchor": "usage-of-packaged-app",
"htmlText": "Usage of packaged app"
},
{
"level": 2,
"text": "Snapshot filesystem",
"anchor": "snapshot-filesystem",
"htmlText": "Snapshot filesystem"
},
{
"level": 2,
"text": "Detecting assets in source code",
"anchor": "detecting-assets-in-source-code",
"htmlText": "Detecting assets in source code"
},
{
"level": 2,
"text": "Native addons",
"anchor": "native-addons",
"htmlText": "Native addons"
},
{
"level": 2,
"text": "API",
"anchor": "api",
"htmlText": "API"
},
{
"level": 2,
"text": "Troubleshooting",
"anchor": "troubleshooting",
"htmlText": "Troubleshooting"
},
{
"level": 3,
"text": "Error: ENOENT: no such file or directory, uv_chdir",
"anchor": "error-enoent-no-such-file-or-directory-uv_chdir",
"htmlText": "Error: ENOENT: no such file or directory, uv_chdir"
},
{
"level": 3,
"text": "Error: ERR_INSPECTOR_NOT_AVAILABLE",
"anchor": "error-err_inspector_not_available",
"htmlText": "Error: ERR_INSPECTOR_NOT_AVAILABLE"
},
{
"level": 3,
"text": "Error: require(...).internalModuleStat is not a function",
"anchor": "error-requireinternalmodulestat-is-not-a-function",
"htmlText": "Error: require(...).internalModuleStat is not a function"
},
{
"level": 2,
"text": "Advanced",
"anchor": "advanced",
"htmlText": "Advanced"
},
{
"level": 3,
"text": "exploring virtual file system embedded in debug mode",
"anchor": "exploring-virtual-file-system-embedded-in-debug-mode",
"htmlText": "exploring virtual file system embedded in debug mode"
}
],
"siteNavLoginPath": "/login?return_to=https%3A%2F%2Fgithub.com%2Fvercel%2Fpkg"
}
},
{
"displayName": "LICENSE",
"repoName": "pkg",
"refName": "main",
"path": "LICENSE",
"preferredFileType": "license",
"tabName": "MIT",
"richText": null,
"loaded": false,
"timedOut": false,
"errorMessage": null,
"headerInfo": {
"toc": null,
"siteNavLoginPath": "/login?return_to=https%3A%2F%2Fgithub.com%2Fvercel%2Fpkg"
}
},
{
"displayName": "SECURITY.md",
"repoName": ".github",
"refName": "main",
"path": "SECURITY.md",
"preferredFileType": "security",
"tabName": "Security",
"richText": null,
"loaded": false,
"timedOut": false,
"errorMessage": null,
"headerInfo": {
"toc": null,
"siteNavLoginPath": "/login?return_to=https%3A%2F%2Fgithub.com%2Fvercel%2Fpkg"
}
}
],
"overviewFilesProcessingTime": 0
}
},
"appPayload": {
"helpUrl": "https://docs.github.com",
"findFileWorkerPath": "/assets-cdn/worker/find-file-worker-1583894afd38.js",
"findInFileWorkerPath": "/assets-cdn/worker/find-in-file-worker-3a63a487027b.js",
"githubDevUrl": null,
"enabled_features": {
"code_nav_ui_events": false,
"overview_shared_code_dropdown_button": false,
"react_blob_overlay": false,
"copilot_conversational_ux_embedding_update": false,
"copilot_smell_icebreaker_ux": true,
"copilot_workspace": false
}
}
}
}
{
"accept-ranges": "bytes",
"cache-control": "max-age=0, private, must-revalidate",
"content-encoding": "gzip",
"content-security-policy": "default-src 'none'; base-uri 'self'; child-src github.com/assets-cdn/worker/ gist.github.com/assets-cdn/worker/; connect-src 'self' uploads.github.com www.githubstatus.com collector.github.com raw.githubusercontent.com api.github.com github-cloud.s3.amazonaws.com github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com github-production-user-asset-6210df.s3.amazonaws.com api.githubcopilot.com objects-origin.githubusercontent.com copilot-proxy.githubusercontent.com/v1/engines/github-completion/completions proxy.enterprise.githubcopilot.com/v1/engines/github-completion/completions *.actions.githubusercontent.com wss://*.actions.githubusercontent.com productionresultssa0.blob.core.windows.net/ productionresultssa1.blob.core.windows.net/ productionresultssa2.blob.core.windows.net/ productionresultssa3.blob.core.windows.net/ productionresultssa4.blob.core.windows.net/ productionresultssa5.blob.core.windows.net/ productionresultssa6.blob.core.windows.net/ productionresultssa7.blob.core.windows.net/ productionresultssa8.blob.core.windows.net/ productionresultssa9.blob.core.windows.net/ productionresultssa10.blob.core.windows.net/ productionresultssa11.blob.core.windows.net/ productionresultssa12.blob.core.windows.net/ productionresultssa13.blob.core.windows.net/ productionresultssa14.blob.core.windows.net/ productionresultssa15.blob.core.windows.net/ productionresultssa16.blob.core.windows.net/ productionresultssa17.blob.core.windows.net/ productionresultssa18.blob.core.windows.net/ productionresultssa19.blob.core.windows.net/ github-production-repository-image-32fea6.s3.amazonaws.com github-production-release-asset-2e65be.s3.amazonaws.com insights.github.com wss://alive.github.com; font-src github.githubassets.com; form-action 'self' github.com gist.github.com copilot-workspace.githubnext.com objects-origin.githubusercontent.com; frame-ancestors 'none'; frame-src viewscreen.githubusercontent.com notebooks.githubusercontent.com; img-src 'self' data: blob: github.githubassets.com media.githubusercontent.com camo.githubusercontent.com identicons.github.com avatars.githubusercontent.com github-cloud.s3.amazonaws.com objects.githubusercontent.com secured-user-images.githubusercontent.com/ user-images.githubusercontent.com/ private-user-images.githubusercontent.com opengraph.githubassets.com github-production-user-asset-6210df.s3.amazonaws.com customer-stories-feed.github.com spotlights-feed.github.com objects-origin.githubusercontent.com *.githubusercontent.com; manifest-src 'self'; media-src github.com user-images.githubusercontent.com/ secured-user-images.githubusercontent.com/ private-user-images.githubusercontent.com github-production-user-asset-6210df.s3.amazonaws.com gist.github.com; script-src github.githubassets.com; style-src 'unsafe-inline' github.githubassets.com; upgrade-insecure-requests; worker-src github.com/assets-cdn/worker/ gist.github.com/assets-cdn/worker/",
"content-type": "text/html; charset=utf-8",
"date": "Sat, 27 Jul 2024 06:33:47 GMT",
"etag": "ef413fccb783b3b642a2f5132a78c619",
"referrer-policy": "no-referrer-when-downgrade",
"server": "GitHub.com",
"set-cookie": "logged_in=no; Path=/; Domain=github.com; Expires=Sun, 27 Jul 2025 06:33:46 GMT; HttpOnly; Secure; SameSite=Lax",
"strict-transport-security": "max-age=31536000; includeSubdomains; preload",
"transfer-encoding": "chunked",
"vary": "X-PJAX, X-PJAX-Container, Turbo-Visit, Turbo-Frame, Accept-Encoding, Accept, X-Requested-With",
"x-content-type-options": "nosniff",
"x-frame-options": "deny",
"x-github-request-id": "8878:21C908:C6CDD4:1007BF1:66A494CA",
"x-xss-protection": "0"
}