Cross-Platform Targeting
Build executables for multiple platforms from a single machine.
Multi-Target Builds
Hakobu can produce executables for multiple platforms and architectures in a single command. Pass a comma-separated list of targets to the --target flag:
hakobu ./my-app --target node24-linux-x64,node24-win-x64,node24-macos-arm64Hakobu analyzes and bundles your code once, then produces a separate binary for each target. Only the binary injection step runs per target, so multi-target builds are significantly faster than running separate commands.
Target Format
Each target follows the pattern node24-{platform}-{arch}:
| Platform | Description |
|---|---|
linux | glibc-based Linux (Ubuntu, Debian, RHEL, Fedora, etc.) |
linuxstatic | Statically linked Linux (works on any Linux distro) |
macos | macOS (Darwin) |
win | Windows |
| Architecture | Description |
|---|---|
x64 | 64-bit x86 (Intel/AMD) |
arm64 | 64-bit ARM (Apple Silicon, AWS Graviton) |
Build All Targets
Use the all shorthand to build for every platform with a published base binary:
hakobu ./my-app --target all --output ./dist/This expands to: linux-x64, linux-arm64, win-x64, macos-arm64, macos-x64, and linuxstatic-x64.
Output Directory
When building for multiple targets, --output must be a directory, not a file path. Hakobu creates one executable per target using the naming convention {appId}-{platform}-{arch}:
hakobu ./my-app --target node24-linux-x64,node24-win-x64,node24-macos-arm64 --output ./dist/dist/
├── my-app-linux-x64
├── my-app-win-x64.exe
└── my-app-macos-arm64The appId is derived from the name field in your package.json. Windows executables automatically receive the .exe extension.
If --output is omitted, executables are written to the current directory.
When only a single target is specified, --output can still be a file path -- the existing single-target behavior is unchanged.
Configuration via package.json
You can define multiple targets in your package.json instead of passing them on the command line:
{
"hakobu": {
"targets": ["node24-linux-x64", "node24-win-x64", "node24-macos-arm64"],
"output": "./dist"
}
}Use targets (plural) for multi-target mode. The singular target field still works for single targets. CLI flags override the package.json configuration.
Programmatic API
For build scripts and tooling, use the packageMultiple() function:
import { packageMultiple } from '@hakobu/hakobu';
const results = await packageMultiple({
projectRoot: '/path/to/project',
targets: ['node24-linux-x64', 'node24-win-x64', 'node24-macos-arm64'],
outputDir: './dist',
});
for (const r of results) {
console.log(`${r.target.platform}-${r.target.arch}: ${r.outputPath} (${r.status})`);
}Support Tiers
Not all targets carry the same level of support. Hakobu classifies targets into tiers:
| Tier | Targets | Release Status |
|---|---|---|
| Tier 1 | linux-x64, linux-arm64, win-x64, macos-arm64 | Release-blocking -- must pass all tests |
| Tier 2 | macos-x64, linuxstatic-x64, linuxstatic-arm64, win-arm64 | Supported, best-effort |
| Tier 3 | alpine-*, linux-armv7, freebsd-*, and others | Deferred -- not built or published |
Hakobu targets Node 24.x LTS exclusively. Older Node lines (20, 22) inherited from @yao-pkg/pkg are not part of the Hakobu support contract.
Error Handling
Multi-target builds are resilient. If one target fails, the others still proceed:
- Invalid target -- skipped with an error, other targets continue
- Base binary fetch failure -- skipped, other targets continue
- All targets failed -- exit code 1
- Mix of success and failure -- exit code 1, summary shows which failed
After all targets complete, Hakobu prints a summary table:
=== Packaging Results ===
OK linux-x64 → dist/my-app-linux-x64 (67 MB)
OK win-x64 → dist/my-app-win-x64.exe (101 MB)
OK macos-arm64 → dist/my-app-macos-arm64 (68 MB)
3 succeeded, 0 failed