| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Each subdirectory is one engine variant of the NativeScript Windows app runtime, published as @nativescript/windows-<engine>. A variant is the same framework as @nativescript/windows (the WinUI 3 app template, dotnet-bridge, and tools) — only the runtime DLL differs. All of runtime/src/napi_engine/* is engine-neutral and reused verbatim; a package supplies the engine + its Node-API provider + a thin adapter that exposes the runtime DLL's C ABI over that engine.
@nativescript/windows and @nativescript/windows-<engine> are drop-in replacements: an app swaps the dependency and rebuilds, and it runs unchanged on the other engine. This works because every variant ships the same framework and a nativescript.dll that exposes the same C ABI the WinUI 3 host P/Invokes (runtime_init / runtime_runscript / runtime_pump_timers / …). The package metadata is uniform too — same files, and a nativescript: { runtime, engine } block — so tooling resolves any of them the same way.
Producing a variant is a build flag, not a separate template (see Building below):
template/build.ps1 # @nativescript/windows (classic V8, default)
template/build.ps1 -Engine quickjs # @nativescript/windows-quickjsSame convention as @nativescript/android / @nativescript/ios:
| Package | npm | Engine binary (Windows) | napi in binary? |
|---|---|---|---|
| windows-quickjs | @nativescript/windows-quickjs | compiled from source (quickjs-ng + napi-android shim) | shim (compiled) |
| windows-hermes | @nativescript/windows-hermes | prebuilt hermes.dll (Microsoft.JavaScript.Hermes NuGet) | ✅ yes (napi+jsr) |
| windows-v8 | @nativescript/windows-v8 | in-tree: rusty_v8 (V8 14.7, prebuilt static lib + headers) | napi-android v8 shim, ported to V8 14.7 |
| windows-jsc | @nativescript/windows-jsc | Playwright's webkit-win64 JavaScriptCore.dll (current; buildbot is dead) | napi-android JSC shim over the public C API (+ 2 Win fixes) |
All four supported engines run the full WinRT runtime with no Node. (PrimJS was dropped — its concurrent GC is hard-coded to POSIX mmap/pthreads and it has no Windows build.)
Prebuilt-availability notes (checked Jul 2026): V8 engine is already in-tree (rusty_v8). JSC: the WebKit WinCairo buildbot is dead (last Windows build Sept 2024) and the microsoft.javascript.jsc / javascriptcore NuGet ids are 1-byte placeholders — the current source is Playwright's webkit-win64 build (rebuilt continuously; ships JavaScriptCore.dll + ICU). microsoft.chakracore (1.11.x) is a real Windows engine but JSRT, not napi; openkraken/jsc is Android/macOS only.
packages/windows-<engine>/ Cargo.toml # excluded from the workspace (C build / prebuilt link) build.rs # compile engine + shim, or link the prebuilt + copy DLLs src/lib.rs # engine bindings + `abi` module (the nativescript.dll C ABI) src/abi.rs # engine → runtime-DLL adapter (host_dll feature); see below src/main.rs # standalone host: bring up napi_env → napi_engine → run app vendor/ # committed engine binaries (android's model: in-repo, no LFS) package.json # @nativescript/windows-<engine> (same contract as classic) framework/ # generated by the engine build — not committed (see .gitignore) README.md
Shared host code (native crash reporter, demo harness) is in packages/common (ns-windows-common).
The WinUI 3 host loads framework/libs/<arch>/nativescript.dll and P/Invokes its C ABI (runtime_init, runtime_deinit, runtime_runscript, runtime_pump_timers, runtime_notify_app_event, runtime_set_local_folder, runtime_get_last_js_error / runtime_free_js_error, runtime_install_ctrlc_handler, runtime_has_devtools). The classic runtime implements this in the nativescript crate over rusty_v8. Each engine variant implements the same ABI in src/abi.rs, compiled into the package's cdylib under the host_dll feature.
The engine-neutral work — WinRT init, installing the globals + Windows namespace, and one turn of the event loop — is shared in runtime::napi_engine::host_abi (initialize_runtime / pump_once). An adapter only wires the three engine-specific pieces on top: create the napi_env (the engine's shim), evaluate a script, and drain microtasks. windows-quickjs/src/abi.rs is the reference implementation; the other engines follow the identical shape with their own shim.
Build status: all four per-engine nativescript.dll cdylibs have been built and validated here (cargo build --features host_dll for each package). Each was loaded by a foreign .NET host — a C# program that P/Invokes the runtime C ABI exactly like the WinUI 3 app — where runtime_init succeeds, runtime_runscript runs JS, and a real WinRT round-trip (Windows.Data.Json → {"a":7}) works. This required one Windows-port fix: the napi engine DLLs resolve their napi_* provider from the loaded module (the .exe OR the cdylib) rather than always the process .exe — see packages/vendor/napi-sys (a [patch.crates-io] in each engine package). The classic runtime uses rusty_v8 (no napi-sys) and never hit this. Building a cdylib still needs the engine toolchain + vendored engine binaries (each package is excluded from the workspace), so a plain workspace cargo build does not compile them.
nativescript-windows path/to/app.js # e.g. packages/test/test-app.jspackages/test/interop-check.js exercises the shared NSWinRT.interop surface (typed-value/ reference boxing, Pointer/OutParam, buffer + DateTime helpers) and is expected to pass on all four engines. With a script argument the host runs it and then drives the standalone event loop (runtime::napi_engine::event_loop) until the app goes idle: Windows message pump (STA WinRT async completions, delegate invokes), setTimeout/setInterval timers (napi_engine::timers, install-if-missing), and the engine's microtask drain. The prelude (packages/common/src/prelude.rs) provides queueMicrotask and NSWinRT.toPromise(op); toPromise ref-counts the loop via the __nsLoopRetain/__nsLoopRelease natives, so awaited WinRT operations keep the process alive exactly until they settle. Without a script argument the host runs its staged demo (including an async event loop stage) and exits.
Per-engine loop notes: Hermes is created with jsr_config_set_explicit_microtasks (bare hosts have no setImmediate for its RN-style promise scheduling); V8/JSC ship inspector-only inert console objects that the hosts delete so the runtime console installs; microtask drain hooks are qjs_execute_pending_jobs / js_execute_pending_jobs / jsr_drain_microtasks.
The framework is built by template/build.ps1; -Engine selects the runtime DLL. It's the same template for every engine — only framework/libs/ differs.
# Classic V8 — stages into template/framework (x64 + arm64, release + devtools).
template/build.ps1
# An engine variant — copies the shared scaffolding from template/framework, builds the engine
# cdylib as framework/libs/x64/nativescript.dll, and stages it into packages/windows-<engine>/framework.
# (Build classic once first so the shared scaffolding exists to copy. Variants are x64, no devtools.)
template/build.ps1 -Engine quickjs
template/build.ps1 -Engine hermes
template/build.ps1 -Engine jsc # also needs a real JavaScriptCore.lib in windows-jsc/vendorEach variant's package.json build script is just that invocation, so npm run build inside a package produces its framework. Prebuilt engine binaries are committed in each package's vendor/ (provenance + refresh in each vendor/README.md), the same way napi-android commits its libs/.
@nativescript/windows + @nativescript/windows-<engine> — app runtimes: build the framework for the engine (above), then npm publish the package (each is os:["win32"], cpu:["x64"]; the classic package also ships arm64 + devtools). The CLI picks one, like android's jsEngine — and because the packages are interchangeable, switching is a dependency swap.
@nativescript/windows-napi — the Node/Bun/Deno .node (../windows-napi): napi-rs flow, implemented in .github/workflows/windows-napi.yml: a build matrix per triple (x86_64-pc-windows-msvc, aarch64-pc-windows-msvc) runs napi build --platform --release --target <triple> → windows.<triple>.node artifacts (the x64 job also runs the 366-check test suite, non-blocking on server SKUs); pushing a windows-napi-v* tag triggers the publish job: napi artifacts distributes the .node files into the committed windows-napi/npm/<triple>/ sub-packages, napi prepublish (the prepublishOnly script) publishes those, then the root package publishes with them as optionalDependencies. Needs the NPM_TOKEN repo secret. index.js/index.d.ts/package-lock.json are generated but committed (the publish job doesn't build). If arm64 proves unbuildable (rusty_v8/libffi cross), drop the triple from the workflow matrix, napi.triples, optionalDependencies, and npm/win32-arm64-msvc/.
| Back | FazBrowse Home | New Git URL |