Node.js Runtime
The Node.js runtime (@xriptjs/runtime-node) executes user scripts inside a sandboxed Node.js vm context. It provides createRuntimeFromFile for loading manifests directly from disk. Use this runtime when your application runs exclusively on Node.js and you want file-based workflows.
For applications that need to run in browsers, Deno, Bun, or other environments, use the JS/WASM Runtime (@xriptjs/runtime) instead. For Rust host applications, see the Rust Runtime. For .NET applications, see the C# Runtime. For a comparison of all runtimes, see Choosing a Runtime.
Installation
Section titled “Installation”npm install @xriptjs/runtime-nodeCreating a Runtime
Section titled “Creating a Runtime”From a Manifest Object
Section titled “From a Manifest Object”import { createRuntime } from "@xriptjs/runtime-node";
const runtime = createRuntime(manifest, { hostBindings: { greet: (name) => `Hello, ${name}!` },});createRuntime performs basic structural validation on the manifest (required fields, correct types) and returns a runtime immediately.
From a Manifest File
Section titled “From a Manifest File”import { createRuntimeFromFile } from "@xriptjs/runtime-node";
const runtime = await createRuntimeFromFile("./manifest.json", { hostBindings: { greet: (name) => `Hello, ${name}!` },});createRuntimeFromFile reads the manifest from disk, performs structural validation, and creates a runtime. For full JSON Schema validation, use @xriptjs/validate before creating the runtime.
Options
Section titled “Options”createRuntime and createRuntimeFromFile accept the same options:
| Option | Type | Default | Description |
|---|---|---|---|
hostBindings | HostBindings | (required) | Map of binding names to host functions |
capabilities | string[] | [] | List of capabilities granted to this script |
console | { log, warn, error } | no-op functions | Console output routing |
Executing Scripts
Section titled “Executing Scripts”Synchronous
Section titled “Synchronous”const result = runtime.execute("2 + 2");// { value: 4, duration_ms: 0.5 }Asynchronous
Section titled “Asynchronous”const result = await runtime.executeAsync("return await data.get('score');");// { value: "42", duration_ms: 1.2 }executeAsync wraps code in an async function. Use return and await as needed.
Cleanup
Section titled “Cleanup”Call dispose() when you are done with a runtime:
runtime.dispose();The Node.js runtime does not require explicit cleanup, but dispose() is provided for API parity with the universal runtime. Code written against one runtime works identically on the other.
Error Types
Section titled “Error Types”The Node.js runtime exports the same error classes as the universal runtime:
| Error | When | Catchable in script? |
|---|---|---|
ManifestValidationError | Manifest fails structural or schema validation | N/A (thrown at load time) |
BindingError | Host function throws or is missing | Yes |
CapabilityDeniedError | Calling a gated binding without the capability | Yes |
ExecutionLimitError | Script exceeds timeout or resource limits | No |
import { BindingError, CapabilityDeniedError, ExecutionLimitError,} from "@xriptjs/runtime-node";Sandbox Details
Section titled “Sandbox Details”The Node.js runtime creates a vm.Context with a restricted global environment:
- Code generation disabled:
vm.createContextis configured withcodeGeneration: { strings: false, wasm: false }. This blockseval()andnew Function()at the V8 level. - Standard globals available:
Math,JSON,Date,Number,String,Boolean,Array,Object,Map,Set,Promise,RegExp,Symbol,Proxy,Reflect, typed arrays, and standard error constructors - Blocked:
process,require,import,fetch,setTimeout,setInterval,Buffer,__dirname,__filename - Frozen namespaces: Namespace objects are frozen with
Object.freeze - Execution limits: Timeout enforced via
vm.Script.runInContexttimeout option
Loading Mods
Section titled “Loading Mods”runtime.loadMod(modManifest, options?) validates a mod manifest against the app manifest, sanitizes any fragment HTML, and returns a ModInstance. If the mod manifest declares an entry script, that script runs during loading.
const mod = runtime.loadMod(modManifest, { sources: fragmentSources });console.log(mod.name, mod.version);console.log(mod.fragments.length);fragmentSources is an object mapping fragment IDs to their raw HTML strings. The runtime sanitizes each source before attaching it to the mod.
Fragment Lifecycle Hooks
Section titled “Fragment Lifecycle Hooks”runtime.fireFragmentHook(fragmentId, lifecycle, bindings?) fires a lifecycle hook registered by the active mod script and returns any command buffer operations the script issued. Supported lifecycles: mount, unmount, update, suspend, resume.
const ops = runtime.fireFragmentHook("health-bar", "update", { health: 75 });// ops is an array of command arrays: [["setText", ".hp", "75"], ...]Each entry in ops is a command array whose first element is the command name followed by its arguments. The host applies these operations to the rendered fragment.
Fragment Processing
Section titled “Fragment Processing”runtime.processFragment(fragmentId, source, bindings) evaluates data-bind and data-if attributes in the fragment HTML against the provided binding data and returns the resolved output.
const { html, visibility } = runtime.processFragment("health-bar", source, { health: 75, maxHealth: 100,});html is the processed HTML string with data-bind values substituted. visibility is a map of element selectors to boolean values derived from data-if expressions.