node script.mjs or js -e "..." need a JavaScript
engine. Mirage calls that engine a runtime, and node and js are
two names for the same command family. One runtime ships today:
What it is for
node/js runs small, self-contained scripts and pipe transforms:
compute, JSON munging, regex text processing, code generation. It is a
bare modern engine (ES2023 syntax, ES modules, JSON, Promise,
top-level await), not Node: there is no require, no npm, no
process, no fs, no fetch. Anything that needs those belongs in a
sandboxed deployment, not the workspace runtime.
python3:
-e <code>evaluates the argument.- A file (
node script.js) is read through the workspace before the run, so a mounted script executes. - stdin with no
-eor file runs the piped text as the program.
scriptArgs holds the arguments after the code or script,
std.in.readAsString() reads piped stdin, and std.open/os.readdir
reach workspace mounts (see Isolation). These match the
Python quickjs runtime, so a script behaves the same in both languages.
Modules
A.mjs file runs as an ES module automatically (top-level
import/export/await); .js and -e run as a classic script. Pass
-m/--module to force module mode for inline code:
Isolation
The engine runs under WebAssembly capability isolation: it sees only what the run passes it. Host files and the network are invisible. Workspace mounts are visible with no setup:std.open('/data/f.txt', 'r')
reads the mount and os.readdir('/data') lists it, bridged through the
workspace dispatch so the code sees exactly what cat sees, with the same
cache and write modes. Writes are visible to every command once the file is
closed, and a read-only mount (or a session narrowed to read) fails the
open, so std.open returns null instead of writing. The engine runs on
quickjs-emscripten’s asyncify build, which lets std.open suspend the run
while a mount read or write awaits the dispatch, matching the Python
quickjs runtime’s live file I/O.
This is capability isolation, not a resource sandbox: the sandboxed code
cannot reach your files or the network, but CPU and memory are bounded only
by soft engine caps and command_safeguards timeouts. For untrusted code or
hard resource limits, run behind a sandboxed deployment.
Setup
The runtime needs the optionalquickjs-emscripten peer dependency (it
bundles its own wasm, so there is nothing else to download):
Selecting in YAML
Server workspace config files take a top-levelruntimes list; the
JavaScript runtime is just another entry:
Resource limits
node/js is a command like any other: the same command_safeguards
that guard cat or python3 guard it, enforced at the same central
point. A run that exceeds timeout_seconds answers with exit 124, and
max_bytes/max_lines cap its output.
One caveat: the guard bounds how long a run may answer, not the engine
itself. Give untrusted code a finite workload, or run it behind a
sandboxed deployment.