opentui: support Node.js 26 alongside Bun#1149
Open
simonklee wants to merge 10 commits into
Open
Conversation
Node's node:ffi has no usize, and Bun returns usize values as BigInt, forcing per-call coercion in the binding layer. Empty Uint8Arrays also cross to Zig as null pointers, which the old non-optional slice parameters could not safely accept. Replace usize length arguments with u32 and make slice pointers optional with explicit zero-length and null guards. This drops the BigInt round-trips and lines up the ABI for the Node.
Switch native log and event callback length parameters from usize to u32 so the JS bridge receives plain numbers on both Bun and Node FFI backends and avoids per-call BigInt conversion. Arena byte counts move to u64 and route through a safe-integer guard since the value can legitimately exceed u32. Pointer-typed arguments (Pointer, ArrayBuffer, ArrayBufferView, null) now normalize at the Node symbol boundary, and toArrayBuffer offsets are validated up front. Callers no longer need to wrap every buffer in ptr() to satisfy Node's stricter FFI surface.
Decouple the tree-sitter worker from runtime-specific globals so it can construct and communicate on Node, Bun, and other Worker-capable hosts through a single seam. The platform layer now owns main-thread worker construction (including a node:worker_threads shim) and worker-side message bridging, with a shared typed protocol on both ends.
Allow examples to run under Node 26 with --experimental-ffi in addition to Bun. Replace some Bun-specific APIs with standard Node equivalents, lazy-load demos that still require Bun (WebGPU, sprites, shaders), and import Rapier via its ESM subpath.
Add conditional exports (bun/node/default) so each runtime resolves the correct variant, and add a packed dist smoke test that verifies imports work in both Node.js and Bun.
The test suite was tightly coupled to Bun-specific APIs (bun:test, Bun.sleep) making it impossible to validate behavior on other runtimes. A module hook now rewrites bun:test imports for Node's test runner, and fake clocks replace wall-clock delays so tests run deterministically everywhere. Fix FFI type mismatches and boolean normalization that caused silent failures on non-Bun runtimes. Correct bundled asset resolution so published packages load without a TypeScript loader. Reorganize the example menu with themed sections, two-panel focus management, and proper tree-sitter cleanup to prevent worker leaks.
Add jsx/jsxs/jsxDEV/Fragment runtime implementations, split the build into Node and Bun entry points, and gate CI on Bun tests, Node source tests, and a packed-consumer smoke test that verifies the tarball installs and runs under Node.
Pack the dist artifacts, install them into a fresh Node project, and import every public entrypoint to verify the published shape. Wire the script into the keymap CI workflow and both npm release jobs so packed consumers are validated before npm sees them. Clarify the runtime split in the docs: import-only use is Node-safe, while creating a native renderer still requires Node 26 with --experimental-ffi.
Node.js 26.3 expects FFI signatures to use the current argument and return field names.
Require callers and CI jobs to select the supported Node.js version instead of downloading a private copy on demand.
This was referenced Jun 5, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bun remains the primary runtime; Node.js 26 is now a validated
second target, requiring --experimental-ffi for native rendering.
The published packages ship runtime-conditioned exports, the core
test suite runs under both lanes through a repo-owned bun:test
compatibility module, and the keymap and Solid packages have
packed-consumer smoke tests under Node.
Runtime-plugin, Solid preload, and Bun-plugin subpaths stay Bun-only for now.