Migration from pkg
Migrate your project from @yao-pkg/pkg to Hakobu.
Hakobu is a fork of @yao-pkg/pkg (v6.14.1) rebuilt for Node 24 with native ESM support. Most pkg projects can migrate with minimal changes.
Migration Steps
Install Hakobu
Replace @yao-pkg/pkg with @hakobu/hakobu:
npm uninstall @yao-pkg/pkg
npm install -g @hakobu/hakobuOr as a dev dependency:
npm install @hakobu/hakobu --save-devUpdate your package.json config
Hakobu reads the "hakobu" field in package.json. The legacy "pkg" field is still accepted with a migration warning, so you can migrate incrementally.
Before (pkg):
{
"pkg": {
"scripts": ["lib/**/*.js"],
"assets": ["views/**", "public/**"],
"targets": ["node18-linux-x64", "node18-win-x64"],
"outputPath": "./dist"
}
}After (hakobu):
{
"hakobu": {
"assets": ["lib/**/*.js", "views/**", "public/**"],
"target": "node24-linux-x64",
"output": "./dist/my-app"
}
}You can leave the "pkg" field in place while migrating. Hakobu reads it and emits guidance about what to change. If both "hakobu" and "pkg" fields exist, "hakobu" takes priority and "pkg" is ignored.
Update CLI commands
Replace pkg with hakobu in your build scripts:
{
"scripts": {
"build:exe": "hakobu . --output ./dist/my-app"
}
}Update target strings
Change Node version targets from older versions to node24:
- hakobu . --target node18-linux-x64
+ hakobu . --target node24-linux-x64Test the packaged binary
Run the output executable and verify your application works correctly:
./dist/my-appConfig Field Mapping
| pkg option | Hakobu equivalent | Notes |
|---|---|---|
pkg.scripts | hakobu.assets | Merged into assets list. In pkg, "scripts" were extra JS files to compile; Hakobu includes all reachable files automatically. |
pkg.assets | hakobu.assets | Direct mapping. |
pkg.targets | hakobu.target | Hakobu builds one target at a time, or use comma-separated multi-target. |
pkg.outputPath | hakobu.output | Direct mapping. |
pkg.patches | Not supported | Hakobu does not support source patching. |
pkg.dictionary | Not supported | Hakobu resolves dependencies directly. |
pkg.deployFiles | hakobu.assets or hakobu.externals | Use assets for files to embed, externals for files kept outside. |
pkg.ignore | Not needed | Hakobu only includes files reachable from the entry point. |
CLI Flag Mapping
| pkg flag | Hakobu flag | Notes |
|---|---|---|
-t, --targets | --target | Singular. Comma-separated multi-target or all for all published targets. |
-o, --output | --output | Same. |
-d, --debug | --debug / -d | Same. Shows detailed packaging diagnostics. |
-c, --config | Not supported | Use "hakobu" field in package.json. |
--out-path | --output | Accepted with warning. Use --output with a full path. |
--no-bytecode | Not needed | Hakobu always packages source (no bytecode mode by default). |
--compress | --compress | Same. Supports Brotli and GZip. |
--public | Not needed | Hakobu always includes source. |
--sea | Not supported | Hakobu uses its own snapshot format. |
--options | --options | Same. Comma-separated V8 flags baked into the executable. |
--build / -b | --build / -b | Same. Forces local build of base binary instead of downloading. |
--no-native-build | Not needed | Hakobu does not prebuild native addons. |
--no-dict | Not supported | Dictionaries are not used. |
Unsupported flags cause a clear error with an explanation. For example, --sea produces: Error! --sea is not supported. Hakobu uses its own snapshot format, not Node SEA.
Key Behavioral Differences
Node Version
- pkg: Supported Node 8--22 with V8 bytecode compilation.
- Hakobu: Targets Node 24 only. Base binaries are Node 24.14.0.
Module Format
- pkg: CJS-first. ESM was experimental and required workarounds.
- Hakobu: Native ESM by default.
"type": "module"in package.json works out of the box. CJS also works. Mixed ESM/CJS withcreateRequire()works.
Multi-Target Builds
- pkg:
pkg -t node18-linux,node18-win,node18-macos .builds three executables in one command. - Hakobu: Same syntax supported with comma-separated targets or the
allshorthand:
hakobu . --target node24-linux-x64,node24-win-x64,node24-macos-arm64 --output dist/
hakobu . --target all --output dist/Hakobu performs shared analysis and parallel base binary fetching for efficiency.
No Bytecode Compilation (by default)
- pkg: Could compile JS to V8 bytecode (default behavior).
- Hakobu: Packages source by default. This simplifies the pipeline and avoids V8 version mismatch issues. The executable still contains a snapshot filesystem -- source is not visible to end users without effort. Bytecode can be opted into with
--bytecode.
Cache Location
- pkg:
~/.pkg-cache/ - Hakobu:
~/.hakobu/cache/
These do not conflict. You can have both installed side by side.
Binary Naming
- pkg: Base binaries named
fetched-v{nodeVersion}-{platform}-{arch} - Hakobu: Base binaries named
hakobu-base-v{nodeVersion}-{platform}-{arch}
Bundle Mode (new)
Hakobu adds optional bundle mode (--bundle) for TypeScript and monorepo projects. This has no pkg equivalent -- pkg required pre-compiled JavaScript.
hakobu ./my-ts-app --bundle --output ./dist/appDiagnostic Commands (new)
Hakobu adds commands that pkg did not have:
hakobu targets # Show available targets and cache status
hakobu inspect ./my-app # Analyze project without packaging
hakobu doctor ./my-app # Check if project is ready to packageWhat Should Work Without Changes
- Simple CJS projects with
require()andmodule.exports - JSON file loading via
require('./data.json') - Native addon loading (
.nodefiles) child_process.fork()andchild_process.spawn()worker_threadswithworkerDataprocess.execPathpointing to the packaged binary__dirnameand__filenamein CJS modules
What Needs Attention
- ESM entries: If your
package.jsonhas"type": "module", Hakobu handles it natively. No changes needed, but this is different from pkg's CJS-only model. process.execPathwith-e: Spawningprocess.execPath -e "code"does not work in packaged mode (same as pkg). Use script files instead.- Bytecode protection: If you relied on bytecode to obscure source, Hakobu does not offer this by default. Source is embedded in the snapshot.