HakobuHakobu

Assets & Scripts

How to include static files and scripts in your Hakobu package.

Hakobu can include non-code files -- templates, configuration, data files, and other static assets -- inside the packaged binary. These files are embedded in the snapshot filesystem and readable at runtime.

Declaring Assets

Use the "assets" field in your package.json to declare which files to include:

package.json
{
  "hakobu": {
    "assets": [
      "templates/**",
      "config.yaml",
      "locales/*.json"
    ]
  }
}

Asset paths support glob patterns. All matched files are included in the snapshot alongside your code.

Declaring Scripts

The "scripts" field lets you include additional JavaScript files that are not reachable through the normal require() / import dependency graph:

package.json
{
  "hakobu": {
    "scripts": [
      "workers/*.js",
      "plugins/**/*.js"
    ]
  }
}

This is useful for files that are loaded dynamically at runtime (e.g., worker scripts, plugin systems) where the analyzer cannot trace the dependency statically.

Accessing Assets at Runtime

Assets are embedded in the snapshot and accessible using standard fs APIs with __dirname-relative paths (CJS) or import.meta.url-derived paths (ESM).

CJS Example

app.js
const fs = require('fs');
const path = require('path');

const template = fs.readFileSync(
  path.join(__dirname, 'templates', 'email.html'),
  'utf-8'
);

ESM Example

app.mjs
import { readFileSync } from 'fs';
import { dirname, join } from 'path';
import { fileURLToPath } from 'url';

const __dirname = dirname(fileURLToPath(import.meta.url));

const config = JSON.parse(
  readFileSync(join(__dirname, 'config.yaml'), 'utf-8')
);

At runtime, these paths resolve to /snapshot/... locations inside the virtual filesystem. The fs module transparently reads from the snapshot when the path starts with /snapshot/. See Snapshot Filesystem for details.

External Artifacts

For large files that should not be embedded in the binary (browsers, helper tools, large data files), use the "externals" config instead:

package.json
{
  "hakobu": {
    "externals": ["camoufox-browser"]
  }
}

External artifacts are resolved at runtime in the following order:

  1. HAKOBU_EXTERNAL_{NAME} environment variable
  2. {execDir}/externals/{name}/
  3. Pattern path (absolute or relative to cwd)

This keeps the binary size manageable while still allowing your application to locate companion files at runtime.

On this page