mirror of
https://github.com/anomalyco/opentui.git
synced 2026-09-19 01:26:03 +08:00
node: support Node.js 26.4 and later (#1410)
Keep 26.4.0 as the minimum supported version while allowing later releases.
This commit is contained in:
@@ -15,7 +15,7 @@ concurrency:
|
||||
|
||||
env:
|
||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
||||
NODE_VERSION: 26.4.0
|
||||
NODE_VERSION: 26.7.0
|
||||
ZIG_VERSION: 0.16.0
|
||||
|
||||
jobs:
|
||||
|
||||
@@ -15,7 +15,7 @@ concurrency:
|
||||
|
||||
env:
|
||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
||||
NODE_VERSION: 26.4.0
|
||||
NODE_VERSION: 26.7.0
|
||||
|
||||
jobs:
|
||||
test:
|
||||
|
||||
@@ -15,7 +15,7 @@ concurrency:
|
||||
|
||||
env:
|
||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
||||
NODE_VERSION: 26.4.0
|
||||
NODE_VERSION: 26.7.0
|
||||
|
||||
jobs:
|
||||
bun-test:
|
||||
|
||||
@@ -15,7 +15,7 @@ concurrency:
|
||||
|
||||
env:
|
||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
||||
NODE_VERSION: 26.4.0
|
||||
NODE_VERSION: 26.7.0
|
||||
|
||||
jobs:
|
||||
test:
|
||||
|
||||
@@ -22,7 +22,7 @@ permissions:
|
||||
id-token: write
|
||||
|
||||
env:
|
||||
NODE_VERSION: 26.4.0
|
||||
NODE_VERSION: 26.7.0
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
|
||||
@@ -10,7 +10,7 @@ permissions:
|
||||
contents: write
|
||||
|
||||
env:
|
||||
NODE_VERSION: 26.4.0
|
||||
NODE_VERSION: 26.7.0
|
||||
|
||||
jobs:
|
||||
# Extract version and check if it's a dry run
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
- Use Bun for dependency management and development commands: `bun install`, `bun run <script>`, `bun test`, and `bun <file>`.
|
||||
- Run package scripts from the package directory unless the script is defined at the repository root.
|
||||
- Shared runtime code must preserve the supported Bun and Node paths. Keep runtime-specific behavior behind existing
|
||||
platform/runtime/build seams; do not introduce Bun-only APIs into shared modules. Node checks use the version enforced
|
||||
by `scripts/node26.mjs`.
|
||||
platform/runtime/build seams; do not introduce Bun-only APIs into shared modules. Node checks use the minimum
|
||||
version enforced by `scripts/node26.mjs`.
|
||||
|
||||
## Verification
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ Calibration failures retry a complete pair. Retained timing and pair-gap drift a
|
||||
|
||||
## Run
|
||||
|
||||
From `packages/core`, set `NODE26_PATH` to Node 26.4.0:
|
||||
From `packages/core`, set `NODE26_PATH` to Node 26.4 or later:
|
||||
|
||||
```sh
|
||||
export NODE26_PATH=/absolute/path/to/node
|
||||
|
||||
@@ -5,6 +5,7 @@ import { readFileSync, rmSync, writeFileSync } from "node:fs"
|
||||
import { availableParallelism, tmpdir } from "node:os"
|
||||
import { dirname, join, resolve } from "node:path"
|
||||
import { fileURLToPath } from "node:url"
|
||||
import { isSupportedNode26Version } from "../../../../scripts/node26.mjs"
|
||||
|
||||
type RuntimeName = "bun" | "node"
|
||||
type SuiteName = "quick" | "default" | "long"
|
||||
@@ -84,7 +85,9 @@ if (unknownScenarios.length > 0) throw new Error(`unknown scenarios: ${unknownSc
|
||||
if (selectedNames.length === 0) throw new Error("no benchmark scenarios selected")
|
||||
|
||||
const nodeVersion = readNodeVersion()
|
||||
if (nodeVersion !== "v26.4.0") throw new Error(`Node v26.4.0 is required, got ${nodeVersion}`)
|
||||
if (!isSupportedNode26Version(nodeVersion)) {
|
||||
throw new Error(`Node v26.4.0 or later is required, got ${nodeVersion}`)
|
||||
}
|
||||
|
||||
const raw = new Map<string, ProcessRoundSample[]>()
|
||||
const scenarioMetadata = new Map<string, ChildPayload["scenario"]>()
|
||||
|
||||
@@ -6,6 +6,7 @@ import { existsSync, readFileSync, realpathSync, renameSync, rmSync, writeFileSy
|
||||
import { availableParallelism, cpus, loadavg, release, tmpdir } from "node:os"
|
||||
import { dirname, isAbsolute, join, resolve } from "node:path"
|
||||
import { fileURLToPath } from "node:url"
|
||||
import { isSupportedNode26Version } from "../../../../scripts/node26.mjs"
|
||||
import { getNativeAssetDescriptor, type NodeAssetTarget } from "../node-asset-target.js"
|
||||
import {
|
||||
analyzePairedObservations,
|
||||
@@ -134,7 +135,9 @@ if (process.env.OTUI_ASSET_ROOT) {
|
||||
throw new Error("unset OTUI_ASSET_ROOT so paired provenance matches the native packages being hashed")
|
||||
}
|
||||
const nodeRuntime = readNodeRuntime()
|
||||
if (nodeRuntime.version !== "v26.4.0") throw new Error(`Node v26.4.0 is required, got ${nodeRuntime.version}`)
|
||||
if (!isSupportedNode26Version(nodeRuntime.version)) {
|
||||
throw new Error(`Node v26.4.0 or later is required, got ${nodeRuntime.version}`)
|
||||
}
|
||||
|
||||
const baseline = createTarget("baseline", baselineRoot)
|
||||
const candidate = createTarget("candidate", candidateRoot)
|
||||
|
||||
@@ -83,7 +83,9 @@ mkdirSync(attemptsDir, { recursive: true })
|
||||
mkdirSync(reportsDir, { recursive: true })
|
||||
|
||||
const nodeRuntime = readNodeRuntime()
|
||||
if (nodeRuntime.version !== "v26.4.0") throw new Error(`Node v26.4.0 is required, got ${nodeRuntime.version}`)
|
||||
if (!isSupportedNode26Version(nodeRuntime.version)) {
|
||||
throw new Error(`Node v26.4.0 or later is required, got ${nodeRuntime.version}`)
|
||||
}
|
||||
if (nodeRuntime.arch !== "x64") throw new Error(`Node x64 is required, got ${nodeRuntime.arch}`)
|
||||
|
||||
buildNodeScenario()
|
||||
@@ -166,7 +168,7 @@ for (let attemptIndex = 0; attemptIndex < runs; attemptIndex++) {
|
||||
payload.schemaVersion === 1 &&
|
||||
payload.scenario.name === scenario &&
|
||||
payload.sample.runtime.name === "node" &&
|
||||
payload.sample.runtime.version === "v26.4.0" &&
|
||||
isSupportedNode26Version(payload.sample.runtime.version) &&
|
||||
payload.sample.runtime.arch === "x64" &&
|
||||
payload.sample.operations > 0 &&
|
||||
payload.sample.elapsedNs > 0 &&
|
||||
@@ -245,6 +247,18 @@ if (
|
||||
)
|
||||
process.exit(1)
|
||||
|
||||
function isSupportedNode26Version(version: string): boolean {
|
||||
const match = /^v?(\d+)\.(\d+)\.(\d+)/.exec(version)
|
||||
if (match === null) return false
|
||||
|
||||
const major = Number(match[1])
|
||||
const minor = Number(match[2])
|
||||
const patch = Number(match[3])
|
||||
if (major !== 26) return major > 26
|
||||
if (minor !== 4) return minor > 4
|
||||
return patch >= 0
|
||||
}
|
||||
|
||||
function readNodeRuntime(): {
|
||||
version: string
|
||||
execPath: string
|
||||
|
||||
@@ -5,6 +5,7 @@ import { readFileSync, rmSync, writeFileSync } from "node:fs"
|
||||
import { availableParallelism, tmpdir } from "node:os"
|
||||
import { dirname, join, resolve } from "node:path"
|
||||
import { fileURLToPath } from "node:url"
|
||||
import { isSupportedNode26Version } from "../../../../scripts/node26.mjs"
|
||||
|
||||
type RuntimeName = "bun" | "node"
|
||||
|
||||
@@ -65,7 +66,9 @@ if (suite !== "quick" && suite !== "default" && suite !== "long") {
|
||||
}
|
||||
|
||||
const nodeVersion = readNodeVersion()
|
||||
if (nodeVersion !== "v26.4.0") throw new Error(`Node v26.4.0 is required, got ${nodeVersion}`)
|
||||
if (!isSupportedNode26Version(nodeVersion)) {
|
||||
throw new Error(`Node v26.4.0 or later is required, got ${nodeVersion}`)
|
||||
}
|
||||
|
||||
const listedScenarios = listScenarios()
|
||||
const scenarios = listedScenarios
|
||||
|
||||
@@ -756,8 +756,10 @@ function toNodeFFIType(type: FFITypeOrString, position: "parameter" | "result"):
|
||||
// Bun's N-API bridge types are not equivalent to raw Node FFI pointers.
|
||||
throw new Error(NODE_NAPI_UNSUPPORTED)
|
||||
case FFIType.buffer:
|
||||
// Node 26.4's Linux fast-buffer trampoline can pass a null pointer for
|
||||
// multi-argument signatures. The pointer path still borrows the owner.
|
||||
// Keep `buffer` on the pointer path. Node 26.4's Linux fast-buffer trampoline
|
||||
// can pass a null pointer for multi-argument signatures, and later Fast FFI
|
||||
// still treats buffer-shaped args more tightly than pointer args. The pointer
|
||||
// path still borrows the owner for the call.
|
||||
return "pointer"
|
||||
default:
|
||||
return unsupportedNodeFFIType(type)
|
||||
|
||||
@@ -39,9 +39,9 @@ npm install @opentui/ssh
|
||||
```
|
||||
|
||||
`@opentui/core` is a peer dependency. Supported runtimes are Bun ≥ 1.3.0 and
|
||||
Node.js 26.4.0. CI runs the SSH integration suite with Bun on macOS, Linux,
|
||||
Node.js ≥ 26.4.0. CI runs the SSH integration suite with Bun on macOS, Linux,
|
||||
and Windows, and installs, imports, starts, and closes the packed ESM package
|
||||
with Node.js 26.4.0.
|
||||
on Node.js.
|
||||
|
||||
## The shape: `createServer(config).serve(handler)`
|
||||
|
||||
|
||||
@@ -45,6 +45,6 @@
|
||||
},
|
||||
"engines": {
|
||||
"bun": ">=1.3.0",
|
||||
"node": "26.4.0"
|
||||
"node": ">=26.4.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ export default {
|
||||
}
|
||||
```
|
||||
|
||||
Use Node.js 26.4.0 with `--experimental-ffi`. If you enable the Node permission model, also pass `--permission`,
|
||||
Use Node.js 26.4.0 or later with `--experimental-ffi`. If you enable the Node permission model, also pass `--permission`,
|
||||
`--allow-ffi`, and the filesystem permissions that the application needs. The Solid Node source lane in CI compiles
|
||||
TSX and runs on Linux x64.
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ A failed automatic start destroys the partial native engine. Successful automati
|
||||
|
||||
Audio uses the same native runtime as the renderer. Read [Runtime and platform support](/docs/getting-started/runtime-support) for setup and distribution details.
|
||||
|
||||
The local requirements are Bun 1.3.0 or later, or Node.js 26.4.0 with experimental FFI. Native packages support macOS, Linux, and Windows on x64 and arm64.
|
||||
The local requirements are Bun 1.3.0 or later, or Node.js 26.4.0 or later with experimental FFI. Native packages support macOS, Linux, and Windows on x64 and arm64.
|
||||
|
||||
Linux selects glibc by default. Set the documented libc selector when the target needs musl. Audio has no browser target.
|
||||
|
||||
|
||||
@@ -15,10 +15,9 @@ Check the runtime, native artifact, permission, asset, and package requirements
|
||||
| Runtime | Project requirement | Native Core requirements |
|
||||
| ------- | ------------------- | ------------------------------------------------------ |
|
||||
| Bun | 1.3.0 or later | Bun loads the matching optional native package. |
|
||||
| Node.js | 26.4.0 exactly | Use ECMAScript modules (ESM) and `--experimental-ffi`. |
|
||||
| Node.js | 26.4.0 or later | Use ECMAScript modules (ESM) and `--experimental-ffi`. |
|
||||
|
||||
The Node.js acceptance scripts reject every version other than 26.4.0. Do not interpret this requirement as
|
||||
Node.js 26 or later.
|
||||
The Node.js acceptance scripts accept Node.js 26.4 or later.
|
||||
|
||||
Use ESM for Node.js applications. The Core root has an asynchronous ESM graph. A CommonJS `require("@opentui/core")`
|
||||
call fails with `ERR_REQUIRE_ASYNC_MODULE`.
|
||||
|
||||
@@ -27,49 +27,49 @@ A row can have more than one class. Read [Runtime and platform support](/docs/ge
|
||||
|
||||
The runtime column describes the published target. A Node stub throws during import for each Bun-only support entry point.
|
||||
|
||||
| Package entry point | Runtime | Class | Canonical documentation |
|
||||
| ------------------------------------------------- | --------------------------- | ----------------------------------------------- | ---------------------------------------------------------------- |
|
||||
| `@opentui/core` | Bun and Node.js | Supported | [Renderer](/docs/core-concepts/renderer) |
|
||||
| `@opentui/core/testing` | Bun and Node.js | Supported | [Testing](/docs/core-concepts/testing) |
|
||||
| `@opentui/core/runtime-plugin` | Bun only | Runtime-specific, Advanced | [Runtime module loading](/docs/extend/runtime-plugins) |
|
||||
| `@opentui/core/runtime-plugin-support` | Bun only | Runtime-specific, Advanced | [Runtime module loading](/docs/extend/runtime-plugins) |
|
||||
| `@opentui/core/runtime-plugin-support/configure` | Bun only | Runtime-specific, Advanced | [Runtime module loading](/docs/extend/runtime-plugins) |
|
||||
| `@opentui/core/yoga` | Bun and Node.js | Advanced | [Yoga API](/docs/reference/yoga) |
|
||||
| `@opentui/core/tree-sitter/update-assets` | Build time, with Bun CLI | Runtime-specific | [Tree-sitter](/docs/reference/tree-sitter) |
|
||||
| `@opentui/core/parser.worker` | Bun and Node.js worker | Implementation-looking public export | [Tree-sitter](/docs/reference/tree-sitter) |
|
||||
| `@opentui/core/node-assets` | Node.js build time | Runtime-specific | [Standalone executables](/docs/reference/standalone-executables) |
|
||||
| `@opentui/react` | Bun and Node.js | Supported | [React bindings](/docs/bindings/react) |
|
||||
| `@opentui/react/renderer` | Bun and Node.js | Supported, Implementation-looking public export | [React bindings](/docs/bindings/react) |
|
||||
| `@opentui/react/test-utils` | Bun and Node.js | Supported | [Testing](/docs/core-concepts/testing) |
|
||||
| `@opentui/react/runtime-plugin-support` | Bun only | Runtime-specific, Advanced | [Runtime module loading](/docs/extend/runtime-plugins) |
|
||||
| `@opentui/react/runtime-plugin-support/configure` | Bun only | Runtime-specific, Advanced | [Runtime module loading](/docs/extend/runtime-plugins) |
|
||||
| `@opentui/react/jsx-runtime` | Compiler selected | Supported | [React bindings](/docs/bindings/react) |
|
||||
| `@opentui/react/jsx-dev-runtime` | Compiler selected | Supported | [React bindings](/docs/bindings/react) |
|
||||
| `@opentui/solid` | Bun and Node.js | Supported | [Solid bindings](/docs/bindings/solid) |
|
||||
| `@opentui/solid/preload` | Bun only | Runtime-specific | [Solid bindings](/docs/bindings/solid) |
|
||||
| `@opentui/solid/bun-plugin` | Bun only | Runtime-specific, Advanced | [Solid bindings](/docs/bindings/solid) |
|
||||
| `@opentui/solid/runtime-plugin-support` | Bun only | Runtime-specific, Advanced | [Runtime module loading](/docs/extend/runtime-plugins) |
|
||||
| `@opentui/solid/runtime-plugin-support/configure` | Bun only | Runtime-specific, Advanced | [Runtime module loading](/docs/extend/runtime-plugins) |
|
||||
| `@opentui/solid/components` | Bun and Node.js | Advanced | [Solid bindings](/docs/bindings/solid) |
|
||||
| `@opentui/solid/jsx-runtime` | Compiler selected | Supported | [Solid bindings](/docs/bindings/solid) |
|
||||
| `@opentui/solid/jsx-dev-runtime` | Compiler selected | Supported | [Solid bindings](/docs/bindings/solid) |
|
||||
| `@opentui/keymap` | JavaScript runtimes | Supported | [Core keymap API](/docs/keymap/core) |
|
||||
| `@opentui/keymap/extras` | JavaScript runtimes | Supported | [Core keymap API](/docs/keymap/core) |
|
||||
| `@opentui/keymap/extras/graph` | JavaScript runtimes | Advanced | [Core keymap API](/docs/keymap/core) |
|
||||
| `@opentui/keymap/addons` | JavaScript runtimes | Supported | [Built-in keymap addons](/docs/keymap/addons) |
|
||||
| `@opentui/keymap/addons/opentui` | Bun and Node.js | Supported | [Built-in keymap addons](/docs/keymap/addons) |
|
||||
| `@opentui/keymap/testing` | JavaScript test runtimes | Supported | [Core keymap API](/docs/keymap/core) |
|
||||
| `@opentui/keymap/html` | Browser DOM | Runtime-specific | [Keymap hosts](/docs/keymap/hosts) |
|
||||
| `@opentui/keymap/opentui` | Bun and Node.js | Runtime-specific | [Keymap hosts](/docs/keymap/hosts) |
|
||||
| `@opentui/keymap/react` | OpenTUI React | Runtime-specific | [React keymap integration](/docs/keymap/react) |
|
||||
| `@opentui/keymap/solid` | OpenTUI Solid | Runtime-specific | [Solid keymap integration](/docs/keymap/solid) |
|
||||
| `@opentui/keymap/runtime-modules` | Bun runtime loading | Runtime-specific, Advanced | [Runtime module loading](/docs/extend/runtime-plugins) |
|
||||
| `@opentui/qrcode` | Bun and Node.js | Supported | [QR encoder](/docs/reference/qr-encoder) |
|
||||
| `@opentui/qrcode/react` | OpenTUI React | Runtime-specific | [QR code component](/docs/components/qr-code) |
|
||||
| `@opentui/qrcode/solid` | OpenTUI Solid | Runtime-specific | [QR code component](/docs/components/qr-code) |
|
||||
| `@opentui/ssh` | Bun 1.3.0 or Node.js 26.4.0 | Runtime-specific | [SSH](/docs/reference/ssh) |
|
||||
| `@opentui/three` | Bun only | Runtime-specific, Advanced | [Three.js WebGPU](/docs/reference/three) |
|
||||
| `@opentui/three/runtime-modules` | Bun only | Runtime-specific, Advanced | [Runtime module loading](/docs/extend/runtime-plugins) |
|
||||
| Package entry point | Runtime | Class | Canonical documentation |
|
||||
| ------------------------------------------------- | ------------------------------------ | ----------------------------------------------- | ---------------------------------------------------------------- |
|
||||
| `@opentui/core` | Bun and Node.js | Supported | [Renderer](/docs/core-concepts/renderer) |
|
||||
| `@opentui/core/testing` | Bun and Node.js | Supported | [Testing](/docs/core-concepts/testing) |
|
||||
| `@opentui/core/runtime-plugin` | Bun only | Runtime-specific, Advanced | [Runtime module loading](/docs/extend/runtime-plugins) |
|
||||
| `@opentui/core/runtime-plugin-support` | Bun only | Runtime-specific, Advanced | [Runtime module loading](/docs/extend/runtime-plugins) |
|
||||
| `@opentui/core/runtime-plugin-support/configure` | Bun only | Runtime-specific, Advanced | [Runtime module loading](/docs/extend/runtime-plugins) |
|
||||
| `@opentui/core/yoga` | Bun and Node.js | Advanced | [Yoga API](/docs/reference/yoga) |
|
||||
| `@opentui/core/tree-sitter/update-assets` | Build time, with Bun CLI | Runtime-specific | [Tree-sitter](/docs/reference/tree-sitter) |
|
||||
| `@opentui/core/parser.worker` | Bun and Node.js worker | Implementation-looking public export | [Tree-sitter](/docs/reference/tree-sitter) |
|
||||
| `@opentui/core/node-assets` | Node.js build time | Runtime-specific | [Standalone executables](/docs/reference/standalone-executables) |
|
||||
| `@opentui/react` | Bun and Node.js | Supported | [React bindings](/docs/bindings/react) |
|
||||
| `@opentui/react/renderer` | Bun and Node.js | Supported, Implementation-looking public export | [React bindings](/docs/bindings/react) |
|
||||
| `@opentui/react/test-utils` | Bun and Node.js | Supported | [Testing](/docs/core-concepts/testing) |
|
||||
| `@opentui/react/runtime-plugin-support` | Bun only | Runtime-specific, Advanced | [Runtime module loading](/docs/extend/runtime-plugins) |
|
||||
| `@opentui/react/runtime-plugin-support/configure` | Bun only | Runtime-specific, Advanced | [Runtime module loading](/docs/extend/runtime-plugins) |
|
||||
| `@opentui/react/jsx-runtime` | Compiler selected | Supported | [React bindings](/docs/bindings/react) |
|
||||
| `@opentui/react/jsx-dev-runtime` | Compiler selected | Supported | [React bindings](/docs/bindings/react) |
|
||||
| `@opentui/solid` | Bun and Node.js | Supported | [Solid bindings](/docs/bindings/solid) |
|
||||
| `@opentui/solid/preload` | Bun only | Runtime-specific | [Solid bindings](/docs/bindings/solid) |
|
||||
| `@opentui/solid/bun-plugin` | Bun only | Runtime-specific, Advanced | [Solid bindings](/docs/bindings/solid) |
|
||||
| `@opentui/solid/runtime-plugin-support` | Bun only | Runtime-specific, Advanced | [Runtime module loading](/docs/extend/runtime-plugins) |
|
||||
| `@opentui/solid/runtime-plugin-support/configure` | Bun only | Runtime-specific, Advanced | [Runtime module loading](/docs/extend/runtime-plugins) |
|
||||
| `@opentui/solid/components` | Bun and Node.js | Advanced | [Solid bindings](/docs/bindings/solid) |
|
||||
| `@opentui/solid/jsx-runtime` | Compiler selected | Supported | [Solid bindings](/docs/bindings/solid) |
|
||||
| `@opentui/solid/jsx-dev-runtime` | Compiler selected | Supported | [Solid bindings](/docs/bindings/solid) |
|
||||
| `@opentui/keymap` | JavaScript runtimes | Supported | [Core keymap API](/docs/keymap/core) |
|
||||
| `@opentui/keymap/extras` | JavaScript runtimes | Supported | [Core keymap API](/docs/keymap/core) |
|
||||
| `@opentui/keymap/extras/graph` | JavaScript runtimes | Advanced | [Core keymap API](/docs/keymap/core) |
|
||||
| `@opentui/keymap/addons` | JavaScript runtimes | Supported | [Built-in keymap addons](/docs/keymap/addons) |
|
||||
| `@opentui/keymap/addons/opentui` | Bun and Node.js | Supported | [Built-in keymap addons](/docs/keymap/addons) |
|
||||
| `@opentui/keymap/testing` | JavaScript test runtimes | Supported | [Core keymap API](/docs/keymap/core) |
|
||||
| `@opentui/keymap/html` | Browser DOM | Runtime-specific | [Keymap hosts](/docs/keymap/hosts) |
|
||||
| `@opentui/keymap/opentui` | Bun and Node.js | Runtime-specific | [Keymap hosts](/docs/keymap/hosts) |
|
||||
| `@opentui/keymap/react` | OpenTUI React | Runtime-specific | [React keymap integration](/docs/keymap/react) |
|
||||
| `@opentui/keymap/solid` | OpenTUI Solid | Runtime-specific | [Solid keymap integration](/docs/keymap/solid) |
|
||||
| `@opentui/keymap/runtime-modules` | Bun runtime loading | Runtime-specific, Advanced | [Runtime module loading](/docs/extend/runtime-plugins) |
|
||||
| `@opentui/qrcode` | Bun and Node.js | Supported | [QR encoder](/docs/reference/qr-encoder) |
|
||||
| `@opentui/qrcode/react` | OpenTUI React | Runtime-specific | [QR code component](/docs/components/qr-code) |
|
||||
| `@opentui/qrcode/solid` | OpenTUI Solid | Runtime-specific | [QR code component](/docs/components/qr-code) |
|
||||
| `@opentui/ssh` | Bun 1.3.0 or Node.js 26.4.0 or later | Runtime-specific | [SSH](/docs/reference/ssh) |
|
||||
| `@opentui/three` | Bun only | Runtime-specific, Advanced | [Three.js WebGPU](/docs/reference/three) |
|
||||
| `@opentui/three/runtime-modules` | Bun only | Runtime-specific, Advanced | [Runtime module loading](/docs/extend/runtime-plugins) |
|
||||
|
||||
See [Package entry points](/docs/reference/package-entrypoints) for each entry point's role and import constraints.
|
||||
|
||||
@@ -379,7 +379,7 @@ The package root works in Bun and Node.js. Each framework path re-exports the fu
|
||||
|
||||
## `@opentui/ssh`
|
||||
|
||||
The package supports Bun 1.3.0 and Node.js 26.4.0. It has one public entry point.
|
||||
The package supports Bun 1.3.0 and Node.js 26.4.0 or later. It has one public entry point.
|
||||
|
||||
| Symbols | Class | Canonical documentation |
|
||||
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -------------------------- |
|
||||
|
||||
@@ -95,9 +95,9 @@ The framework paths include the encoder and renderable exports. They are not reg
|
||||
|
||||
## `@opentui/ssh`
|
||||
|
||||
| Entry point | Runtime | Purpose | Workflow |
|
||||
| -------------- | --------------------------- | ------------------------------------------------------------------------------------------- | -------------------------- |
|
||||
| `@opentui/ssh` | Bun 1.3.0 or Node.js 26.4.0 | SSH server builder, authentication, middleware, sessions, logging, errors, and public types | [SSH](/docs/reference/ssh) |
|
||||
| Entry point | Runtime | Purpose | Workflow |
|
||||
| -------------- | ------------------------------------ | ------------------------------------------------------------------------------------------- | -------------------------- |
|
||||
| `@opentui/ssh` | Bun 1.3.0 or Node.js 26.4.0 or later | SSH server builder, authentication, middleware, sessions, logging, errors, and public types | [SSH](/docs/reference/ssh) |
|
||||
|
||||
The package has no framework subpaths. Pass the session renderer to the React or Solid root API.
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ SSH is an access transport. It is not an application packaging format. See
|
||||
bun add @opentui/ssh @opentui/core
|
||||
```
|
||||
|
||||
`@opentui/core` is a peer dependency. The SSH package declares Bun >=1.3.0 and Node.js 26.4.0. The SSH Node CI lane
|
||||
`@opentui/core` is a peer dependency. The SSH package declares Bun >=1.3.0 and Node.js >=26.4.0. The SSH Node CI lane
|
||||
runs on Linux x64. Its packed Node consumer test uses a Core stub, so that test does not start the native renderer. See
|
||||
[Runtime and platform support](/docs/getting-started/runtime-support) before you run the native renderer with Node.js.
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ apk add --no-cache libstdc++ libgcc
|
||||
|
||||
## Node.js SEA
|
||||
|
||||
Use exactly Node.js 26.4.0 for this procedure. The tested SEA is ESM and enables experimental FFI. It does not support
|
||||
Use Node.js 26.4.0 or later for this procedure. The tested SEA is ESM and enables experimental FFI. It does not support
|
||||
OpenTUI's Bun runtime-plugin system or `@opentui/three`.
|
||||
|
||||
Node stores SEA assets as bytes inside the executable. The OpenTUI native library and worker need filesystem paths.
|
||||
@@ -144,7 +144,7 @@ function run(command, args) {
|
||||
}
|
||||
```
|
||||
|
||||
Run this build file with Node.js 26.4.0. The example builds for the host platform and architecture. It uses Bun only as
|
||||
Run this build file with Node.js 26.4.0 or later. The example builds for the host platform and architecture. It uses Bun only as
|
||||
the ESM bundler. The matching optional native package must be installed.
|
||||
|
||||
The application uses normal OpenTUI imports:
|
||||
|
||||
@@ -20,7 +20,7 @@ must reach the target machine.
|
||||
| Bun source | You can install Bun and dependencies on the target. | Ship source, the lockfile, production dependencies, and the matching Core native package. |
|
||||
| Bun bundle | You want built JavaScript but can install Bun on the target. | Ship the bundle and every emitted asset or external dependency. The build needs the matching native package unless it remains external. |
|
||||
| Bun executable | You want one target-specific host executable. | Build once per operating system, architecture, and Linux libc. Deploy runtime-loaded plugins as sidecars. |
|
||||
| Node.js ESM | You need the accepted Node.js runtime path without SEA packaging. | Use Node.js 26.4.0, ESM, `--experimental-ffi`, installed runtime assets, and the matching native package. |
|
||||
| Node.js ESM | You need the accepted Node.js runtime path without SEA packaging. | Use Node.js 26.4.0 or later, ESM, `--experimental-ffi`, installed runtime assets, and the matching native package. |
|
||||
| Node.js SEA | You need one Node.js executable and can extract its assets at startup. | Embed the exact Node asset manifest, extract it, and set `OTUI_ASSET_ROOT` before Core executes. |
|
||||
| SSH | Users connect through an SSH client instead of a local terminal. | Package the host with one of the preceding forms, then configure listener security and remote-session policy. |
|
||||
|
||||
@@ -48,7 +48,7 @@ Use [Standalone executables](/docs/reference/standalone-executables#bun) for the
|
||||
|
||||
The accepted Node.js SEA workflow has these constraints:
|
||||
|
||||
- Use Node.js 26.4.0 and an ESM application bundle.
|
||||
- Use Node.js 26.4.0 or later and an ESM application bundle.
|
||||
- Do not use `@opentui/three` or runtime-plugin support. Those entry points are Bun-only.
|
||||
- Call `getNodeAssets()` at build time only.
|
||||
- Select the target platform, architecture, and Linux libc when you create the manifest.
|
||||
|
||||
@@ -22,7 +22,7 @@ Start with the visible symptom. Run the diagnostic in its row, then open the lin
|
||||
|
||||
| Symptom | Diagnostic and first action | Canonical guide |
|
||||
| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `OpenTUI native FFI is not available for this runtime yet` | Run `node --version`. It must print `v26.4.0`. Start the ESM app with `node --experimental-ffi app.mjs`. With `--permission`, also grant `--allow-ffi` and native-library read access. | [Node.js runtime](/docs/getting-started/runtime-support#runtime-versions) |
|
||||
| `OpenTUI native FFI is not available for this runtime yet` | Run `node --version`. It must print `v26.4.0` or later. Start the ESM app with `node --experimental-ffi app.mjs`. With `--permission`, also grant `--allow-ffi` and native-library read access. | [Node.js runtime](/docs/getting-started/runtime-support#runtime-versions) |
|
||||
| `ERR_REQUIRE_ASYNC_MODULE` | Find `require("@opentui/core")` or a CommonJS entry. Change the application to ESM and use `import`. | [Node.js runtime](/docs/getting-started/runtime-support#runtime-versions) |
|
||||
| A native package or library is missing | Run `bun -e 'console.log(process.platform, process.arch, process.env.OPENTUI_LIBC ? process.env.OPENTUI_LIBC : "glibc")'`. Replace `bun` with `node` for a Node.js host. Check for the matching `@opentui/core-*` optional package. An install that omits optional dependencies can defer the failure until native work. | [Native artifacts](/docs/getting-started/runtime-support#native-artifacts) |
|
||||
| Linux reports a loader error for `libopentui.so` | Compare the selected libc with the target system. Set `OPENTUI_LIBC=musl` before Core imports on musl. On Alpine, install `libstdc++` and `libgcc`. | [Select the Linux libc](/docs/getting-started/runtime-support#select-the-linux-libc) |
|
||||
|
||||
@@ -24,7 +24,7 @@ categories:
|
||||
|
||||
`@opentui/ssh` maps each accepted SSH shell to a `CliRenderer`. The renderer dimensions track the client's terminal.
|
||||
|
||||
The package requires Bun `>=1.3.0` or Node.js `26.4.0`.
|
||||
The package requires Bun `>=1.3.0` or Node.js `>=26.4.0`.
|
||||
|
||||
Open authentication accepts SSH `none` without credentials. Use it only for loopback development. Do not expose open
|
||||
authentication to a public or untrusted network.
|
||||
|
||||
+46
-3
@@ -1,7 +1,7 @@
|
||||
import { spawnSync } from "node:child_process"
|
||||
import { delimiter, dirname } from "node:path"
|
||||
|
||||
export const NODE26_VERSION = "v26.4.0"
|
||||
export const NODE26_MIN_VERSION = "v26.4.0"
|
||||
|
||||
export function requireNode26() {
|
||||
const nodeCommand = typeof process.versions?.bun === "string" ? "node" : process.execPath
|
||||
@@ -20,7 +20,7 @@ export function requireNode26() {
|
||||
}
|
||||
|
||||
const runtime = parseNodeRuntime(nodeCommand, result.stdout)
|
||||
if (runtime.version !== NODE26_VERSION) {
|
||||
if (!isSupportedNode26Version(runtime.version)) {
|
||||
throw new Error(nodeVersionError(`${runtime.execPath} reports ${runtime.version}`))
|
||||
}
|
||||
|
||||
@@ -29,6 +29,49 @@ export function requireNode26() {
|
||||
return runtime.execPath
|
||||
}
|
||||
|
||||
export function isSupportedNode26Version(version) {
|
||||
const parsed = parseNodeVersion(version)
|
||||
const minimum = parseNodeVersion(NODE26_MIN_VERSION)
|
||||
if (parsed === null || minimum === null) {
|
||||
return false
|
||||
}
|
||||
|
||||
return compareNodeVersion(parsed, minimum) >= 0
|
||||
}
|
||||
|
||||
export function parseNodeVersion(version) {
|
||||
if (typeof version !== "string") {
|
||||
return null
|
||||
}
|
||||
|
||||
const match = /^v?(\d+)\.(\d+)\.(\d+)/.exec(version)
|
||||
if (match === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
major: Number(match[1]),
|
||||
minor: Number(match[2]),
|
||||
patch: Number(match[3]),
|
||||
}
|
||||
}
|
||||
|
||||
function compareNodeVersion(left, right) {
|
||||
if (left.major !== right.major) {
|
||||
return left.major < right.major ? -1 : 1
|
||||
}
|
||||
|
||||
if (left.minor !== right.minor) {
|
||||
return left.minor < right.minor ? -1 : 1
|
||||
}
|
||||
|
||||
if (left.patch !== right.patch) {
|
||||
return left.patch < right.patch ? -1 : 1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
function parseNodeRuntime(nodeCommand, output) {
|
||||
try {
|
||||
const runtime = JSON.parse(output)
|
||||
@@ -43,5 +86,5 @@ function parseNodeRuntime(nodeCommand, output) {
|
||||
}
|
||||
|
||||
function nodeVersionError(actualVersion) {
|
||||
return `Node.js ${NODE26_VERSION} is required, but ${actualVersion}. Select the required Node.js version before running this command; OpenTUI will not install it automatically.`
|
||||
return `Node.js ${NODE26_MIN_VERSION} or later is required, but ${actualVersion}. Select a supported Node.js version before running this command; OpenTUI will not install it automatically.`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user