Skip to content
GitHub Get Started
Node.js Runtime

Resident Runner

Each exec() / run() call starts a fresh guest process, which is the right default for isolation between runs. When you run many small snippets against the same runtime (an evaluation loop, a REPL, a test harness), that per-run process startup dominates. A resident runner keeps one guest process alive and evaluates each snippet in it, so repeated calls are fast.

createResidentRunner() returns a handle with exec() and dispose(). Dispose it when you are done so the live process is torn down.

import { NodeRuntime } from "secure-exec";
const rt = await NodeRuntime.create();
const runner = await rt.createResidentRunner();
try {
const a = await runner.exec("console.log(1 + 1)");
const b = await runner.exec("console.log(2 + 2)");
console.log(a.stdout.trim(), b.stdout.trim()); // "2" "4"
} finally {
await runner.dispose();
await rt.dispose();
}

Each runner.exec(code, options?) resolves with the same { stdout, stderr, exitCode } shape as rt.exec(). Pass options.timeout to bound a single evaluation.

A warm resident evaluation runs in roughly a millisecond, versus the hundreds of milliseconds a cold run pays to stand up a guest process. Reach for a resident runner when the same runtime runs many small snippets and the snippets are trusted to share a process. See the measured difference in Benchmarks.