node
experimentalTyped JavaScript and TypeScript functions, Node modules and async callbacks.
use plugin node Plugin snippets can be edited in the Playground, but native capabilities are executed locally with the Zolo CLI.
From import to result
- 01Import only what you use
- 02Copy the smallest example
- 03Run it with the Zolo CLI
Functions¶
Import these provider exports to select the native language of an extern binding:
| Provider | Description |
|---|---|
javascript |
JavaScript bodies, modules and expression captures |
typescript |
TypeScript bodies, modules and expression captures |
use plugin node::{javascript as js, typescript as ts}
extern js fn add(a: int, b: int) -> int {
return a + b;
}
extern ts async fn later(value: int) -> int {
await new Promise(resolve => setTimeout(resolve, 1));
return value + 1n;
}
print(add(20, 22))
print(await later(41))Signatures use Zolo types. Bodies use the selected native language. Both providers share an embedded Node runtime, including built-in modules. Import either provider explicitly and use ordinary aliases, function calls, groups and expression blocks. An expression can capture values from its Zolo scope.
Zolo int and i64 become native bigint, preserving all signed 64-bit values.
Use 1n with these values. Floating-point and narrower integer signatures use
number. Bytes become Buffer/Uint8Array; nil becomes null; arrays preserve
empty shape and null entries. Typed structs become copied records. Returned
functions and class instances support normal call/property syntax and retain
their native state.
Modules and async¶
extern ts from "./tools.ts" use {twice, Counter as Count}
extern ts fn digest(text: str) -> str {
import {createHash} from "node:crypto";
return createHash("sha256").update(text).digest("hex");
}
extern ts async fn transform(value: int, callback: fn(int) -> Future<int>) -> int {
return await callback(value);
}Source imports expose statically known exported functions and classes.
TypeScript annotations and JavaScript JSDoc supply their signatures. CommonJS
and ECMAScript modules use their native loading semantics. Relative paths
follow the importing Zolo source file. A native extern ts mod can expose
several functions and classes through a Zolo namespace.
Async functions return Zolo Futures. Callbacks returning Futures become native
Promises and execute on the Zolo runtime thread. Use a Future-returning
callback when the callback itself awaits another Node function. A synchronous
callback reentering async work from a Promise continuation cannot wait for a
nested V8 microtask; the provider reports that unsupported operation explicitly.
Errors propagate through try/catch. Cancellation releases owned cancellable
resources but cannot forcibly interrupt synchronous native work.
Runtime and editor¶
The experimental adapter uses a version-matched Node 26.10.0 Windows x64 shared
runtime and native shim (module ABI 147). An arbitrary installed node.exe
does not supply the embedding library. The build stages node-runtime/ beside
the plugin with libnode.dll and upstream license notices. Deploy this
directory too, or configure ZOLO_NODE_HOME/ZOLO_NODE_LIBRARY before first use.
The selected runtime remains fixed for the process. Other hosts have not been
validated. Windows consumers also need the Microsoft Visual C++ x64 v14
runtime (MSVCP140 and VCRUNTIME140, including VCRUNTIME140_1); the Node library
and shim use that shared runtime. A source-free executable still needs these
runtime dependencies.
The TypeScript 6.0.3 compiler, standard declarations and Node typings are embedded in the plugin. Diagnostics, completion, hover, signature help and semantic tokens inspect the current source without executing authored imports, getters or decorators. Unsupported dynamic signatures remain explicit rather than appearing as invented precise types.
VM, native and LLVM use the common provider protocol. A wasm host without Node rejects the binding. Plugin embedding/static linking does not install arbitrary npm dependencies or remove the shared Node runtime requirement.
Typed string-keyed map inputs become native Node Map values. Copied map results
can contain imported class instances, and returned callables preserve native
parameter types. Promise-valued fields/getters and nullable or union Promise
return signatures currently report unsupported metadata; use an async function
or method with a concrete Promise return type.
Static fields and properties also report unsupported metadata; use a static
method or an exported function for associated access.
Package dependencies¶
use plugin node::{javascript as js, typescript as ts}
extern ts deps {
"date-fns" = "4.1.0"
}JavaScript and TypeScript share a provider environment. Declare packages at
file scope or in [foreign.node.dependencies] with [packages] schema = 2 in
zolo.toml. zolo install and zolo add node:date-fns@4.1.0 use an isolated npm
graph, including transitive and peer dependencies. Short versions are exact;
{ requirement = "^4.1.0" } explicitly selects npm range semantics.
Package exports, bare imports/require and TypeScript declarations use the prepared tree. Runtime artifacts include its verified closure for deployment. Native addons must match the embedded Node ABI. Lifecycle scripts are disabled in this adapter version; packages requiring those steps need a future explicit build workflow. Opening a file reads prepared packages without installing or executing them. See foreign dependencies.
From the repository root, prepare the pinned build inputs and install only Node:
powershell -NoProfile -File scripts/acquire-node-runtime.ps1
node scripts/acquire-node-tooling.mjs
cargo xtask install-plugins --only node