Native Mode
How Hakobu's default native packaging mode works.
Native mode is Hakobu's default packaging mode. It packages your JavaScript files directly from disk without any transformation step, preserving the file-by-file structure inside the snapshot filesystem.
hakobu ./my-project --output ./dist/appWhen to Use Native Mode
Use native mode when your project is already plain JavaScript that Node.js can run directly. This is the primary path and the most predictable.
Native mode is ideal for:
- Pure JavaScript projects (CJS or ESM)
- Projects with no build step required
- Applications where you want the snapshot to mirror your source layout exactly
If your project requires TypeScript compilation, monorepo resolution, or tree-shaking, see Bundle Mode instead.
Entry Detection
Hakobu discovers your application entry point from package.json:
- The
"main"field (most common) - The
"module"field - The
"bin"field (for CLI tools)
You can also specify the entry explicitly:
hakobu ./my-project --entry src/index.js --output ./dist/appModule System Support
ESM
"type": "module"inpackage.json-- full support.mjsfiles -- full supportimport.meta.url-- returns afile:///snapshot/...URL- Static
import-- full support - Dynamic
import()-- supported for static string paths package.json"exports"map -- main entry and subpath exportspackage.json"imports"map (#specifiers) -- supported
CJS
require()-- full supportrequire.resolve()-- full support__dirname/__filename-- available, point to snapshot pathsmodule.exports/exports-- full support.cjsfiles -- full support- JSON
require('./data.json')-- full support
Mixed ESM/CJS
- ESM entry with
createRequire()for CJS dependencies -- works - CJS subpackage inside ESM root (via nested
"type": "commonjs") -- works .mjsin a CJS package /.cjsin an ESM package -- works
What Gets Included
Hakobu's analyzer traces your dependency graph starting from the entry point:
- JavaScript files -- all files reachable via
require()and staticimport - JSON files -- included as content
node_modules-- dependencies are traced and included- Assets -- files declared in the
"assets"config (see Assets & Scripts) - Native addons --
.nodefiles detected during analysis (see Native Addons)
Files that are not reachable from the entry point and not listed in assets are excluded from the binary.
Bytecode Compilation
Hakobu supports opt-in V8 bytecode compilation for CJS scripts. Bytecode pre-compiles your JavaScript into V8's internal format, which can improve startup time and provides light source obfuscation.
hakobu ./my-app --bytecode --output ./dist/appOr via package.json:
{
"hakobu": {
"bytecode": true
}
}| Input type | Bytecode compiled? |
|---|---|
CJS scripts (.js, .cjs) | Yes |
ESM scripts (.mjs, type: "module") | No -- source only |
| JSON files | No -- included as content |
| Assets / native addons | No -- included as content or extracted |
To disable bytecode compilation when it is enabled by config, use:
hakobu ./my-app --no-bytecode --output ./dist/appBytecode is V8 version-specific. Executables must run on the same V8 version they were compiled with. Bytecode mode cannot be combined with --bundle (bundle produces ESM, which does not support bytecode).
Snapshot Creation
After analysis and optional bytecode compilation, Hakobu creates the final executable:
- Analyze -- trace the dependency graph from the entry point
- Collect -- gather all scripts, assets, and native addons
- Compile -- optionally compile CJS scripts to V8 bytecode
- Pack -- embed everything into the snapshot filesystem
- Produce -- inject the snapshot into the patched Node base binary
The result is a single self-contained executable with all your code and dependencies embedded.