Headless
Checked against f15b998 on 2026-11-10. The files it covers are unchanged since.
Two hosts have no window. They run a page’s event loop on virtual time, render frames when asked and tap at coordinates, and they’re how niso’s own tests drive pages.
niso-run
Section titled “niso-run”niso-run (crates/niso-quickjs/src/bin/niso-run.rs) runs scripts or an HTML
page on QuickJS:
cargo run --release -p niso-quickjs --bin niso-run -- --dump --tap 60,140 examples/dist/counter.jstarget/release/niso-run --page index.html --root . --boxesThe options that matter most:
--page FILE [--root DIR] [--url URL]loads a page as a browser does; with--root,http://localhost/serves the files under DIR.--serve URL=FILEanswers a fetch with a file’s bytes, so a page that reads the network gets the same answer every run.--tap X,Yrenders a frame and taps there;--dumpprints the document’s HTML;--boxesprints every element’s border box as JSON.--render FILErecords every frame’s render stream;--timereports the time to first frame, the time per tap frame and peak memory.--missinglists every DOM member and global the page looked up that niso doesn’t have, which is the quickest way to see why a web app breaks.--storage DIRkeeps localStorage and IndexedDB between runs.--holdkeeps the process (and its workers) alive after--timeuntil stdin closes, so a heap tool can inspect it.
It exits 1 on any uncaught exception. The full list is in the CLI reference.
niso-node
Section titled “niso-node”niso-node (bindings/js/napi/niso-node.js) is the same thing on Node, Deno
or Bun through the Node-API binding (crates/niso-napi), so a page runs on V8
or JavaScriptCore instead of QuickJS. It takes niso-run’s options, plus
--live, which runs the page in real time until it has nothing left to do.
cargo build --release -p niso-napinode --experimental-vm-modules bindings/js/napi/niso-node.js --dump --tap 60,140 examples/dist/counter.jsThe binding’s details, and why it’s built on napi-sys, are in Node-API.
Running niso inside Node as a library for server-side rendering is possible
through bindings/js/napi/niso.js, but no guide covers it yet.