Skip to content

fix(build): compile x64 binaries against Bun's baseline runtime - #797

Merged
elucid merged 1 commit into
mainfrom
fix/x64-baseline-binaries
Aug 18, 2026
Merged

fix(build): compile x64 binaries against Bun's baseline runtime#797
elucid merged 1 commit into
mainfrom
fix/x64-baseline-binaries

Conversation

@elucid

@elucid elucid commented Aug 17, 2026

Copy link
Copy Markdown
Member

Fixes #454.

Problem

Every prebuilt x64 binary dies before running a line of Hunk code on CPUs without AVX2 — pre-2013 hardware and VMs with a conservative CPU model. bun build --compile with no --target embeds Bun's default x64 runtime, which is built for Haswell (AVX2/BMI2). Reported against 0.15.3; 0.19.0 is identical.

Reproduced on a real Nehalem KVM VM and on Windows 11 masked to SandyBridge:

today with this PR
Linux x64 Illegal instruction (core dumped), exit 132 0.19.0, full TUI with syntax highlighting
Windows x64 Bun panic, Features: no_avx2, exit 3 0.19.0

Fix

Compile x64 hosts against Bun's baseline runtime, which needs only x86-64-v2 (SSE4.2/POPCNT, Nehalem 2008+). arm64 keeps Bun's host default. CI and the release workflow now run the built linux-x64 artifact under an emulated pre-AVX CPU, so dropping the target fails the build instead of shipping a binary that cannot start.

Performance tradeoff

The baseline runtime is compiled without AVX2-dependent codegen, so this trades a small amount of optimization for running on every x86-64 CPU since 2008. Measured, that tradeoff is not material. Both Bun runtimes were run against the repo's benchmark suite with per-sample interleaving on Skylake Linux and Windows hosts:

metrics median delta metrics with self-noise ≤3%
Linux (full suite, 15 samples/runtime) 58 −0.10% within ±1%
Linux (interleaved re-run, 9 samples) 18 −0.29% within ±1%
Windows (5 scripts, 7 paired samples) 41 +0.84% median +0.07%

Every metric that looked like a regression turned out to be noise: the release gate's own thresholds are exceeded by same-runtime control comparisons on these hosts, and the one metric with a consistent early signal (scroll_tick_median_ms, baseline slower in 5 of 7 pairs) reversed at 17 pairs to 4.6% faster, slower in 9 of 17.

At the primitive level only Bun.stringWidth moved (+19.5% CJK, +9.1% ASCII). OpenTUI calls it, but instrumenting real renders shows ~20 calls totaling 0.06–0.08 ms per render — Hunk's own width path is plain JS and unchanged — so it costs roughly 0.015 ms per frame.

Distribution

No asset or package names change, so npm, mise/aqua (hunkdiff-{{.OS}}-{{.Arch}}.tar.gz), and the GitHub release tarballs are unaffected. Homebrew builds from source via bun run build:bin, so its x86_64 bottles pick this up automatically. nix/package.nix invokes bun build --compile directly and is unchanged — --target fetches a runtime, which the Nix sandbox cannot do.

Not included

  • Launcher fallback in bin/hunk.cjs. Today it exits 1 with no output when the prebuilt binary dies. Worth fixing separately; note it cannot rescue Windows, where the failure is a normal exit code rather than a signal.
  • Nix, which still requires AVX2 to build and to run.

@vercel

vercel Bot commented Aug 17, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
hunk-web Ignored Ignored Preview Aug 18, 2026 3:09pm

Request Review

@elucid
elucid marked this pull request as ready for review August 17, 2026 22:05
@greptile-apps

greptile-apps Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR compiles x64 binaries against Bun’s baseline runtimes and adds pre-AVX2 startup checks to CI and release builds.

  • Selects OS- and libc-specific baseline targets for x64 hosts while retaining Bun’s default runtime on arm64.
  • Adds unit coverage for target selection and QEMU-based Linux compatibility gates.
  • Documents the new x86-64 CPU floor and records the patch-level release change.

Confidence Score: 4/5

The PR appears safe to merge after the non-blocking test-file indentation inconsistency is corrected.

The baseline target selection and Linux compatibility gates align with the supported native build matrix; the only accepted issue is formatting in the newly added unit test.

Files Needing Attention: scripts/build-bin.test.ts

Important Files Changed

Filename Overview
scripts/build-bin.ts Adds host-aware Bun baseline target selection and passes the selected target to compiled binary builds.
scripts/build-bin.test.ts Covers x64 platform targets, Linux musl selection, arm64 defaults, and unsupported platforms; formatting needs adjustment.
.github/workflows/ci.yml Adds a QEMU Nehalem smoke test for the locally built Linux x64 binary.
.github/workflows/release-prebuilt-npm.yml Adds the same pre-AVX2 startup gate to the released Linux x64 artifact build.
README.md Documents the SSE4.2 CPU requirement for x86-64 installations.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[build:bin] --> B{Host architecture}
    B -->|arm64 or unsupported| C[Bun host-default runtime]
    B -->|x64| D{Host platform}
    D -->|macOS| E[bun-darwin-x64-baseline]
    D -->|Windows| F[bun-windows-x64-baseline]
    D -->|Linux glibc| G[bun-linux-x64-baseline]
    D -->|Linux musl| H[bun-linux-x64-musl-baseline]
    E --> I[Compile dist binary]
    F --> I
    G --> I
    H --> I
    C --> I
    I --> J[Linux x64 QEMU Nehalem startup check]
Loading
Prompt To Fix All With AI
### Issue 1
scripts/build-bin.test.ts:5
**Test indentation breaks convention**

The newly added test bodies use two-space indentation instead of the repository's required four-space indentation, leaving the file inconsistent with the required formatting convention.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "fix(build): compile x64 binaries against..." | Re-trigger Greptile

Comment thread scripts/build-bin.test.ts
Bun's default x64 runtime is built for Haswell (AVX2/BMI2, 2013+), so every
prebuilt x64 Hunk binary died before running a line of Hunk code on older CPUs
and on VMs that expose a conservative CPU model: SIGILL on Linux, a Bun panic
with `Features: no_avx2` on Windows. Reported in #454 against 0.15.3 and
reproduced on 0.19.0.

Compile x64 hosts against Bun's baseline runtime instead, which only needs
x86-64-v2 (SSE4.2/POPCNT), and keep arm64 on Bun's host default. Both CI and
the release workflow now run the built linux-x64 artifact under an emulated
pre-AVX CPU so a dropped target fails the build instead of shipping a binary
that cannot start.

Measured on Skylake Linux and Windows hosts with the repo benchmark suite:
no material performance difference (median delta -0.29% Linux, +0.84% Windows;
metrics with self-noise <= 3% land within +-1%).
@elucid
elucid force-pushed the fix/x64-baseline-binaries branch from b1cd862 to b7db92f Compare August 18, 2026 15:09
@elucid
elucid merged commit ee3aa1b into main Aug 18, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Linux x64 prebuilt binary SIGILLs on non-AVX/Haswell CPU; Bun fallback works

1 participant