HakobuHakobu

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-arm64

Hakobu 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}:

PlatformDescription
linuxglibc-based Linux (Ubuntu, Debian, RHEL, Fedora, etc.)
linuxstaticStatically linked Linux (works on any Linux distro)
macosmacOS (Darwin)
winWindows
ArchitectureDescription
x6464-bit x86 (Intel/AMD)
arm6464-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-arm64

The 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:

package.json
{
  "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:

TierTargetsRelease Status
Tier 1linux-x64, linux-arm64, win-x64, macos-arm64Release-blocking -- must pass all tests
Tier 2macos-x64, linuxstatic-x64, linuxstatic-arm64, win-arm64Supported, best-effort
Tier 3alpine-*, linux-armv7, freebsd-*, and othersDeferred -- 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

On this page