CLI Options
A reference for nstd commands, runtime options, and NODE_OPTIONS.
This page lists everything the nstd command accepts: the commands, the
options you can put in front of a script, and what NODE_OPTIONS can hold.
#Commands
nstd script.js [args...] # run a file
nstd run script.js [args...] # the same, spelled out
nstd -e 'code' # evaluate a string
nstd -p 'code' # evaluate a string and print the result
nstd --print-realm # list the builtin modules this build provides
nstd -v # print the version
nstd -h # print usage| Command | What it does |
|---|---|
<file> [args...] | Run <file> as the program. |
run <file> [args...] | The same, spelled out. |
-e, --eval <code> | Run <code> as CommonJS. |
-p, --print <code> | Run <code> and print its result. |
--print-realm | Start up and report which builtin modules are available. |
-v, --version | Print the version and exit. |
-h, --help | Print usage and exit. |
#Options
Options go before the file (or before -e, -p or --print-realm).
Inside your program they appear in process.execArgv, exactly as typed, the
same as under node.
| Option | What it does |
|---|---|
-r, --require <file> | Load a CommonJS module before the program starts. Repeatable. |
-C, --conditions <name> | Add a custom condition for "exports"/"imports". Repeatable. |
--preserve-symlinks | Resolve dependencies to the symlink path instead of its target. |
--preserve-symlinks-main | The same, for the entry file. |
--unhandled-rejections <mode> | Choose what happens to unhandled rejections. |
--stack-trace-limit=<n> | How many stack frames an Error keeps (default 10). |
--dns-result-order <order> | The default address order for dns.lookup(). |
--title <name> | Set process.title (and, on Linux, the name ps shows). |
--no-warnings | Hide all process warnings. |
--disable-warning <code|name> | Hide one warning by its code or name. Repeatable. |
--trace-warnings | Print a stack trace with every warning. |
--trace-deprecation | Print a stack trace with deprecation warnings only. |
--throw-deprecation | Turn deprecation warnings into thrown errors. |
--pending-deprecation | Show deprecation warnings that are off by default. |
--no-deprecation | Hide all deprecation warnings. |
--redirect-warnings <file> | Append warnings to <file> instead of stderr. |
--experimental-eventsource | Add globalThis.EventSource. |
--no-experimental-websocket | Remove globalThis.WebSocket and globalThis.CloseEvent. |
--experimental-stream-iter | Enable node:stream/iter and node:zlib/iter. |
--experimental-bench | Enable node:bench and node:bench/reporters. |
--experimental-require-module | Allow require() of ES modules. On by default. |
--no-experimental-require-module | Disallow require() of ES modules. |
--experimental-vfs | Allow require("node:vfs"). On by default. |
--expose-gc | Add globalThis.gc() to trigger garbage collection. |
--expose-internals | Allow require() of Node's internal/* modules. |
The sections below explain the options that need more than one line.
#Running code
#-p, --print
-p works like -e, but also prints what the code evaluates to. It behaves
exactly like node -p:
nstd -p '1 + 1' # 2
nstd -p '"hi"' # hi (strings print without quotes)
nstd -p 'new Map([["a", 1]])' # Map(1) { 'a' => 1 }
nstd -p 'let x = 5' # undefined (a declaration has no value)The result is printed the way console.log would print it. It's printed once
the program has otherwise finished, so anything the code started, such as
a timer, still runs first:
nstd -p 'setTimeout(() => console.log("timer"), 1) && "done"'
# timer
# doneIf the code throws, nothing is printed.
One difference from node: -p always needs code after it. node -p on its
own reads the program from stdin, but nstd -p reports
-p requires an argument and exits with 9. To run code from stdin, pipe it
into plain nstd (it runs, but the result isn't printed).
#-r, --require
Loads a CommonJS module before your program starts. Repeat it, in either spelling, to load several in order:
nstd -r ./a.cjs --require=./b.cjs script.jsCommand-line options aren't passed on to child processes started with
child_process.fork() or by running process.execPath. To preload a module in
those too, put it in NODE_OPTIONS. See also
Running Code.
#Module resolution
#-C, --conditions
Adds a custom condition used when resolving a package's "exports" and
"imports", for both require() and import(). Repeat it, in either
spelling, to add several:
nstd -C custom --conditions=other script.jsA package whose "exports" has a custom entry now resolves to it instead of
default.
Note that -C=custom does not work. Like node, short options don't
accept =, so this is reported as bad option and exits with 9.
#Errors and stack traces
#--unhandled-rejections
Chooses what happens when a promise is rejected and nothing handles it:
| Mode | What happens |
|---|---|
throw (default) | Treated as an uncaught exception, unless an unhandledRejection listener handles it. |
strict | Always treated as an uncaught exception. |
warn | Print a warning and keep running. |
warn-with-error-code | Print a warning, keep running, and exit with 1 at the end. |
none | Ignore it. |
nstd --unhandled-rejections=none script.jsAny other value is rejected before the program starts, with
invalid value for --unhandled-rejections and exit code 9.
#--stack-trace-limit
Sets how many stack frames an Error keeps. The default is 10, and 0
keeps none.
nstd --stack-trace-limit=25 script.jsYou must use the = form. --stack-trace-limit 25 (with a space) is
rejected with exit code 9, just as node rejects it.
#Warnings
Every warning nstd raises is emitted as a "warning" event on process,
with an Error that has a name, a message and usually a code. Your
program can listen for them:
process.on("warning", (warning) => {
console.error(warning.name, warning.code, warning.message);
});nstd prints warnings using Node's own built-in listener, so the output and
the options below behave the same as in node:
--no-warnings(orNODE_NO_WARNINGS=1) hides every warning.--disable-warninghides a single warning by itscodeorname, and can be repeated:nstd --disable-warning=DEP0040 --disable-warning=ExperimentalWarning app.jsIt also works for nstd's own
UnsupportedOptionWarning.--trace-warningsprints a stack trace with each warning.--trace-deprecationdoes the same, but only for deprecation warnings.--throw-deprecationturns a deprecation warning into an error. As innode, the error is thrown one tick later, so the deprecated call still returns and the program then stops with an uncaught exception.--pending-deprecationshows deprecation warnings that are normally hidden.--no-deprecationhides every deprecation warning, including pending ones, and setsprocess.noDeprecationtotrue.--redirect-warnings <file>appends warnings to a file instead of printing them to stderr. If the file can't be opened, warnings go to stderr instead. Unlikenode,--diagnostic-dirdoes not redirect warnings here (it's ignored), so this is the only way to move them.
#Process
#--title
Sets the name of the process:
nstd --title=my-worker script.jsprocess.title reads it back on every platform, and you can change it at any
time:
console.log(process.title); // my-worker
process.title = "phase-two";On Linux, nstd also renames the process at the operating-system level, so
tools like ps and top show the new name:
$ nstd --title=my-worker script.js &
$ ps -o comm=,args= -p $!
my-worker my-workerNote
On every other platform, including WASI and macOS, only process.title
changes. ps keeps showing the original command, and nstd doesn't warn
about it. If you rely on --title so that ps or a process supervisor
shows a name, that only works on Linux.
A few small differences from node:
- Without
--title,process.titleis"nstd". Innodeit's the path the binary was started with. - A very long title reads back in full.
nodecuts it short to fit the space the operating system gives it; nstd only shortens the copy thatpssees. - On Linux,
ps -o commshowsmy-workerfor the example above, wherenodeshowsnode-MainThread, becausenoderenames its main thread after applying the title.
--title= with nothing after it is an error (exit code 9), and
--title "" is accepted and leaves the title unchanged, both matching node.
#--dns-result-order
Sets the order in which dns.lookup() returns addresses, and what
dns.getDefaultResultOrder() reports:
verbatim(default) keeps the order the resolver returned.ipv4firstputs IPv4 addresses first.ipv6firstputs IPv6 addresses first.
As in node, an invalid value isn't caught when the command line is read.
The program starts, then fails with ERR_INVALID_ARG_VALUE and exit code 1.
#Globals
#--experimental-eventsource and --no-experimental-websocket
These control whether EventSource, WebSocket and CloseEvent exist as
globals:
EventSourceis missing by default, as innode. Pass--experimental-eventsourceto add it.WebSocketandCloseEventexist by default. Pass--no-experimental-websocketto remove them.
#--expose-gc
Adds globalThis.gc(), which runs a real garbage collection. That's enough to
reliably clear a WeakRef or trigger a FinalizationRegistry callback.
Calling gc({ type: "major-snapshot" }) is not supported, because there's no
heap profiler to write a snapshot.
#--expose-internals
Lets require() load Node's own internal/* modules. This is meant for
testing and debugging, just like node --expose-internals. Ordinary programs
never need it.
#NODE_OPTIONS
nstd reads options from the NODE_OPTIONS environment variable before the
command line, and accepts the same options listed above:
NODE_OPTIONS='--require ./setup.cjs --no-warnings' nstd script.jsIt works the same way as in node:
- Spaces separate options. Double quotes group text that contains spaces,
and
\escapes a character inside quotes. - Options from
NODE_OPTIONStake effect but don't appear inprocess.execArgv, which only lists what was typed on the command line. - Options that choose what to run, such as
--evaland--prof, aren't allowed inNODE_OPTIONSand are rejected like an unknown option. - Options nstd ignores (see below) produce the same warning here as on the command line.
#Unsupported options
nstd handles Node options it doesn't implement in one of two ways, depending on whether ignoring them could change what your program does.
#Ignored options
Many scripts and CI setups pass options that only affect diagnostics or
performance, such as --cpu-prof, --max-old-space-size=4096, --inspect
or the --report-* family. nstd has no V8 heap, profiler or inspector, so it
can't honor them. Instead of failing, it runs your program anyway and prints a
single warning:
$ nstd --cpu-prof --max-old-space-size=64 script.js
(nstd) UnsupportedOptionWarning: --cpu-prof, --max-old-space-size are accepted
and ignored: nstd does not implement them, and the program runs as if they had
not been passed.You get one warning per run no matter how many such options you pass, and
--no-warnings or --disable-warning=UnsupportedOptionWarning hides it. The
options still appear in process.execArgv, as in node, but have no effect.
nstd --help lists every option in this group.
An option is only ignored if skipping it costs you information or speed, never correctness or security. A missing profile or a missing memory limit doesn't change what your program computes.
#Rejected options
Every other option is treated like a typo: nstd prints bad option: <name>
and exits with code 9, just as node does for an option it doesn't know.
Nothing is silently accepted and dropped.
Some examples, and why they're rejected rather than ignored:
--permissionand--allow-*ask for a sandbox nstd doesn't have. Ignoring them would give your program more access than you asked for.-c,--checkwould run a program you only wanted to syntax-check.--testwould run your program instead of its tests, and report success.--watchwould exit where you expected the process to keep running.
This can seem strict, but it saves you time. An option that silently does nothing lets your program start normally and then fail later, somewhere that seems unrelated. Rejecting it up front points straight at the real cause.