Skip to content

Use Bun's JavaScriptCore builds on Android and Linux#206

Open
matthargett wants to merge 3 commits into
BabylonJS:mainfrom
rebeckerspecialties:agent/use-bun-jsc-android
Open

Use Bun's JavaScriptCore builds on Android and Linux#206
matthargett wants to merge 3 commits into
BabylonJS:mainfrom
rebeckerspecialties:agent/use-bun-jsc-android

Conversation

@matthargett

@matthargett matthargett commented Jul 12, 2026

Copy link
Copy Markdown

Summary

  • replace the abandoned jsc-android npm/AAR dependency and Linux WebKitGTK dependency with the JavaScriptCore archives published for the WebKit revision pinned by Bun v1.3.14 (5488984d20e0dbfe4be2c3ba8fb18eb81a5e0e8b);
  • support only arm64-v8a and x86_64 on Android, and only glibc arm64 and x86_64 on Linux;
  • consume the Linux full-LTO archives directly in the final PIE with Clang/LLD 21;
  • download only the selected asset, extract only the headers and six required archives, validate a revision/SHA-keyed completion stamp, and delete the tarball immediately; and
  • adapt JsRuntimeHost to the Bun embedder-held JSC API-lock model, including teardown ordering that keeps the N-API environment alive through VM last-chance finalizers.

This removes the need for npm, Maven, an AAR, WebKitGTK, or a separate jsc-android-buildscripts publication pipeline.

Platform model

Android

  • arm64-v8a: bun-webkit-linux-arm64-android.tar.gz
  • x86_64: bun-webkit-linux-amd64-android.tar.gz
  • API 28 minimum for the JSC path; V8/Hermes retain their existing minimums.
  • NDK r26b or newer is required by the current C++23 WebKit headers; the test app selects CI NDK r28c for JSC.
  • The archives are relinked into the existing libjsc.so boundary with a narrow export map and 16 KiB ELF alignment.

Bun does not publish Android LTO assets. These are the optimized native Android archives. The full-LTO variants are Linux-only.

Linux

  • x86_64: Nehalem-baseline bun-webkit-linux-amd64-baseline-lto.tar.gz
  • arm64: bun-webkit-linux-arm64-lto.tar.gz
  • Clang 21, LLD 21, and a C++23 standard library with <expected> are required. Ubuntu 22.04 installs libstdc++-12-dev for that header surface.
  • The result is a final PIE with full LTO, whole-program vtables, and section GC.
  • The practical compatibility floor is pinned to Ubuntu 22.04: GLIBC 2.35 and GLIBCXX 3.4.30.

The Bun Linux archives contain bmalloc local-exec TLS relocations, so they cannot be repackaged as a shared JSC library. They must flow through static napi/JsRuntimeHost targets into the final executable; a shared downstream final consumer is unsupported.

CI and disk use

  • Linux CI is pinned to Ubuntu 22.04 and installs only Clang/LLD 21 plus the GCC 12 C++ headers, using --no-install-recommends.
  • CMake downloads one ABI/architecture asset, checks its pinned SHA-256, extracts only include/, JavaScriptCore, WTF, bmalloc, and ICU, then deletes the compressed archive.
  • The x64 baseline-LTO selective cache measured 969 MB after extraction, with no retained tarball.
  • CI audits PIE flags, the JSC wrapper symbol, unresolved symbols, absence of a dynamic JavaScriptCore dependency, and maximum GLIBC/GLIBCXX symbol versions.

Validation

Focused main-based change:

  • Android arm64 API 31 emulator: 206 JavaScript tests and all 6 native tests passed.
  • Android x86_64 build completed with NDK r28c.
  • Android arm64 and x86_64 libjsc.so load segments are 16 KiB-aligned or better; the APK passes zipalign -c -P 16 -v 4.
  • Linux x64 full-LTO PIE runtime smoke passed before layering the N-API stack: 204 JavaScript tests and all 6 native tests.

Layered onto the pending napi-v7 patch stack:

  • Exact Ubuntu 22.04, Clang/LLD 21, GCC 12 headers, x64 baseline-LTO asset: 147 JavaScript tests and all 4 native runtime tests passed.
  • Linux NodeApiTests: 16 registered, 15 passed, and only the pre-existing quarantined test_reference_double_free/test_wrap.js case skipped. Real BigInt and instance-data tests passed.
  • The Linux node_lite PIE exports its napi_* surface for .node modules, has no unresolved or dynamic WebKit/JSC dependency, and requires at most GLIBC 2.35 / GLIBCXX 3.4.30.
  • Android arm64 API 31 emulator: 149 JavaScript tests passed; 11 of 12 native Node-API tests passed with the same one known quarantine skipped. Real BigInt and instance-data finalization passed.
  • Every packaged arm64 native library (libjsc.so, libnapi.so, JNI, libc++, and all Node-API addons) is 16 KiB-aligned or better, and the APK passes the 16 KiB zip-alignment check.
  • actionlint and git diff --check pass.

