Running Code
Run files, evaluate code, preload modules, and understand exit codes.
This page covers the everyday ways to run a program with nstd, what
require() and import() can load, how the filesystem behaves, and what
happens when a program exits or throws.
#Run a script
Pass the file you want to run. Anything after it is passed to your program as arguments:
nstd script.js one twonstd run script.js does exactly the same thing, if you prefer to spell it
out.
Just like Node, nstd decides whether a file is CommonJS or an ES module from
its extension and the nearest package.json:
.mjsfiles run as ES modules..cjsfiles run as CommonJS..jsfiles run as CommonJS, unlesspackage.jsonhas"type": "module".
Inside your program, process.argv looks the same as under Node: the path to
the nstd binary, the full path to your script, then one and two.
#Evaluate code directly
Use -e (or --eval) to run a snippet of code instead of a file:
nstd -e 'console.log(require("os").hostname())'Use -p (or --print) to also print the result:
nstd -p '1 + 1' # 2As with node -e, there's no script path in process.argv here, so
process.argv[1] is the first argument after the code.
#Load a module first
Use -r (or --require) to load a CommonJS module before your program
starts. Repeat it to load several, in order:
nstd -r ./setup.cjs script.js
nstd -r ./a.cjs -r ./b.cjs script.jsA preloaded module runs in the same environment as your program, so if it patches a global or configures a library, your program sees the change. If it throws an error that nothing catches, your program never starts.
You can also pass --require through the NODE_OPTIONS environment
variable:
NODE_OPTIONS='--require ./setup.cjs' nstd script.jsThis matters for child processes. A child started with
child_process.fork(), or by running process.execPath, doesn't inherit the
parent's command-line options, only its environment. NODE_OPTIONS is the one
way to make a preload reach it. See CLI Options for
everything NODE_OPTIONS can hold.
#Check what a build supports
--print-realm starts nstd's JavaScript environment and reports what's in it,
without running any program:
nstd --print-realmnstd 0.0.1 (quickjs-ng ..., zig ...)
node v26.10.0 on linux/x64
67 builtin(s) registered, 0 unavailable
+ assert
+ buffer
+ fs
...Each builtin module that loaded is marked with +. Any that failed are marked
with -, followed by the reason. It's the quickest way to check whether a
build has what your program needs.
#Loading modules with require() and import()
require() can load:
- the
node:builtins compiled into the binary, - your own files on disk, and
- packages in
node_modules, resolved the same way Node does it, including"exports"and"imports"inpackage.json.
import() and .mjs files work too. That includes relative paths, packages,
node: builtins, importing CommonJS and JSON files, import attributes,
circular imports and top-level await. You can also:
require()an ES module,- call
import()from a CommonJS file, with the path resolved relative to that file, and - use named imports from a CommonJS file, such as
import { readFile } from "./some.cjs".
See Node.js Compatibility for what module loading doesn't cover yet.
#The filesystem
nstd uses the real filesystem of the machine it runs on. There's no sandbox
and no virtual root. Relative paths resolve against the current working
directory, and fs.watch() and fs.watchFile() both work.
Warning
Treat a script run with nstd exactly like one run with node: it can
read, write and delete anything the current user can.
#Exit codes and uncaught errors
When your program finishes without calling process.exit(), it exits with
process.exitCode. That defaults to 0, and you can set it yourself, just as
in Node.
An uncaught exception stops the program: the error is printed and the exit
code is 1. A process.on("uncaughtException", ...) listener (or
process.setUncaughtExceptionCaptureCallback()) can handle it and keep the
program running.
An unhandled promise rejection works the same way. A
process.on("unhandledRejection", ...) listener sees it first, and if nothing
handles it there, it stops the program like an uncaught exception.
These are the exit codes you can expect, all matching node:
| Exit code | When |
|---|---|
0 | The program finished, or --help, --version or --print-realm ran. |
1 | An uncaught exception or unhandled rejection, or process.exit(1). |
9 | An option on the command line or in NODE_OPTIONS was rejected. |
70 | nstd itself failed to start. This is a bug in nstd, not in your program. |
If the script file doesn't exist, nstd prints an error and exits with 1
before running anything.