Skip to content

Detecting assets in source code

When pkg encounters path.join(__dirname, '../path/to/asset'), it automatically packages the referenced file as an asset — no manual assets entry needed. This static analysis avoids forcing every project to configure its assets explicitly.

The supported pattern

js
path.join(__dirname, 'views/greeting.html'); // ✅ detected
path.join(__dirname, 'migrations/001.sql'); // ✅ detected
path.join(__dirname, '../data/cities.json'); // ✅ detected

Two arguments only

path.join must have exactly two arguments, and the second must be a string literal. Anything else — three args, a variable, a template literal with expressions — is not detected.

Not detected

js
const view = 'greeting.html';
path.join(__dirname, 'views', view); // ❌ three arguments
path.join(__dirname, `views/${name}.html`); // ❌ expression inside template
const p = 'views/greeting.html';
path.join(__dirname, p); // ❌ variable, not literal

For these, list the file(s) manually in the assets glob — see Configuration → Assets.

How detection works

The static walker rewrites detected calls so that at runtime, the resolved path points at /snapshot/... and the asset is served from the virtual filesystem. If the call isn't detected, the asset isn't bundled and the packaged binary throws ENOENT at runtime.

How to find missing assets

  1. Build with --debug:
    sh
    pkg --debug index.js
  2. Run the binary with DEBUG_PKG=1:
    sh
    DEBUG_PKG=1 ./app-linux
  3. Look at the snapshot tree in the output — is your asset there? If not, either fix the call-site to match the supported pattern or add the asset to the assets glob.

See Debug virtual FS for the full debug workflow.

Escape hatch — dynamic assets

If your asset paths are genuinely dynamic (e.g. user-selected theme, loaded language pack), glob the whole directory in package.json:

json
{
  "pkg": {
    "assets": ["themes/**/*", "i18n/**/*.json"]
  }
}

This packages everything matching the glob, regardless of whether any specific path.join(...) call is statically analysable.

See also

Released under the MIT License.