Conformance boundary

Tests/NodeApi is the repository patch stack adapted from Node.js js-native-api tests; it is not the complete upstream Node-API CTS. This establishes the selected v1-v6 surface plus the current v7 stack integration, but it does not claim complete N-API v7 coverage. The imported detach/get-all-property-names cases remain gated because their harness path also depends on the v9 node_api_basic_env surface.

Follow-up

The WebKit archives contain private cached-bytecode machinery but not the stable Bun bytecode generation/loading facade. A revision-locked JsRuntimeHost API for precompiled Babylon bundles remains separate work.

This is the JSC replacement referenced by the Android XR preparation in #182, and it unblocks the modern JSC portion of #187.

Closes #186

@matthargett matthargett changed the title Use Bun's JavaScriptCore build on Android Use Bun JavaScriptCore builds on Android and Linux Jul 12, 2026
@matthargett matthargett changed the title Use Bun JavaScriptCore builds on Android and Linux Use Bun's JavaScriptCore builds on Android and Linux Jul 12, 2026
@matthargett matthargett marked this pull request as ready for review July 12, 2026 06:53
Copilot AI review requested due to automatic review settings July 12, 2026 06:53
@matthargett

Copy link
Copy Markdown
Author

Ready for review. The hosted CI run is currently at GitHub's fork-workflow approval gate (run 29183225207); my token cannot approve workflows for the upstream repository. GitGuardian is green. The PR description records the completed Ubuntu 22.04 baseline-LTO, arm64 Android, N-API patch-stack, conformance, ABI-floor, and 16 KiB alignment validation.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates the JavaScriptCore integration on Android and Linux to consume Bun’s pinned WebKit/JavaScriptCore archive releases (instead of jsc-android/AAR and Linux WebKitGTK), and adapts JsRuntimeHost’s teardown/locking behavior to Bun’s embedder-held JSC API-lock model.

Changes:

  • Replace Android jsc-android + Linux WebKitGTK linkage with selective download/extraction of Bun WebKit JSC headers + static archives, plus a small wrapper (bun_jsc) to align with required locking/teardown semantics.
  • Tighten platform support expectations (Android arm64/x86_64 with API 28+ for JSC; Linux glibc arm64/x86_64 with Clang/LLD 21 and C++23 headers).
  • Update CI to build on Ubuntu 22.04 and audit the resulting PIE/static-JSC linkage properties.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
Tests/UnitTests/Android/app/build.gradle Raises minSdk for JSC builds and wires JSR_BUN_JSC_ROOT override through Gradle/CMake.
Core/Node-API/Source/jsc_bun.exports Adds an Android linker version-script to constrain exported symbols for libjsc.so.
Core/Node-API/Source/jsc_bun.cpp Introduces Bun-JSC init + VM/API-lock helpers used by the embedder/teardown path.
Core/Node-API/Source/js_native_api_javascriptcore.h Adds Bun-specific context/API locking RAII, plus shutdown-aware teardown ordering.
Core/Node-API/Source/js_native_api_javascriptcore.cc Avoids ref-tracking mutations during shutdown; ensures napi_coerce_to_bool validates env under Bun locking model.
Core/Node-API/package-jsc.json Removes the old jsc-android dependency metadata.
Core/Node-API/Include/Engine/JavaScriptCore/napi/env.h Adds Napi::ContextLock wrapper to keep the VM alive across ordering-sensitive operations.
Core/Node-API/CMakeLists.txt Implements Bun WebKit archive download/extract/stamp + Android shared wrapper / Linux static-LTO propagation.
Core/AppRuntime/Source/AppRuntime_JavaScriptCore.cpp Calls JSCBunInitialize() and adjusts release/detach ordering using Napi::ContextLock.
.github/workflows/ci.yml Updates Linux CI job matrix naming/selection to reflect the new JSC-LTO flow.
.github/workflows/build-linux.yml Pins Ubuntu 22.04, installs LLVM/LLD 21 as needed, and adds PIE/static-JSC audits.
.github/tsan_suppressions.txt Updates suppressions commentary/targets for the Bun statically-linked JSC scenario.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Core/Node-API/CMakeLists.txt Outdated
Comment thread .github/tsan_suppressions.txt Outdated
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.

RFC: replace abandoned jsc-android with a maintained JSC (Bun's WebKit fork) on Android

2 participants