NODE(1)
π NAME π
node β the server-side JavaScript runtime, aka the girlies' favorite way to run JS outside the browser π«Ά
β¨ SYNOPSIS β¨
node [options] [v8 options] [<program-entry-point> | -e string | --]
[arguments ...]
node inspect, [<program-entry-point> | -e string | <host>:<port>] ...
node [--v8-options]
π¦ DESCRIPTION π¦
Okay so bestie, picture this: Node.js is a whole set of libraries for JavaScript that lets you use JS outside of the browser. Iconic behavior, honestly π
. Its main character energy is all about making simple, easy-to-build network clients and servers β that's the whole vibe.
And ngl, if you run node with zero arguments? It literally just drops you into a REPL. Surprise! You're in. π
π OPTIONS π
-β Alias for stdin, bestie. It's analogous to how-works in other command-line utilities: the script gets read from stdin, and everything else in the options gets passed along to that script. π--β The "okay we're DONE with node options" flag β. Everything after this gets passed to the script. Important detail though: if there's no script filename or eval/print script supplied before this, then the next argument gets used as the script filename. No cap.--abort-on-uncaught-exceptionβ Instead of just exiting, this aborts, which causes a core file to get generated for post-mortem analysis with a debugger (thinklldb,gdb, andmdb). Lowkey useful when you're doing detective work π. Now β the behavior can still be set to not abort throughprocess.setUncaughtExceptionCaptureCallback()(and through usage of thenode:domainmodule that uses it). So like, it's not the final word.--allow-addonsβ So when you're using the Permission Model, the process can't use native addons by default. Try it anyway and it throws anERR_DLOPEN_DISABLEDunless you explicitly pass--allow-addonswhen starting Node.js. Example moment π:
// Attempt to require an native addon
require('nodejs-addon-example');
$ node --permission --allow-fs-read=* index.js
node:internal/modules/cjs/loader:1319
return process.dlopen(module, path.toNamespacedPath(filename));
^
Error: Cannot load native addon because loading addons is disabled.
at Module._extensions..node (node:internal/modules/cjs/loader:1319:18)
at Module.load (node:internal/modules/cjs/loader:1091:32)
at Module._load (node:internal/modules/cjs/loader:938:12)
at Module.require (node:internal/modules/cjs/loader:1115:19)
at require (node:internal/modules/helpers:130:18)
at Object.<anonymous> (/home/index.js:1:15)
at Module._compile (node:internal/modules/cjs/loader:1233:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1287:10)
at Module.load (node:internal/modules/cjs/loader:1091:32)
at Module._load (node:internal/modules/cjs/loader:938:12) {
code: 'ERR_DLOPEN_DISABLED'
}
--allow-child-processβ Same Permission Model situation: the process can't spawn any child process by default. Attempts throw anERR_ACCESS_DENIEDunless you explicitly pass--allow-child-processwhen starting Node.js. Watch this π:
const childProcess = require('node:child_process');
// Attempt to bypass the permission
childProcess.spawn('node', ['-e', 'require("fs").writeFileSync("/new-file", "example")']);
$ node --permission --allow-fs-read=* index.js
node:internal/child_process:388
const err = this._handle.spawn(options);
^
Error: Access to this API has been restricted
at ChildProcess.spawn (node:internal/child_process:388:28)
at node:internal/main/run_main_module:17:47 {
code: 'ERR_ACCESS_DENIED',
permission: 'ChildProcess'
}
Oh and here's the tea π«: the child_process.fork() API inherits the execution arguments from the parent process. Which means if Node.js is started with the Permission Model enabled and the --allow-child-process flag is set, any child process created using child_process.fork() will automatically receive all relevant Permission Model flags. Same energy applies to child_process.spawn() β except in that case the flags get propagated via the NODE_OPTIONS environment variable rather than directly through the process arguments. Sneaky but slay.
--allow-ffiβ Permission Model again: the process can't use FFI APIs by default, and attempts will throw anERR_ACCESS_DENIEDexception unless you explicitly pass--allow-ffiwhen starting Node.js. Heads up though β thenode:ffimodule is only available in builds with FFI support. No build support, no module, periodt. Example:
const { DynamicLibrary, suffix } = require('node:ffi');
const lib = new DynamicLibrary(`./mylib.${suffix}`);
$ node --permission index.js
Error: Access to this API has been restricted. Use --allow-ffi to manage permissions.
at node:internal/main/run_main_module:17:47 {
code: 'ERR_ACCESS_DENIED',
permission: 'FFI'
}
--allow-fs-readβ This flag configures file system read permissions using the Permission Model π. The valid arguments for--allow-fs-readare:*β to allow all FileSystemRead operations.- Multiple paths can be allowed using multiple
--allow-fs-readflags. Example--allow-fs-read=/folder1/ --allow-fs-read=/folder2/
Examples can be found in the File System Permissions documentation. Also the initializer module and custom --require modules have an implicit read permission β¨.
$ node --permission -r custom-require.js -r custom-require-2.js index.js
- The
custom-require.js,custom-require-2.js, andindex.jswill be by default in the allowed read list.
process.permission.has('fs.read', 'index.js'); // true
process.permission.has('fs.read', 'custom-require.js'); // true
process.permission.has('fs.read', 'custom-require-2.js'); // true
--allow-fs-vfsβ Permission Model moment: a virtual file system cannot be mounted by default, sovfs.mount()throwsERR_INVALID_STATEunless you explicitly pass--allow-fs-vfswhen starting Node.js. Why a whole separate flag? Because a mounted VFS serves paths that the file system permissions do not describe β so mounting one is gated on its own flag rather than on--allow-fs-reador--allow-fs-write. Makes sense, honestly π§
$ node --experimental-vfs --permission --allow-fs-vfs app.js
--allow-fs-writeβ This flag configures file system write permissions using the Permission Model βοΈ. The valid arguments for--allow-fs-writeare:*β to allow all FileSystemWrite operations.- Multiple paths can be allowed using multiple
--allow-fs-writeflags. Example--allow-fs-write=/folder1/ --allow-fs-write=/folder2/
Okay important: paths delimited by comma (,) are no longer allowed. When passing a single flag with a comma a warning will be displayed β οΈ. Examples can be found in the File System Permissions documentation.
--allow-inspectorβ Permission Model: the process can't connect through the inspector protocol by default. Attempts throw anERR_ACCESS_DENIEDunless you explicitly pass--allow-inspectorwhen starting Node.js. Example:
const { Session } = require('node:inspector/promises');
const session = new Session();
session.connect();
$ node --permission index.js
Error: connect ERR_ACCESS_DENIED Access to this API has been restricted. Use --allow-inspector to manage permissions.
code: 'ERR_ACCESS_DENIED',
}
--allow-netβ Permission Model: the process can't access the network by default π. Attempts throw anERR_ACCESS_DENIEDunless you explicitly pass--allow-netwhen starting Node.js. Example:
const http = require('node:http');
// Attempt to bypass the permission
const req = http.get('http://example.com', () => {});
req.on('error', (err) => {
console.log('err', err);
});
$ node --permission index.js
Error: connect ERR_ACCESS_DENIED Access to this API has been restricted. Use --allow-net to manage permissions.
code: 'ERR_ACCESS_DENIED',
}
--allow-openssl-storeβ Permission Model: the process can't use OpenSSL STORE loaders by default β think loading a private key from a<URL>passed tocrypto.createPrivateKey(). Attempts throw anERR_ACCESS_DENIEDunless you explicitly pass--allow-openssl-store. This permission can be dropped at runtime viapermission.drop().
π¨ Okay this one needs a serious moment: this flag grants broad authority to configured OpenSSL STORE loaders. A loader may access files, devices, tokens, or the network. Access performed by a loader is not constrained by thefs.read,fs.write, ornetpermission scopes. Like, at all. Be careful, bestie π
--allow-wasiβ Permission Model: the process won't be capable of creating any WASI instances by default. And for security reasons, the call throws anERR_ACCESS_DENIEDunless you explicitly pass--allow-wasiin the main Node.js process. Example:
const { WASI } = require('node:wasi');
// Attempt to bypass the permission
new WASI({
version: 'preview1',
// Attempt to mount the whole filesystem
preopens: {
'/': '/',
},
});
$ node --permission --allow-fs-read=* index.js
Error: Access to this API has been restricted
at node:internal/main/run_main_module:30:49 {
code: 'ERR_ACCESS_DENIED',
permission: 'WASI',
}
--allow-workerβ Permission Model: the process can't create any worker threads by default π§΅. For security reasons, the call throws anERR_ACCESS_DENIEDunless you explicitly pass--allow-workerin the main Node.js process. Example:
const { Worker } = require('node:worker_threads');
// Attempt to bypass the permission
new Worker(__filename);
$ node --permission --allow-fs-read=* index.js
...and if you try to sneak past it without the right permission, the whole thing just slaps you with this:
Error: Access to this API has been restricted
at node:internal/main/run_main_module:17:47 {
code: 'ERR_ACCESS_DENIED',
permission: 'WorkerThreads'
}
Not me getting read to filth by the runtime π anywayβ
--benchβ bestie, this starts the Node.js command-line benchmark runner π₯. You gotta give it at least one explicit file or glob pattern, like fr, it needs something to chew on:
node --experimental-bench --bench benchmark.mjs
node --experimental-bench --bench 'benchmarks/**/*.js'
The --experimental-bench flag is required to use this flag or any other --bench-* option, no cap. Quote your glob patterns so the shell doesn't go expanding them behind your back π. Matching files get sorted and run serially β one at a time, no chaos. By default each file runs in its own separate child process. Benchmark files declare their benchmarks using node:bench, and they must not call run() themselves β like, stay in your lane, the runner's got it π
. See the benchmark runner documentation for the whole story. Also this flag cannot be combined with --test, --watch, --watch-path, --check, --eval, or --interactive β it's giving exclusive main character energy, pick one π€.
--bench-isolation=mode β configures how benchmark files get isolated from each other π. When mode is'process', each matching file runs in its own separate child process β that's the default, and files still run serially so their measured work doesn't overlap, zero cross-contamination β¨. When mode is'none', all matching files and benchmarks run serially inside the benchmark runner process itself. It lowkey reduces startup overhead, BUT it lets module, heap, and process state carry between files π³. Also in this mode, user writes to stdout or stderr share destinations with the benchmark reporters. The supported modes are'process'and'none'β those two, periodt.--bench-name-pattern=pattern β only runs the benchmarks whose full hierarchical name matches the JavaScript regular expression pattern π¦. Anything that doesn't match gets reported as skipped β not ignored, just gently benched π .--bench-reporter-destination=destination β tells the corresponding benchmark reporter where to send its output πΈ. The value can bestdout,stderr, or a file path. If you've got a single reporter and you don't specify a destination, it defaults tostdoutβ she just knows where she belongs π«Ά.--bench-reporter=reporter β picks your benchmark reporter π. The built-in ones arespecandjson. Thejsonreporter emits newline-delimited JSON (iykyk). You can also bring a custom reporter using a module specifier that gets resolved from the current working directory β bougie and valid β¨. This option can be repeated π. When you specify multiple reporters, each one must have a corresponding--bench-reporter-destinationβ no reporter left without a home π. The default reporter isspec.--bench-samples=count β overrides the max number of measured callback invocations for every selected benchmark π. A benchmark can still dip out earlier by callingcontext.done()β early bird rights π¦. count must be an integer between1and4294967295β that's the range, respect it fr.--bench-warmup=count β overrides the number of unreported warmup callback invocations for every selected benchmark π₯. count must be an integer between0and4294967295. Without this option, each benchmark uses its own warmup value, which defaults to10β the little stretch before the real workout πͺ.--build-sea=config β generates a single executable application from a JSON configuration file π. The argument must be a path to the configuration file. If that path isn't absolute, it gets resolved relative to the current working directory. For the config fields, cross-platform notes, and asset APIs, go read the single executable application documentation π.--build-snapshotβ generates a snapshot blob when the process exits and writes it to disk, so you can load it later with--snapshot-blobπ. When you're building the snapshot, if--snapshot-blobisn't specified, the generated blob goes by default tosnapshot.blobin the current working directory. Otherwise it goes to whatever path--snapshot-blobsays. Watch the workflow:
$ echo "globalThis.foo = 'I am from the snapshot'" > snapshot.js
# Run snapshot.js to initialize the application and snapshot the
# state of it into snapshot.blob.
$ node --snapshot-blob snapshot.blob --build-snapshot snapshot.js
$ echo "console.log(globalThis.foo)" > index.js
# Load the generated snapshot and start the application from index.js.
$ node --snapshot-blob snapshot.blob index.js
I am from the snapshot
The v8.startupSnapshot API can specify an entry point at snapshot building time, which means you don't need an extra entry script at deserialization time β the way that just simplifies everything, obsessed π:
$ echo "require('v8').startupSnapshot.setDeserializeMainFunction(() => console.log('I am from the snapshot'))" > snapshot.js
$ node --snapshot-blob snapshot.blob --build-snapshot snapshot.js
$ node --snapshot-blob snapshot.blob
I am from the snapshot
For more info, check out the v8.startupSnapshot API documentation β¨.
Now for the real talk caveats, bestie, listen up π’:
- The snapshot currently only supports loading a single entrypoint during the snapshot building process, which can load built-in modules, but not additional user-land modules π. Users can bundle their applications into a single script with their bundler of choice before building a snapshot β that's the move.
- It's complicated to ensure the serializablility of all built-in modules, which are also growing over time, so only a subset of the built-in modules are well tested to be serializable during the snapshot building process π§.
- The Node.js core test suite checks that a few fairly complex applications can be snapshotted. The list of built-in modules being captured by the built-in snapshot of Node.js is considered supported π.
- When the snapshot builder encounters a built-in module that cannot be serialized, it may crash the snapshot building process π. In that case, a typical workaround is to delay loading that module until runtime, using either
v8.startupSnapshot.setDeserializeMainFunction()orv8.startupSnapshot.addDeserializeCallback(). If you need serialization for an additional module during the snapshot building process, please file a request in the Node.js issue tracker and link to it in the tracking issue for user-land snapshots π«Ά. --build-snapshot-configβ specifies the path to a JSON configuration file that configures snapshot creation behavior π. The following options are currently supported:builder<string> β Required. Provides the name to the script that is executed before building the snapshot, as if--build-snapshothad been passed with builder as the main script name.withoutCodeCache<boolean> β Optional. Including the code cache reduces the time spent on compiling functions included in the snapshot, at the expense of a bigger snapshot size and potentially breaking portability of the snapshot.
When using this flag, additional script files provided on the command line will not be executed and instead get interpreted as regular command line arguments π.
-c,--checkβ syntax check the script without executing it π¦. Like a vibe check but for your syntax, and nothing actually runs.--completion-bashβ prints a source-able bash completion script for Node.js π . Get that tab-completion glow-up:
node --completion-bash > node_bash_completion
source node_bash_completion
-Ccondition,--conditions=condition β provides custom conditional exports resolution conditions π. Any number of custom string condition names are permitted β go wild. The default Node.js conditions of"node","default","import", and"require"will always apply as defined. For example, to run a module with"development"resolutions:
node -C development app.js
--config-file=path,--config-fileβ if present, Node.js looks for a configuration file at the specified path π. If no path is specified, Node.js looks for anode.config.jsonfile in the current working directory. To specify a custom path, use the--config-file=pathform. The space-separated--config-file pathform is not supported β that's a no from her π .
Node.js reads the config file and applies the settings. It should be a JSON file with this structure. The vX.Y.Z in the $schema must be replaced with the version of Node.js you're using, or latest-vX.x for the latest version of that major release line β¨:
{
"$schema": "https://nodejs.org/dist/vX.Y.Z/docs/node-config-schema.json",
"nodeOptions": {
"import": [
"amaro/strip"
],
"watch-path": "src",
"watch-preserve-output": true
},
"test": {
"test-isolation": "process"
},
"watch": {
"watch-preserve-output": true
}
}
The configuration file supports namespace-specific options:
- The
nodeOptionsfield contains CLI flags that are allowed inNODE_OPTIONSπ. - Namespace fields like
test,watch, andpermissioncontain configuration specific to that subsystem π.
The configuration file can target a specific Node.js major version with nodeVersion π¦:
{
"nodeVersion": 25,
"nodeOptions": {
"watch-path": "src"
}
}
To keep multiple version-specific configurations in the same file, use the configs array. Node.js will use the first entry whose nodeVersion matches the current Node.js major version:
{
"$schema": "https://nodejs.org/dist/latest-v26.x/docs/node-config-schema.json",
"configs": [
{
"nodeVersion": 25,
"config": {
"$schema": "https://nodejs.org/dist/latest-v25.x/docs/node-config-schema.json",
"nodeOptions": {
"watch-path": "src"
}
}
}
]
}
okay so when you use configs, the top level may only contain $schema and configs β that's it, bestie, no sneaking extra keys in there π
. Each configs item has to define an integer nodeVersion and an object config. A single top-level config doesn't need nodeVersion, but if you do put it there it must match the current Node.js major version. no cap.
And here's the cute part π β when a namespace shows up in the configuration file, Node.js automatically enables the corresponding flag (think --test, --watch, --permission). So you can configure all your subsystem-specific options without ever passing the flag on the command line. it's giving convenience. For example:
{
"test": {
"test-isolation": "process"
}
}
is literally equivalent to:
node --test --test-isolation=process
Want the automatic flag to chill out while you still use namespace options? Just explicitly set the flag to false inside the namespace:
{
"test": {
"test": false,
"test-isolation": "process"
}
}
A few things to know π β no-op flags are not supported, and not all V8 flags are currently supported either. You can use the official JSON schema to validate the configuration file, but heads up: the schema may vary depending on the Node.js version. Each key in the config file corresponds to a flag you could pass as a command-line argument, and the value of the key is the value you'd pass to that flag. For example, the configuration file above is equivalent to these command-line arguments:
node --import amaro/strip --watch-path=src --watch-preserve-output --test-isolation=process
The priority in configuration goes like this, highest first π:
NODE_OPTIONSand command-line options- Dotenv
NODE_OPTIONS - Configuration file
So values in the configuration file will not override the values in the environment variables, command-line options, or the NODE_OPTIONS env file parsed by the --env-file flag. Also: keys cannot be duplicated within the same namespace or across different namespaces. The configuration parser will throw an error if the configuration file contains unknown keys or keys that can't be used in a namespace.
π¨ REAL TALK: Node.js will not sanitize or perform validation on the user-provided configuration. So NEVER use untrusted configuration files. periodt. π
π» --cpu-prof
Starts the V8 CPU profiler on startup, and writes the CPU profile to disk before exit. If --cpu-prof-dir isn't specified, the generated profile lands in the current working directory. And if --cpu-prof-name isn't specified, the profile gets named CPU.${yyyymmdd}.${hhmmss}.${pid}.${tid}.${seq}.cpuprofile. slay.
$ node --cpu-prof index.js
$ ls *.cpuprofile
CPU.20190409.202950.15293.0.0.cpuprofile
If you do pass --cpu-prof-name, your value is used as a template for the file name β¨. The following placeholder is supported and gets substituted at runtime:
${pid}β the current process ID
$ node --cpu-prof --cpu-prof-name 'CPU.${pid}.cpuprofile' index.js
$ ls *.cpuprofile
CPU.15293.cpuprofile
π --cpu-prof-dir
Specifies the directory where the CPU profiles generated by --cpu-prof get placed. The default value is controlled by the --diagnostic-dir command-line option.
β±οΈ --cpu-prof-interval
Specifies the sampling interval in microseconds for the CPU profiles generated by --cpu-prof. The default is 1000 microseconds.
π·οΈ --cpu-prof-name
Specifies the file name of the CPU profile generated by --cpu-prof.
π§ --diagnostic-dir=directory
Sets the directory where all diagnostic output files get written. Defaults to the current working directory. This affects the default output directory of:
--cpu-prof-dir--heap-prof-dir--redirect-warnings
π« --disable-proto=mode
Disables the Object.prototype.__proto__ property. If mode is delete, the property is removed entirely. If mode is throw, accesses to the property throw an exception with the code ERR_PROTO_ACCESS. pick your fighter π
π
--disable-sigusr1
Disables the ability of starting a debugging session by sending a SIGUSR1 signal to the process. not today, signal π«Ά
π --disable-warning=code-or-type
Disables specific process warnings by code or type. Warnings emitted from process.emitWarning() may contain a code and a type. This option will not-emit warnings that have a matching code or type. (List of deprecation warnings.)
The Node.js core warning types are: DeprecationWarning and ExperimentalWarning.
For example, the following script will not emit DEP0025 require('node:sys') when executed with node --disable-warning=DEP0025:
import sys from 'node:sys';
const sys = require('node:sys');
For example, the following script will emit the DEP0025 require('node:sys'), but not any Experimental Warnings (such as ExperimentalWarning: vm.measureMemory is an experimental feature in <=v21) when executed with node --disable-warning=ExperimentalWarning:
import sys from 'node:sys';
import vm from 'node:vm';
vm.measureMemory();
const sys = require('node:sys');
const vm = require('node:vm');
vm.measureMemory();
π§± --disable-wasm-trap-handler
okay this one's a whole saga, buckle up π¦. Node.js enables V8's trap-handler-based WebAssembly bound checks on 64-bit platforms, which significantly improves WebAssembly performance by eliminating the need for inline bound checks. That optimization requires allocating a large virtual memory cage per WebAssembly memory instance (currently typically 8GB for 32-bit WebAssembly memory, 16GB for 64-bit WebAssembly memory) to trap out-of-bound accesses.
On most 64-bit platforms the virtual memory address space is usually large enough (around 128TB) to accommodate typical WebAssembly usages β but if the machine has manual limits on virtual memory (e.g. through ulimit -v), WebAssembly memory allocation is more likely to fail with WebAssembly.Memory(): could not allocate memory.
At startup, Node.js automatically checks whether there's enough virtual memory available to allocate at least one cage, and if not, the trap-handler optimization is automatically disabled so that WebAssembly can still run using inline bound checks (with less optimal performance). But if your app needs to create many WebAssembly memory instances and the machine still configures a relatively high limit on virtual memory, allocation of WebAssembly memory instances may still fail more quickly than expected due to the raised virtual memory usage. π
--disable-wasm-trap-handler fully disables this optimization so that WebAssembly memory instances always use inline bound checks instead of reserving large virtual memory cages. This allows more instances to be created when the virtual memory address space available to the Node.js process is limited. iconic behavior honestly π
π‘οΈ --disallow-code-generation-from-strings
Makes built-in language features like eval and new Function that generate code from strings throw an exception instead. Note bestie: this does not affect the Node.js node:vm module.
π --dns-result-order=order
Sets the default value of order in dns.lookup() and dnsPromises.lookup(). The value could be:
ipv4first: sets default order toipv4first.ipv6first: sets default order toipv6first.verbatim: sets default order toverbatim.
The default is verbatim, and dns.setDefaultResultOrder() has higher priority than --dns-result-order. iykyk πΈ
π --enable-fips
Enables FIPS mode at startup. With OpenSSL 3, a configured provider named fips must be available and initialize successfully. With OpenSSL 1.1.1, Node.js must be built against a FIPS-capable OpenSSL.
π‘ --enable-fips-indicator-events
Publishes OpenSSL FIPS indicator results to the 'crypto.fips.indicator' diagnostics channel. This option requires OpenSSL 3.4 or later. Important caveat β¨ β it does not enable FIPS mode or change whether an operation is permitted.
πΊοΈ --enable-source-maps
Enables Source Map support for stack traces. When you're using a transpiler β like TypeScript, bestie β stack traces thrown by an application reference the transpiled code, not the original source position. π --enable-source-maps enables caching of Source Maps and makes a best effort to report stack traces relative to the original source file.
Overriding Error.prepareStackTrace may prevent --enable-source-maps from modifying the stack trace. So call and return the results of the original Error.prepareStackTrace in your overriding function to modify the stack trace with source maps:
const originalPrepareStackTrace = Error.prepareStackTrace;
Error.prepareStackTrace = (error, trace) => {
// Modify error and trace and format stack trace with
// original Error.prepareStackTrace.
return originalPrepareStackTrace(error, trace);
};
β οΈ Note: enabling source maps can introduce latency to your application whenError.stackis accessed. If you accessError.stackfrequently in your app, take into account the performance implications of--enable-source-maps. don't say I didn't warn you π«Ά
π --entry-url
When present, Node.js will interpret the entry point as a URL rather than a path. Follows ECMAScript module resolution rules. Any query parameter or hash in the URL will be accessible via import.meta.url. cute, right? π
node --entry-url 'file:///path/to/file.js?queryparams=work#and-hashes-too'
node --entry-url 'file.ts?query#hash'
node --entry-url 'data:text/javascript,console.log("Hello")'
--env-file-if-exists=fileβ literally the exact same behavior as--env-file, except bestie, it does not throw an error if the file isn't there. That's the whole vibe. π--env-file=fileβ loads environment variables from a file (path is relative to the current directory) and makes them available to your app onprocess.env. The environment variables that configure Node.js itself, likeNODE_OPTIONS, get parsed and applied too. If the same variable is defined both in the environment and in the file, the environment wins β environment takes precedence. You can pass multiple--env-filearguments, and subsequent files override pre-existing variables defined in previous files. If the file doesn't exist? An error is thrown, no cap. π
node --env-file=.env --env-file=.development.env index.js
The format of the file is one line per key-value pair of environment variable name and value, separated by =:
PORT=3000
Any text after a # is treated as a comment:
# This is a comment
PORT=3000 # This is also a comment
Values can start and end with the following quotes: a backtick, ", or '. They are omitted from the values.
USERNAME="nodejs" # will result in `nodejs` as the value.
Multi-line values are supported:
MULTI_LINE="THIS IS
A MULTILINE"
# will result in `THIS IS\nA MULTILINE` as the value.
An export keyword before a key is ignored:
export USERNAME="nodejs" # will result in `nodejs` as the value.
If you want to load environment variables from a file that may not exist, use the --env-file-if-exists flag instead. β¨
-e,--eval scriptβ evaluate the following argument as JavaScript. The modules which are predefined in the REPL can also be used in script. If script starts with-, pass it using=(for example,node --print --eval=-42) so it is parsed as the value of--eval. On Windows, usingcmd.exea single quote will not work correctly because it only recognizes double"for quoting. In Powershell or Git bash, both'and"are usable. It is possible to run code containing inline types unless the--no-strip-typesflag is provided. π«Ά--experimental-addon-modulesβ enable experimental import support for.nodeaddons.--experimental-benchβ enable the experimentalnode:benchmodule and command-line benchmark runner. πββοΈ--experimental-dtlsβ enable experimental support for the DTLS protocol. See the dtls documentation for details.--experimental-eventsourceβ enable exposition ofEventSourceWeb API on the global scope.--experimental-import-meta-resolveβ enable experimentalimport.meta.resolve()parent URL support, which allows passing a second parentURL argument for contextual resolution. Previously gated the entireimport.meta.resolvefeature. π¦--experimental-import-textβ enable experimental support for importing modules withwith { type: 'text' }.--experimental-inspector-network-resourceβ enable experimental support for inspector network resources.--experimental-loader=moduleβ specify the module containing exported asynchronous module customization hooks. module may be any string accepted as an import specifier. This feature requires--allow-workerif used with the Permission Model. π₯--experimental-network-inspectionβ enable experimental support for the network inspection with Chrome DevTools.--experimental-package-map=<path>β enable experimental package map resolution. The path argument specifies the location of a JSON configuration file that defines package resolution mappings. π
node --experimental-package-map=./package-map.json app.js
When enabled, bare specifier resolution consults the package map for resolution. This allows explicit control over which packages can import which dependencies. See Package maps for details on the configuration file format and resolution algorithm.
--experimental-print-required-tlaβ if the ES module graph cannot berequire()'d because it contains any top-level await, this flag allows Node.js to locate and print their locations. π so helpful--experimental-quicβ enable experimental support for the QUIC protocol.--experimental-sea-configβ use this flag to generate a blob that can be injected into the Node.js binary to produce a single executable application. See the documentation about this configuration for details. π--experimental-shadow-realmβ use this flag to enableShadowRealmsupport.--experimental-storage-inspectionβ enable experimental support for storage inspection--experimental-stream-iterβ enable the experimentalnode:stream/itermodule.--experimental-test-coverageβ when used in conjunction with thenode:testmodule, a code coverage report is generated as part of the test runner output. If no tests are run, a coverage report is not generated. See the documentation on collecting code coverage from tests for more details. π--experimental-test-module-mocksβ enable module mocking in the test runner. This feature requires--allow-workerif used with the Permission Model.--experimental-test-tag-filter='<expr>'β run only tests that match the provided boolean tag-filter expression. Tests declare tags via thetagsoption ontest(),it(),suite(), ordescribe(). Tags inherit from suites to nested tests by union. The expression supports boolean operators (and/&&,or/||,not/!), parentheses for grouping, and*wildcards inside identifiers. Standard precedence applies:notbinds tighter thanand, which binds tighter thanor. See Test tags for the full grammar and behavior. The flag may be specified more than once; multiple expressions are combined with AND, so a test must satisfy every expression to run. A malformed expression causes the test runner to exit with a non-zero status before running any tests. π no pressure--experimental-vfsβ enable the experimentalnode:vfsmodule.--experimental-vm-modulesβ enable experimental ES Module support in thenode:vmmodule.--experimental-wasi-unstable-preview1β enable experimental WebAssembly System Interface (WASI) support.--experimental-web-workerβ enable experimental support for the Web Worker API.--experimental-worker-inspectionβ enable experimental support for the worker inspection with Chrome DevTools.--force-context-awareβ disable loading native addons that are not context-aware.--force-fips=[mode]β enable FIPS mode at startup and prevent it from being disabled from script code. The same OpenSSL requirements as--enable-fipsapply. An optional mode can be specified using--force-fips=mode:provider: preserve the OpenSSL FIPS provider's configured handling of non-approved operations. This is the current default when the mode is omitted.strict: reject non-approved operations reported through the OpenSSL FIPS indicator callback. This mode requires OpenSSL 3.4 or later.
The strict mode only covers operations reported through the callback for OpenSSL's default library context. It does not cover native addons that use another OSSL_LIB_CTX or another copy of libcrypto, nor operation-specific indicators that do not invoke the callback. β οΈ
--force-node-api-uncaught-exceptions-policyβ enforcesuncaughtExceptionevent on Node-API asynchronous callbacks. To prevent from an existing add-on from crashing the process, this flag is not enabled by default. In the future, this flag will be enabled by default to enforce the correct behavior.--frozen-intrinsicsβ enable experimental frozen intrinsics likeArrayandObject. Only the root context is supported. There is no guarantee thatglobalThis.Arrayis indeed the default intrinsic reference. Code may break under this flag. π¬ To allow polyfills to be added,--requireand--importboth run before freezing intrinsics.--heap-profβ starts the V8 heap profiler on start up, and writes the heap profile to disk before exit. If--heap-prof-diris not specified, the generated profile is placed in the current working directory. If--heap-prof-nameis not specified, the generated profile is namedHeap.${yyyymmdd}.${hhmmss}.${pid}.${tid}.${seq}.heapprofile. π§
$ node --heap-prof index.js
$ ls *.heapprofile
Heap.20190409.202950.15293.0.001.heapprofile
--heap-prof-dirβ specify the directory where the heap profiles generated by--heap-profwill be placed. The default value is controlled by the--diagnostic-dircommand-line option.--heap-prof-intervalβ specify the average sampling interval in bytes for the heap profiles generated by--heap-prof. The default is512 * 1024bytes.--heap-prof-nameβ specify the file name of the heap profile generated by--heap-prof. π--heapsnapshot-near-heap-limit=max_countβ okay so this one writes a V8 heap snapshot to disk when your V8 heap usage is creeping up on the heap limit πcounthas to be a non-negative integer, and if it is, Node.js will write no more thanmax_countsnapshots to disk. Here's the tea though: while it's generating snapshots, garbage collection may get triggered and bring the heap usage down. So lowkey multiple snapshots can land on disk before your Node.js instance finally runs out of memory π Those heap snapshots can be compared to figure out what objects are being allocated during the time between consecutive snapshots. It's not guaranteed that Node.js will write exactlymax_countsnapshots, but it will try its best to generate at least one and up tomax_countsnapshots before the instance runs out of memory whenmax_countis greater than 0. Also bestie, generating V8 snapshots takes time and memory β both the memory managed by the V8 heap and native memory outside the V8 heap. The bigger the heap is, the more resources it needs. Node.js will adjust the V8 heap to accommodate the additional V8 heap memory overhead and try its best to avoid using up all the memory available to the process. But when the process uses more memory than the system deems appropriate, the process may be terminated abruptly by the system, depending on the system configuration π
$ node --max-old-space-size=100 --heapsnapshot-near-heap-limit=3 index.js
Wrote snapshot to Heap.20200430.100036.49580.0.001.heapsnapshot
Wrote snapshot to Heap.20200430.100037.49580.0.002.heapsnapshot
Wrote snapshot to Heap.20200430.100038.49580.0.003.heapsnapshot
<--- Last few GCs --->
[49580:0x110000000] 4826 ms: Mark-sweep 130.6 (147.8) -> 130.5 (147.8) MB, 27.4 / 0.0 ms (average mu = 0.126, current mu = 0.034) allocation failure scavenge might not succeed
[49580:0x110000000] 4845 ms: Mark-sweep 130.6 (147.8) -> 130.6 (147.8) MB, 18.8 / 0.0 ms (average mu = 0.088, current mu = 0.031) allocation failure scavenge might not succeed
<--- JS stacktrace --->
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
--heapsnapshot-signal=signalβ this one enables a signal handler that makes the Node.js process write a heap dump when the specified signal is received πsignalmust be a valid signal name. Disabled by default, bestie.
$ node --heapsnapshot-signal=SIGUSR2 index.js &
$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
node 1 5.5 6.1 787252 247004 ? Ssl 16:43 0:02 node --heapsnapshot-signal=SIGUSR2 index.js
$ kill -USR2 1
$ ls
Heap.20190718.133405.15554.0.001.heapsnapshot
-h,--helpβ prints the node command-line options β¨ but heads up: the output of this option is less detailed than this document. So like, you're already in the better place π--icu-data-dir=fileβ specify the ICU data load path. (This overridesNODE_ICU_DATA.) π§--import=moduleβ preloads the specified module at startup π¦ If the flag is provided several times, each module will be executed sequentially in the order they appear, starting with the ones provided inNODE_OPTIONS. It follows ECMAScript module resolution rules. Use--requireto load a CommonJS module. Modules preloaded with--requirewill run before modules preloaded with--import. Modules are preloaded into the main thread as well as any worker threads, forked processes, or clustered processes β it's giving everywhere-at-once energy π--input-type=typeβ this configures Node.js to interpret--evalor STDIN input as CommonJS or as an ES module. Valid values are"commonjs","module","module-typescript"and"commonjs-typescript". The"-typescript"values are not available with the flag--no-strip-types. The default is no value, or"commonjs"if--no-experimental-detect-moduleis passed. If--input-typeis not provided, Node.js will try to detect the syntax with the following steps:- Run the input as CommonJS.
- If step 1 fails, run the input as an ES module.
- If step 2 fails with a
SyntaxError, strip the types. - If step 3 fails with an error code
ERR_UNSUPPORTED_TYPESCRIPT_SYNTAXorERR_INVALID_TYPESCRIPT_SYNTAX, throw the error from step 2, including the TypeScript error in the message, else run as CommonJS. - If step 4 fails, run the input as an ES module.
To avoid the delay of multiple syntax detection passes, the --input-type=type flag can be used to specify how the --eval input should be interpreted. The REPL does not support this option π And usage of --input-type=module with --print will throw an error, as --print does not support ES module syntax.
--insecure-http-parserβ enables leniency flags on the HTTP parser. This may allow interoperability with non-conformant HTTP implementations. When enabled, the parser will accept the following:- Invalid HTTP headers values.
- Invalid HTTP versions.
- Allow message containing both
Transfer-EncodingandContent-Lengthheaders. - Allow extra data after message when
Connection: closeis present. - Allow extra transfer encodings after chunked has been provided.
- Allow
\nto be used as token separator instead of\r\n. - Allow
\r\nnot to be provided after a chunk. - Allow spaces to be present after a chunk size and before
\r\n.
bestie all of the above will expose your application to request smuggling or poisoning attack π Avoid using this option. Like, fr fr, don't.
--inspect-brk=[[host:]port]β activates the inspector onhost:portand breaks at the start of the user script π₯ Defaulthost:portis127.0.0.1:9229. If port0is specified, a random available port will be used. See V8 Inspector integration for Node.js for further explanation on the Node.js debugger. And see the security warning below regarding thehostparameter usage π--inspect-port=[host:]portβ sets thehost:portto be used when the inspector is activated π Useful when activating the inspector by sending theSIGUSR1signal. Except when--disable-sigusr1is passed. Default host is127.0.0.1. If port0is specified, a random available port will be used. See the security warning below regarding thehostparameter usage.--inspect-publish-uid=stderr,httpβ specifies ways of the inspector web socket url exposure β¨ By default the inspector websocket url is available instderrand under/json/listendpoint onhttp://host:port/json/list.--inspect-wait=[[host:]port]β activates the inspector onhost:portand waits for the debugger to be attached π«Ά Defaulthost:portis127.0.0.1:9229. If port0is specified, a random available port will be used. See V8 Inspector integration for Node.js for further explanation on the Node.js debugger. See the security warning below regarding thehostparameter usage.--inspect=[[host:]port]β activates the inspector onhost:portπ Default is127.0.0.1:9229. If port0is specified, a random available port will be used. V8 inspector integration allows tools such as Chrome DevTools and IDEs to debug and profile Node.js instances β main character energy for real. The tools attach to Node.js instances via a tcp port and communicate using the Chrome DevTools Protocol. See V8 Inspector integration for Node.js for further explanation on the Node.js debugger.-i,--interactiveβ opens the REPL even if stdin does not appear to be a terminal πΈ (iconic behaviour, honestly)--jitlessβ disables runtime allocation of executable memory. This may be required on some platforms for security reasons. It can also reduce attack surface on other platforms, but the performance impact may be severe π When WebAssembly is unavailable in this mode, TypeScript parsing and WebAssembly module imports throwERR_WEBASSEMBLY_NOT_SUPPORTED. Node.js does not guarantee alternative implementations of features that require WebAssembly or runtime allocation of executable memory when those capabilities are unavailable. This flag controls V8's runtime code generation. It does not impose an operating-system restriction on executable memory allocated by native addons ornode:ffi. FFI operations that require unavailable executable memory can throwERR_RX_MEMORY_NOT_SUPPORTED.--localstorage-file=fileβ thefileused to storelocalStoragedata π If the file does not exist, it is created the first timelocalStorageis accessed. The same file may be shared between multiple Node.js processes concurrently. (sharing is caring, bestie π«Ά)--max-http-header-size=sizeβ specify the maximum size, in bytes, of HTTP headers. Defaults to16 KiB. β--max-old-space-size-percentage=percentageβ sets the maximum memory size of V8's old memory section as a percentage of available system memory π This flag takes precedence over--max-old-space-sizewhen both are specified. Thepercentageparameter must be a number greater than 0 and up to 100, representing the percentage of available system memory to allocate to the V8 heap.
Note: this flag utilizes --max-old-space-size, which may be unreliable on 32-bit platforms due to integer overflow issues π
# Using 50% of available system memory
node --max-old-space-size-percentage=50 index.js
# Using 75% of available system memory
node --max-old-space-size-percentage=75 index.js
--network-family-autoselection-attempt-timeoutβ sets the default value for the network family autoselection attempt timeout π For more information, seenet.getDefaultAutoSelectFamilyAttemptTimeout().--no-addonsβ disables thenode-addonsexports condition as well as disables loading native addons. When--no-addonsis specified, callingprocess.dlopenor requiring a native C++ addon will fail and throw an exception π no native addons for you, periodt.--no-async-context-frameβ turns off theAsyncLocalStoragethat's backed byAsyncContextFrame, and falls back to the older implementation that leaned onasync_hooks. Ngl the old model is still hanging around for compatibility with Electron, and for situations where the context flow might come out different. But bestie β if you do find a difference in the flow, please report it, okay? π--no-deprecationβ mutes deprecation warnings. Silence, bestie π€«--no-experimental-detect-moduleβ disables using syntax detection to figure out what type a module is.--no-experimental-ffiβ disables the experimentalnode:ffimodule. Heads up tho: this flag only exists in builds that have FFI support π--no-experimental-global-navigatorβ stops theNavigatorAPI from being exposed on the global scope.--no-experimental-repl-awaitβ use this one to disable top-levelawaitin the REPL.--no-experimental-require-moduleβ legacy alias for--no-require-module. iykyk β¨--no-experimental-sqliteβ disables the experimentalnode:sqlitemodule.--no-experimental-websocketβ stops<WebSocket>from being exposed on the global scope.--no-experimental-webstorageβ disables Web Storage support.--no-extra-info-on-fatal-exceptionβ hides the extra info that shows up on a fatal exception that makes the process exit. Less lore, more mystery π--no-force-async-hooks-checksβ disables the runtime checks forasync_hooks. Lowkey they still get enabled dynamically wheneverasync_hooksitself is enabled, so it's not fully off-off.--no-global-search-pathsβ don't search modules from global paths like$HOME/.node_modulesand$NODE_PATH.--no-network-family-autoselectionβ disables the family autoselection algorithm β unless the connection options explicitly enable it. Rude of them, honestly.--no-require-moduleβ disables support for loading a synchronous ES module graph insiderequire(). See Loading ECMAScript modules using require() π¦--no-strip-typesβ disables type-stripping for TypeScript files. For more info, see the TypeScript type-stripping documentation β¨--no-warningsβ silences all process warnings, deprecations included. Not a single peep π--no-worker-snapshotβ worker threads start by running the internal bootstrap from scratch, instead of deserializing the bootstrapped context out of the built-in startup snapshot.--node-memory-debugβ enables extra debug checks for memory leaks inside Node.js internals. Fr fr this is usually only useful if you're debugging Node.js itself, not your app π«Ά--openssl-config=*fileβ loads an OpenSSL configuration file on startup. That file can activate an OpenSSL 3 FIPS provider, or configure a FIPS-capable OpenSSL 1.1.1 build. See FIPS mode. And important: this option takes precedence over theOPENSSL_CONFenvironment variable π--openssl-legacy-providerβ enables the OpenSSL 3.0 legacy provider. For more info, please seeOSSL_PROVIDER-legacy.--openssl-shared-configβ makes the OpenSSL default configuration section,openssl_conf, get read from the OpenSSL configuration file. The default config file is namedopenssl.cnf, but you can change that with theOPENSSL_CONFenvironment variable, or with the command line option--openssl-config. Where the default OpenSSL config file actually lives depends on how OpenSSL is being linked to Node.js.
Sharing the OpenSSL configuration may have unwanted implications π and it's recommended to use a configuration section specific to Node.js, which is nodejs_conf and is the default when this option is not used.
--pending-deprecationβ emits pending deprecation warnings. Pending deprecations are generally identical to a runtime deprecation, with one notable exception: they're turned off by default and won't be emitted unless either the--pending-deprecationcommand-line flag or theNODE_PENDING_DEPRECATION=1environment variable is set. Think of pending deprecations as a selective "early warning" mechanism that developers can use to detect deprecated API usage π--permissionβ enables the Permission Model for the current process. Once it's on, the following permissions are restricted:- File System β manageable through
--allow-fs-read,--allow-fs-writeflags - Network β manageable through
--allow-netflag - Child Process β manageable through
--allow-child-processflag - Worker Threads β manageable through
--allow-workerflag - WASI β manageable through
--allow-wasiflag - Addons β manageable through
--allow-addonsflag - FFI β manageable through
--allow-ffiflag - OpenSSL STORE loaders β manageable through
--allow-openssl-storeflag
- File System β manageable through
--permission-auditβ enables audit mode for the permission model. This is the β¨vibe checkβ¨ version: permission checks get performed, but access is not denied β noERR_ACCESS_DENIEDerror gets thrown. Instead, each permission violation is published through thenode:diagnostics_channelmodule, and execution just carries on normally.
This flag does not require --permission to be specified. The --allow-* flags aren't needed in audit mode either, since nothing is being denied π
Audit mode is literally so useful for discovering what permissions your app requires before you deploy with --permission. See the Permission Model documentation for the list of diagnostics channel names and the message format.
If both --permission and --permission-audit are specified, --permission takes precedence and the Permission Model runs in enforce mode. Main character wins π
--preserve-symlinksβ tells the module loader to preserve symbolic links when resolving and caching modules. By default, when Node.js loads a module from a path that's symbolically linked to a different on-disk location, Node.js dereferences the link and uses the actual on-disk "real path" of the module as both an identifier and as a root path to locate other dependency modules. In most cases that default behavior is totally acceptable. But β when you're using symbolically linked peer dependencies, like in the example below, the default behavior causes an exception to be thrown ifmoduleAattempts torequiremoduleBas a peer dependency:
{appDir}
βββ app
β βββ index.js
β βββ node_modules
β βββ moduleA -> {appDir}/moduleA
β βββ moduleB
β βββ index.js
β βββ package.json
βββ moduleA
βββ index.js
βββ package.json
The --preserve-symlinks command-line flag tells Node.js to use the symlink path for modules instead of the real path, which lets symbolically linked peer dependencies be found π
Note, however, that using --preserve-symlinks can have other side effects. Specifically, symbolically linked native modules can fail to load if those are linked from more than one location in the dependency tree β Node.js would see those as two separate modules and would attempt to load the module multiple times, causing an exception to be thrown π
Also: the --preserve-symlinks flag does not apply to the main module, which is what lets node --preserve-symlinks node_module/.bin/<foo> work. To apply the same behavior for the main module, also use --preserve-symlinks-main.
--preserve-symlinks-mainβ tells the module loader to preserve symbolic links when resolving and caching the main module (require.main). This flag exists so the main module can opt in to the same behavior that--preserve-symlinksgives to all other imports. They're separate flags, however, for backward compatibility with older Node.js versions. And--preserve-symlinks-maindoes not imply--preserve-symlinksβ use--preserve-symlinks-mainin addition to--preserve-symlinkswhen it's not desirable to follow symlinks before resolving relative paths. See--preserve-symlinksfor more information π«Ά-p,--printscript β identical to-ebut prints the result. That's the whole thing. Iconic, honestly π--process-timeout=*durationβ exits the process with code124if it's still running after duration, measured from the start of the process. duration is a positive integer followed by a unit:ms,s,m, orhβ for example500ms,30s,5m, or1h. The exit code matches the one used by thetimeout(1)command β°
Before exiting, Node.js prints what the main thread was doing and which resources were keeping the event loop alive, all to stderr:
β¦and here's what that hot mess looks like when it actually fires off, bestie:
$ node --process-timeout=5s server.js
(node:25418) Process timed out after 5s (--process-timeout). Exiting with code 124.
Main thread was not executing JavaScript.
Resources keeping the event loop alive:
TCPServerWrap (listening on [::]:3000, fd 20)
Timeout x2 (next due in 2931ms)
So if the main thread was executing JavaScript, you get its stack trace printed instead of that resources list, okay? And if you want even more tea, use --report-on-process-timeout to also generate a diagnostic report. π
The process exits without emitting the 'beforeExit' and 'exit' events, because likeβ¦ the JavaScript code may literally be what keeps the process running, so. Code coverage and profiles, such as those enabled with NODE_V8_COVERAGE=dir or --cpu-prof, are still written though β she's not gonna ghost your data.
β οΈ If the main thread does not respond within two seconds β for example because it's blocked in a synchronous operation such as child_process.execSync() β Node.js exits immediately without printing the stack trace and resources. Rude but fair.
Okay, the ground rules, because this flag is so particular:
- This option is not allowed in
NODE_OPTIONS. - It cannot be combined with the options that enable the inspector, such as
--inspect,--inspect-brk,--inspect-wait,--inspect-port, and--inspect-publish-uid. - Nor with
node inspect,--run, or--build-snapshot. - While it is in effect,
inspector.open()andsession.connectToMainThread()throw, and requests to activate the inspector withSIGUSR1are ignored. Blocked. Denied. Not today.
And the deets for the weird setups:
- Child processes that inherit
process.execArgv, such as those created withchild_process.fork(), apply the timeout from their own start. - With
--watch, the timeout applies to each run of the application rather than to the process that watches for changes. - When running tests from the command line, the test runner process applies the timeout to the whole run, and each test file that runs in its own process applies it as well.
--profβ Generate V8 profiler output. Go off, profiler. π₯--prof-processβ Process V8 profiler output generated using the V8 option--prof. Like, take that raw data and make it make sense.--redirect-warnings=fileβ Write process warnings to the givenfileinstead of printing to stderr. The file gets created if it does not exist, and will be appended to if it does. If something goes wrong while attempting to write the warning to the file, the warning goes to stderr instead. Thefilename may be an absolute path β and if it's not, the default directory it gets written to is controlled by the--diagnostic-dircommand-line option. π--report-compactβ Write reports in a compact format: single-line JSON, which is way more easily consumable by log processing systems than the default multi-line format designed for human consumption. (The default is for the girlies, this one is for the robots. π€)--report-dir=directory,--report-directory=directoryβ Location at which the report will be generated. Pick your venue, bestie. π--report-exclude-envβ When--report-exclude-envis passed, the diagnostic report generated will not contain theenvironmentVariablesdata. Privacy era. π--report-exclude-networkβ Excludeheader.networkInterfacesfrom the diagnostic report. By default this is not set and the network interfaces are included. Opt out if you're feeling mysterious. π¦--report-filename=filenameβ Name of the file to which the report will be written. Iffilenameis set to'stdout'or'stderr', the report is written to the stdout or stderr of the process respectively. Choose your channel. π‘--report-on-fatalerrorβ Enables the report to be triggered on fatal errors (internal errors within the Node.js runtime such as out of memory) that lead to termination of the application. Lowkey useful to inspect various diagnostic data elements such as heap, stack, event loop state, resource consumption etc. to reason about the fatal error. Autopsy but make it aesthetic. π--report-on-process-timeoutβ Enables the report to be generated when--process-timeoutexpires, in addition to the summary printed to stderr. Useful to inspect the JavaScript and native stacks, the event loop state, and resource consumption to reason about why the process did not exit. Requires--process-timeout. Worker threads that do not provide their part of the report within two seconds β for example because they're blocked in a synchronous operation such aschild_process.execSync()β are left out of it. Girl left on read. π
β οΈ Yeah β it genuinely requires --process-timeout. Don't try her solo.
--report-on-signalβ Enables report to be generated upon receiving the specified (or predefined) signal to the running Node.js process. The signal to trigger the report is specified through--report-signal. β¨--report-signal=signalβ Sets or resets thesignalfor report generation (not supported on Windows). Default signal isSIGUSR2. π―--report-uncaught-exceptionβ Enables report to be generated when the process exits due to an uncaught exception. Useful when inspecting the JavaScript stack in conjunction with native stack and other runtime environment data. For when it all goes up in flames and you need the receipts. π₯-r,--require moduleβ Preload the specifiedmoduleat startup. Followsrequire()'s module resolution rules.modulemay be either a path to a file, or a node module name. Modules preloaded with--requirewill run before modules preloaded with--import. Modules are preloaded into the main thread as well as any worker threads, forked processes, or clustered processes. Everybody gets a copy, fr fr. π«Ά--runβ This runs a specified command from apackage.json's"scripts"object. If a missing"command"is provided, it will list the available scripts. Passing--runwithout a command lists the available scripts and exits with a non-zero exit code:
$ node --run
Available scripts are:
test: node --test
--run will traverse up to the root directory and finds a package.json file to run the command from. --run prepends ./node_modules/.bin for each ancestor of the current directory, to the PATH in order to execute the binaries from different folders where multiple node_modules directories are present, if ancestor-folder/node_modules/.bin is a directory. --run executes the command in the directory containing the related package.json. For example, the following command will run the test script of the package.json in the current folder:
$ node --run test
You can also pass arguments to the command. Any argument after -- will be appended to the script:
$ node --run test -- --verbose
Glow up your whole workflow, no cap. π
--secure-heap-min=nβ When using--secure-heap, the--secure-heap-minflag specifies the minimum allocation from the secure heap. The minimum value is2. The maximum value is the lesser of--secure-heapor2147483647. The value given must be a power of two. π§--secure-heap=nβ Initializes an OpenSSL secure heap ofnbytes. When initialized, the secure heap is used for selected types of allocations within OpenSSL during key generation and other operations. This is useful, for instance, to prevent sensitive information from leaking due to pointer overruns or underruns.
The secure heap is a fixed size and cannot be resized at runtime, so if used, it is important to select a large enough heap to cover all application uses. The heap size given must be a power of two. Any value less than 2 will disable the secure heap. The secure heap is disabled by default. The secure heap is not available on Windows. See CRYPTO_secure_malloc_init for more details. π
--snapshot-blob=pathβ When used with--build-snapshot,--snapshot-blobspecifies thepathwhere the generated snapshot blob is written to. If not specified, the generated blob is written tosnapshot.blobin the current working directory.
When used without --build-snapshot, --snapshot-blob specifies the path to the blob that is used to restore the application state.
When loading a snapshot, Node.js checks that:
- The version, architecture, and platform of the running Node.js binary are exactly the same as that of the binary that generates the snapshot.
- The V8 flags and CPU features are compatible with that of the binary that generates the snapshot.
If they don't match, Node.js refuses to load the snapshot and exits with status code 1. It's giving "we are NOT the same." π
--testβ Starts the Node.js command line test runner. This flag cannot be combined with--watch-path,--check,--eval,--interactive, or the inspector. See the documentation on running tests from the command line for more details. π§ͺ--test-concurrencyβ The maximum number of test files that the test runner CLI will execute concurrently. If--test-isolationis set to'none', this flag is ignored and concurrency is one. Otherwise, concurrency defaults toos.availableParallelism() - 1. Squad goals but make it threads. π--test-coverage-branches=thresholdβ Require a minimum percent of covered branches. If code coverage does not reach thethresholdspecified, the process will exit with code1. π--test-coverage-excludeβ Excludes specific files from code coverage using a glob pattern, which can match both absolute and relative file paths. This option may be specified multiple times to exclude multiple glob patterns. If both--test-coverage-excludeand--test-coverage-includeare provided, files must meet both criteria to be included in the coverage report. By default all the matching test files are excluded from the coverage report. Specifying this option will override the default behavior. π--test-coverage-functions=thresholdβ Require a minimum percent of covered functions. If code coverage does not reach thethresholdspecified, the process will exit with code1. π--test-coverage-includeβ Includes specific files in code coverage using a glob pattern, which can match both absolute and relative file paths. This option may be specified multiple times to include multiple glob patterns. If both--test-coverage-excludeand--test-coverage-includeare provided, files must meet both criteria to be included in the coverage report. π--test-coverage-include-allβ bestie this one is for the overachievers π it pulls in source files that never even got loaded by the test run and drops them in the coverage report anyway, where they show up with zero coverage (brutal, honestly). Candidate files get searched for in the current working directory, and they're subject to the exact same--test-coverage-includeand--test-coverage-excludefiltering as the rest of the report. no cap.--test-coverage-lines=thresholdβ sets a minimum percent of covered lines you're willing to accept. If your code coverage doesn't hit the threshold you specified, the process exits with code1. it's giving "we have standards" β¨--test-force-exitβ tells the test runner to just exit the process once all known tests have finished running, even if the event loop would otherwise stay alive being clingy. bye π--test-global-setup=moduleβ point at a module that gets evaluated before all tests are executed, and it can be used to set up global state or fixtures for your tests π see the documentation on global setup and teardown for more deets.--test-isolation=modeβ configures what kind of test isolation the runner uses. When mode is'process', each test file runs in its own separate child process. When mode is'none', all test files run in the same process as the test runner. The default isolation mode is'process'. This flag is ignored if the--testflag is not present (rude but true). See the test runner execution model section for more info π--test-name-patternβ a regular expression that configures the test runner to only execute tests whose name matches the pattern you gave it. See the documentation on filtering tests by name for more details. If you supply both--test-name-patternand--test-skip-pattern, tests have to satisfy both requirements in order to be executed β double gatekeeping, iconic πΈ--test-onlyβ configures the test runner to only execute top level tests that have theonlyoption set. This flag is not necessary when test isolation is disabled. iykyk.--test-random-seedβ sets the seed used to randomize test execution order. This applies to both test file execution order and queued tests within each file. Providing this flag enables randomization implicitly, even without--test-randomize. The value must be an integer between0and4294967295. This flag cannot be used with--watchor--test-rerun-failuresπ₯--test-randomizeβ randomizes test execution order. Applies to both test file execution order and queued tests within each file. This can help detect tests that rely on shared state or execution order (chaos as a diagnostic tool, we love to see it π¦). The seed used for randomization is printed in the test summary and can be reused with--test-random-seed. For detailed behavior and examples, see randomizing tests execution order. This flag cannot be used with--watchor--test-rerun-failures.--test-reporterβ a test reporter to use when running tests. See the documentation on test reporters for more details π--test-reporter-destinationβ the destination for the corresponding test reporter. See the documentation on test reporters for more details.--test-rerun-failuresβ a path to a file that lets the test runner persist the state of the test suite between runs. The runner uses this file to figure out which tests already succeeded or failed, so it can re-run the failed ones without having to re-run the entire test suite (the way that this saves you timeβ¦ obsessed π). The test runner will create this file if it does not exist. See the documentation on test reruns for more details.--test-shardβ test suite shard to execute, in the format of<index>/<total>, where:- index is a positive integer, the index of the divided parts.
- total is a positive integer, the total of divided parts.
This command divides all test files into total equal parts, and runs only the ones that happen to be in the index part. For example, to split your test suite into three parts, use this:
node --test --test-shard=1/3
node --test --test-shard=2/3
node --test --test-shard=3/3
--test-skip-patternβ a regular expression that configures the test runner to skip tests whose name matches the pattern you provided. See the documentation on filtering tests by name for more details. If both--test-name-patternand--test-skip-patternare supplied, tests must satisfy both requirements in order to be executed π--test-timeoutβ a number of milliseconds after which the test execution will fail. If unspecified, subtests inherit this value from their parent. The default value isInfinity(yes, infinite patience, bestie π).--test-update-snapshotsβ regenerates the snapshot files used by the test runner for snapshot testing. out with the old, in with the new β¨--throw-deprecationβ throw errors for deprecations. not a vibe warning, an actual throw π--title=titleβ setprocess.titleon startup.--tls-cipher-list=listβ specify an alternative default TLS cipher list. Requires Node.js to be built with crypto support (which is the default).--tls-keylog=fileβ log TLS key material to a file. The key material is in NSSSSLKEYLOGFILEformat and can be used by software (such as Wireshark) to decrypt the TLS traffic π
bestie that's literally the keys to the kingdom β treat that file like it's your diary, okay? π
--tls-max-v1.2β settls.DEFAULT_MAX_VERSIONto'TLSv1.2'. Use it to disable support for TLSv1.3.--tls-max-v1.3β set defaulttls.DEFAULT_MAX_VERSIONto'TLSv1.3'. Use it to enable support for TLSv1.3.--tls-min-v1.0β set defaulttls.DEFAULT_MIN_VERSIONto'TLSv1'. Use for compatibility with old TLS clients or servers.--tls-min-v1.1β set defaulttls.DEFAULT_MIN_VERSIONto'TLSv1.1'. Use for compatibility with old TLS clients or servers.--tls-min-v1.2β set defaulttls.DEFAULT_MIN_VERSIONto'TLSv1.2'. This is the default for 12.x and later, but the option is supported for compatibility with older Node.js versions.--tls-min-v1.3β set defaulttls.DEFAULT_MIN_VERSIONto'TLSv1.3'. Use to disable support for TLSv1.2, which is not as secure as TLSv1.3 π--trace-deprecationβ print stack traces for deprecations.--trace-envβ prints info about any access to environment variables done in the current Node.js instance to stderr, including:- The environment variable reads that Node.js does internally.
- Writes in the form of
process.env.KEY = "SOME VALUE". - Reads in the form of
process.env.KEY. - Definitions in the form of
Object.defineProperty(process.env, 'KEY', {...}). - Queries in the form of
Object.hasOwn(process.env, 'KEY'),process.env.hasOwnProperty('KEY')or'KEY' in process.env. - Deletions in the form of
delete process.env.KEY. - Enumerations in the form of
...process.envorObject.keys(process.env).
Only the names of the environment variables being accessed are printed. The values are not printed. To print the stack trace of the access, use --trace-env-js-stack and/or --trace-env-native-stack π΅οΈββοΈ
--trace-env-js-stackβ in addition to what--trace-envdoes, this prints the JavaScript stack trace of the access.--trace-env-native-stackβ in addition to what--trace-envdoes, this prints the native stack trace of the access.--trace-event-categoriesβ a comma separated list of categories that should be traced when trace event tracing is enabled using--trace-events-enabled.--trace-event-file-patternβ template string specifying the filepath for the trace event data. It supports${rotation}and${pid}π--trace-events-enabledβ enables the collection of trace event tracing information.--trace-exitβ prints a stack trace whenever an environment is exited proactively, i.e. invokingprocess.exit(). snitching on your own code, love that for you π--trace-require-module=modeβ prints info about usage of Loading ECMAScript modules usingrequire(). When mode is'all', all usage is printed. When mode is'no-node-modules', usage from thenode_modulesfolder is excluded.--trace-sigintβ prints a stack trace onSIGINT.--trace-sync-ioβ prints a stack trace whenever synchronous I/O is detected after the first turn of the event loop.--trace-tlsβ prints TLS packet trace information to stderr. This can be used to debug TLS connection problems π--trace-uncaughtβ print stack traces for uncaught exceptions. Usually the stack trace associated with the creation of anErroris printed, whereas this makes Node.js also print the stack trace associated with throwing the value (which does not need to be anErrorinstance).
heads up bestie: enabling this option may affect garbage collection behavior negatively π
--trace-warningsβ print stack traces for process warnings (including deprecations).--track-heap-objectsβ track heap object allocations for heap snapshots.--unhandled-rejections=modeβ this flag lets you change what should happen when an unhandled rejection occurs. Pick one of these modes:throw: emitunhandledRejection. If this hook is not set, raise the unhandled rejection as an uncaught exception. This is the default.strict: raise the unhandled rejection as an uncaught exception. If the exception is handled,unhandledRejectionis emitted.warn: always trigger a warning, no matter if theunhandledRejectionhook is set or not, but do not print the deprecation warning.warn-with-error-code: emitunhandledRejection. If this hook is not set, trigger a warning, and set the process exit code to1.none: silence all warnings π€«
If a rejection happens during the command line entry point's ES module static loading phase, it will always be raised as an uncaught exception. periodt.
--use-bundled-ca,--use-openssl-caβ okay so this is your classic pick-a-CA-store moment π You either use the bundled Mozilla CA store as supplied by your current Node.js version, or you use OpenSSL's default CA store. Which one is the default default? That's selectable at build-time, bestie. The bundled CA store, as supplied by Node.js, is a snapshot of the Mozilla CA store fixed at release time, and it is identical on all supported platforms. Rolling with the OpenSSL store lets the store be modified from the outside β for most Linux and BSD distributions, that store is maintained by the distribution maintainers and system administrators. Where the OpenSSL CA store lives depends on how the OpenSSL library is configured, but you can change it at runtime using environment variables. SeeSSL_CERT_DIRandSSL_CERT_FILE. β¨--use-env-proxyβ flip this on and Node.js parses theHTTP_PROXY,HTTPS_PROXYandNO_PROXYenvironment variables during startup, and routes requests through the proxy you specified. Use this only with proxies that are trusted and authorized for the deployment, no cap. Proxy support is meant for reaching external networks through authorized proxy servers β like when a firewall requires one. It is not for hiding traffic or evading network policy, and that's on periodt. See Built-in Proxy Support. This is equivalent to setting theNODE_USE_ENV_PROXY=1environment variable, and when both are set,--use-env-proxytakes precedence. π--use-largepages=modeβ plot twist bestie: this option is no longer supported and is a total no-op π It used to re-map the Node.js static code to large memory pages at startup. It still accepts the following values for compatibility though:off: no mapping will be attempted. This is the default.on: no mapping will be attempted and a message will be printed to standard error stating it's no longer supported.silent: same asoff.
--use-system-caβ Node.js uses the trusted CA certificates present in the system store along with the--use-bundled-caoption and theNODE_EXTRA_CA_CERTSenvironment variable. π¦
On platforms other than Windows and macOS, this loads certificates from the directory and file trusted by OpenSSL, similar to --use-openssl-ca, with the difference being that it caches the certificates after first load.
On Windows and macOS, the certificate trust policy is similar to Chromium's policy for locally trusted certificates, but with some differences. On macOS, the following settings are respected:
- Default and System Keychains.Bl -bullet
- Trust:.Bl -bullet
- Any certificate where the βWhen using this certificateβ flag is set to βAlways Trustβ or
- Any certificate where the βSecure Sockets Layer (SSL)β flag is set to βAlways Trustβ.
The certificate must also be valid, with "X.509 Basic Policy" set to βAlways Trustβ.
On Windows, the following settings are respected:
- Local Machine (accessed via certlm.msc).Bl -bullet
- Trust:.Bl -bullet
- Trusted Root Certification Authorities
- Trusted People
- Enterprise Trust -> Enterprise -> Trusted Root Certification Authorities
- Enterprise Trust -> Enterprise -> Trusted People
- Enterprise Trust -> Group Policy -> Trusted Root Certification Authorities
- Enterprise Trust -> Group Policy -> Trusted People
- Current User (accessed via certmgr.msc).Bl -bullet
- Trust:.Bl -bullet
- Trusted Root Certification Authorities
- Enterprise Trust -> Group Policy -> Trusted Root Certification Authorities
On Windows and macOS, Node.js would check that the user settings for the trusted certificates do not forbid them for TLS server authentication before using them. Node.js currently does not support distrust/revocation of certificates from another source based on system settings.
On other systems, Node.js loads certificates from the default certificate file (typically /etc/ssl/cert.pem) and default certificate directory (typically /etc/ssl/certs) that the version of OpenSSL that Node.js links to respects. This typically works with the convention on major Linux distributions and other Unix-like systems. If the overriding OpenSSL environment variables (typically SSL_CERT_FILE and SSL_CERT_DIR, depending on the configuration of the OpenSSL that Node.js links to) are set, the specified paths will be used to load certificates instead. These environment variables can be used as workarounds if the conventional paths used by the version of OpenSSL Node.js links to are not consistent with the system configuration that the users have for some reason.
Okay next up, a few quick ones that are literally just one-liners πΈ
- Print V8 command-line options.
- Set V8's thread pool size which will be used to allocate background jobs. If set to
0then Node.js will choose an appropriate size of the thread pool based on an estimate of the amount of parallelism. The amount of parallelism refers to the number of computations that can be carried out simultaneously in a given machine. In general, it's the same as the amount of CPUs, but it may diverge in environments such as VMs or containers. - Print node's version. π
--vfs-load=source <string>β source is a directory or an archive file to mount and run. Requires--experimental-vfs. May be given at most once. π§
Mounts source as a virtual file system (node:vfs), and runs the entry point and all subsequent require()/import resolution against that mount rather than the real file system. The mount is placed at a reserved mount point assigned by Node.js, so it never shadows real paths and no target can be chosen.
The entry point is taken from the mount the same way node <directory> takes one: the mount's own package.json "main", or index.js. Any positional command-line argument is the program's own (available from process.argv[2] onward), never an entry-point override. process.argv[1] reports source rather than the reserved mount point, since the mount point is an opaque implementation detail.
The provider backing a source is chosen from the source itself rather than from its file name:
- A directory is mounted with a
RealFSProviderrooted there. - A file whose bytes are a ZIP archive is mounted with a
ZipProvider, so an archive can carry any name.
Providers registered with vfs.registerProvider() (typically from a module preloaded with --require or --import) are consulted first, in reverse registration order, and may claim directories as well as files. If no provider claims the source, Node.js exits with an error.
In worker threads --vfs-load mounts but does not load: a worker inherits the mount and runs its own entry point, which may itself live in the mount. The source is mounted at the same reserved mount point in every thread that mounts it, whatever else that thread mounts, so a path into the mount means the same thing in all of them.
A worker created with its own execArgv inherits none of the parent's options, and so does not mount the source at all. To run a script from the mount, such a worker must be given the same options again, --experimental-vfs and --vfs-load; without them, that thread has no mount for the script to come from, and the worker fails to load it. --experimental-vfs is also what makes node:vfs available to the worker's own code. A worker whose script comes from anywhere else, such as the real file system, needs nothing added. π«Ά
--vfs-load is not permitted in NODE_OPTIONS: which entry point runs is the command line's decision, and the environment must not be able to redirect it. π
$ node --experimental-vfs --vfs-load=app.zip
--watchβ starts Node.js in watch mode. π When in watch mode, changes in the watched files cause the Node.js process to restart. By default, watch mode will watch the entry point and any required or imported module. Use--watch-pathto specify what paths to watch. This flag cannot be combined with--check,--eval,--interactive, or the REPL.
Note: The--watchflag requires a file path as an argument and is incompatible with--runor inline script input, as--runtakes precedence and ignores watch mode. If no file is provided, Node.js will exit with status code9. π
node --watch index.js
--watch-kill-signalβ customizes the signal sent to the process on watch mode restarts.
node --watch --watch-kill-signal SIGINT test.js
--watch-pathβ starts Node.js in watch mode and specifies what paths to watch. When in watch mode, changes in the watched paths cause the Node.js process to restart. This will turn off watching of required or imported modules, even when used in combination with--watch. This flag cannot be combined with--check,--eval,--interactive,--test, or the REPL.
Note: Using--watch-pathimplicitly enables--watch, which requires a file path and is incompatible with--run, as--runtakes precedence and ignores watch mode.
node --watch-path=./src --watch-path=./tests index.js
This option is only supported on macOS and Windows. An ERR_FEATURE_UNAVAILABLE_ON_PLATFORM exception will be thrown when the option is used on a platform that does not support it.
--watch-preserve-outputβ disables the clearing of the console when watch mode restarts the process.
node --watch --watch-preserve-output test.js
- Automatically zero-fills all newly allocated
Bufferinstances. π
π ENVIRONMENT π
FORCE_COLOR [1, 2, 3]β theFORCE_COLORenvironment variable is used to enable ANSI colorized output. The value may be:1,true, or the empty string''indicate 16-color support,2to indicate 256-color support, or3to indicate 16 million-color support.
When FORCE_COLOR is used and set to a supported value, both the NO_COLOR, and NODE_DISABLE_COLORS environment variables are ignored. Any other value will result in colorized output being disabled. π
NODE_COMPILE_CACHEdir β enable the module compile cache for the Node.js instance. See the documentation of module compile cache for details. βNODE_COMPILE_CACHE_PORTABLE1β when set to1, the module compile cache can be reused across different directory locations as long as the module layout relative to the cache directory remains the same, and by any user (the cache subdirectory is not suffixed with the creating user's uid).NODE_COMPILE_CACHE_READONLY1β when set to1, the module compile cache only reads existing entries from its directory: nothing is written to it and it is not created if missing. πNODE_DEBUGmodule[,β¦] β','-separated list of core modules that should print debug information.NODE_DEBUG_NATIVEmodule[,β¦] β','-separated list of core C++ modules that should print debug information.NODE_DISABLE_COLORS1β when set, colors will not be used in the REPL.NODE_DISABLE_COMPILE_CACHE1β disable the module compile cache for the Node.js instance. See the documentation of module compile cache for details. π₯
π NODE_EXTRA_CA_CERTS file
Okay bestie, this one is about adding extra trusted certs. When set, the well known "root" CAs (like VeriSign) will be extended with the extra certificates in file. That file should consist of one or more trusted certificates in PEM format. A message will be emitted (once) with process.emitWarning() if the file is missing or malformed, but any errors are otherwise ignored. Also, neither the well known nor extra certificates are used when the ca options property is explicitly specified for a TLS or HTTPS client or server. This environment variable is ignored when node runs as setuid root or has Linux file capabilities set. And FYI: the NODE_EXTRA_CA_CERTS environment variable is only read when the Node.js process is first launched. Changing the value at runtime using process.env.NODE_EXTRA_CA_CERTS has no effect on the current process. Periodt. π
π§ NODE_ICU_DATA file
Data path for ICU (Intl object) data. Will extend linked-in data when compiled with small-icu support. β¨
π NODE_NO_WARNINGS 1
When set to 1, process warnings are silenced. Thatβs it. No cap. π€«
π NODE_OPTIONS options...
Okay so this is the big one: a space-separated list of command-line options. The options... are interpreted before command-line options, so command-line options will override or compound after anything in options.... Node.js will exit with an error if an option that is not allowed in the environment is used, such as -p or a script file. If an option value contains a space, it can be escaped using double quotes:
NODE_OPTIONS='--require "./my path/file.js"'
A singleton flag passed as a command-line option will override the same flag passed into NODE_OPTIONS:
# The inspector will be available on port 5555
NODE_OPTIONS='--inspect=localhost:4444' node --inspect=localhost:5555
A flag that can be passed multiple times will be treated as if its NODE_OPTIONS instances were passed first, and then its command-line instances afterwards:
NODE_OPTIONS='--require "./a.js"' node --require "./b.js"
# is equivalent to:
node --require "./a.js" --require "./b.js"
Node.js options that are allowed are in the following list. If an option supports both --XX and --no-XX variants, they are both supported but only one is included in the list below. π
--allow-addons--allow-child-process--allow-ffi--allow-fs-read--allow-fs-vfs--allow-fs-write--allow-inspector--allow-net--allow-openssl-store--allow-wasi--allow-worker--bench-isolation--bench-name-pattern--bench-reporter-destination--bench-reporter--bench-samples--bench-warmup--conditions,-C--cpu-prof-dir--cpu-prof-interval--cpu-prof-name--cpu-prof--diagnostic-dir--disable-proto--disable-sigusr1--disable-warning--disable-wasm-trap-handler--dns-result-order--enable-fips-indicator-events--enable-fips--enable-network-family-autoselection--enable-source-maps--entry-url--experimental-abortcontroller--experimental-addon-modules--experimental-bench--experimental-detect-module--experimental-dtls--experimental-eventsource--experimental-import-meta-resolve--experimental-import-text--experimental-json-modules--experimental-loader--experimental-modules--experimental-package-map--experimental-print-required-tla--experimental-quic--experimental-require-module--experimental-shadow-realm--experimental-specifier-resolution--experimental-stream-iter--experimental-test-isolation--experimental-top-level-await--experimental-vfs--experimental-vm-modules--experimental-wasi-unstable-preview1--experimental-web-worker--force-context-aware--force-fips--force-node-api-uncaught-exceptions-policy--frozen-intrinsics--heap-prof-dir--heap-prof-interval--heap-prof-name--heap-prof--heapsnapshot-near-heap-limit--heapsnapshot-signal--http-parser--icu-data-dir--import--input-type--insecure-http-parser--inspect-brk--inspect-port,--debug-port--inspect-publish-uid--inspect-wait--inspect--localstorage-file--max-http-header-size--max-old-space-size-percentage--network-family-autoselection-attempt-timeout--no-addons--no-async-context-frame--no-deprecation--no-experimental-ffi--no-experimental-global-navigator--no-experimental-repl-await--no-experimental-sqlite--no-experimental-strip-types--no-experimental-websocket--no-experimental-webstorage--no-extra-info-on-fatal-exception--no-force-async-hooks-checks--no-global-search-paths--no-network-family-autoselection--no-strip-types--no-warnings--no-webstorage--no-worker-snapshot--node-memory-debug--openssl-config--openssl-legacy-provider--openssl-shared-config--pending-deprecation--permission-audit--permission--preserve-symlinks-main--preserve-symlinks--prof-process--redirect-warnings--report-compact--report-dir,--report-directory--report-exclude-env--report-exclude-network--report-filename--report-on-fatalerror--report-on-signal--report-signal--report-uncaught-exception--require-module--require,-r--secure-heap-min--secure-heap--snapshot-blob--test-coverage-branches--test-coverage-exclude--test-coverage-functions--test-coverage-include-all--test-coverage-include--test-coverage-lines--test-global-setup--test-isolation--test-name-pattern--test-only--test-random-seed--test-randomize--test-reporter-destination--test-reporter--test-rerun-failures--test-shard--test-skip-pattern--throw-deprecation--title--tls-cipher-list--tls-keylog--tls-max-v1.2--tls-max-v1.3--tls-min-v1.0--tls-min-v1.1--tls-min-v1.2--tls-min-v1.3--trace-deprecation--trace-env-js-stack--trace-env-native-stack--trace-env--trace-event-categories--trace-event-file-pattern--trace-events-enabled--trace-exit--trace-require-module--trace-sigint--trace-sync-io--trace-tls--trace-uncaught--trace-warnings--track-heap-objects--unhandled-rejections--use-bundled-ca--use-env-proxy--use-largepages--use-openssl-ca--use-system-ca--v8-pool-size--watch-kill-signal--watch-path--watch-preserve-output--watch--zero-fill-buffers
V8 options that are allowed are:
--abort-on-uncaught-exception--disallow-code-generation-from-strings--enable-etw-stack-walking--expose-gc--interpreted-frames-native-stack--jitless--max-heap-size--max-old-space-size--max-semi-space-size--perf-basic-prof-only-functions--perf-basic-prof--perf-prof-unwinding-info--perf-prof--stack-trace-limit
--perf-basic-prof-only-functions, --perf-basic-prof, --perf-prof-unwinding-info, and --perf-prof are only available on Linux. --enable-etw-stack-walking is only available on Windows. π§πͺ
π¦ NODE_PATH path[:β¦]
A ':'-separated list of directories prefixed to the module search path. On Windows, this is a ';'-separated list instead. Slay that cross-platform vibe. π»β¨
NODE_PENDING_DEPRECATION = 1
Set it to 1 and Node starts dropping pending deprecation warnings π
. Okay so pending deprecations are basically runtime deprecations' chill cousin β same energy, except they're off by default and will NOT show up unless you either pass the --pending-deprecation command-line flag or set NODE_PENDING_DEPRECATION=1. It's giving selective "early warning" system, and it's literally there so devs can catch deprecated API usage before it becomes a whole thing π₯.
NODE_PENDING_PIPE_INSTANCES = instances
Sets how many pending pipe instance handles exist while the pipe server is waiting for connections. Windows only, bestie β don't come for me π«Ά.
NODE_PRESERVE_SYMLINKS = 1
Set to 1 and you're telling the module loader "preserve symbolic links when resolving and caching modules" β¨. Symlinks stay symlinks, no cap.
NODE_REDIRECT_WARNINGS = file
Set this and process warnings go into the given file instead of getting printed to stderr π. The file gets created if it doesn't exist, and gets appended to if it does. If something goes wrong while trying to write the warning to the file, the warning goes to stderr instead. This is equivalent to using the --redirect-warnings=file command-line flag.
NODE_REPL_EXTERNAL_MODULE = file
Path to a Node.js module that gets loaded in place of the built-in REPL π¦. Overriding this value to an empty string ('') will use the built-in REPL. Iconic.
NODE_REPL_HISTORY = file
Path to the file where your persistent REPL history lives πΈ. Default path is ~/.node_repl_history, which this variable overrides. Setting the value to an empty string ('' or ' ') disables persistent REPL history entirely β no receipts, no history, main character mystery vibe.
NODE_SKIP_PLATFORM_CHECK = value
If value equals '1', the check for a supported platform gets skipped during Node.js startup π. Real talk: Node.js might not execute correctly, and any issues you hit on unsupported platforms will not be fixed. You're on your own fr fr.
β οΈ That last bit is not a vibe β it's literally "we will not fix this." Proceed accordingly π.
NODE_TEST_CONTEXT = value
If value equals 'child', test reporter options get overridden and test output gets sent to stdout in the TAP format β¨. If it's any other value, Node.js makes no guarantees about the reporter format used or its stability. So, like, do with that what you will π.
NODE_TLS_REJECT_UNAUTHORIZED = value
If value equals '0', certificate validation is disabled for TLS connections π. This makes TLS β and HTTPS by extension β insecure. The use of this environment variable is strongly discouraged. I'm not being dramatic, the manpage is being dramatic, we're all being dramatic together. Do not.
NODE_USE_ENV_PROXY = 1
When enabled, Node.js parses the HTTP_PROXY, HTTPS_PROXY and NO_PROXY environment variables during startup, and routes requests through the specified proxy π§. Use this only with proxies that are trusted and authorized for the deployment, bestie. Proxy support is intended for reaching external networks through authorized proxy servers β for example when a firewall requires one. It is not for hiding traffic or evading network policy π.
See Built-in Proxy Support. This can also be enabled using the --use-env-proxy command-line flag, and when both are set, --use-env-proxy takes precedence π.
NODE_USE_SYSTEM_CA = 1
Node.js uses the trusted CA certificates present in the system store along with the --use-bundled-ca option and the NODE_EXTRA_CA_CERTS environment variable π. This can also be enabled using the --use-system-ca command-line flag, and when both are set, --use-system-ca takes precedence β.
NODE_V8_COVERAGE = dir
When set, Node.js begins outputting V8 JavaScript code coverage and Source Map data to the directory you passed as an argument (coverage info is written as JSON to files with a coverage prefix) π. NODE_V8_COVERAGE automatically propagates to subprocesses, which makes instrumenting apps that call the child_process.spawn() family of functions so much easier. It can be set to an empty string to prevent propagation π¦.
NO_COLOR = <any>
NO_COLOR is an alias for NODE_DISABLE_COLORS π
. The value of the environment variable is arbitrary β literally anything, we don't care, the vibes decide.
OPENSSL_CONF = file
Loads an OpenSSL configuration file on startup π. The file can be used as part of a FIPS mode configuration. If the variable is set to an empty value, Node.js starts without loading any OpenSSL configuration file β which is a way past a default configuration file that exists but cannot be read, for example when /etc/ssl is not accessible to the user Node.js runs as, which is otherwise fatal at startup π. No configuration is applied in that case, including any FIPS mode setup the file would have performed. And if the --openssl-config command-line option is used, the environment variable is ignored, and an empty value has no effect π«Ά.
SSL_CERT_DIR = dir
If --use-openssl-ca is enabled, or if --use-system-ca is enabled on platforms other than macOS and Windows, this overrides and sets OpenSSL's directory containing trusted certificates πΈ. Be aware that unless the child environment is explicitly set, this environment variable will be inherited by any child processes, and if they use OpenSSL, it may cause them to trust the same CAs as node π.
SSL_CERT_FILE = file
If --use-openssl-ca is enabled, or if --use-system-ca is enabled on platforms other than macOS and Windows, this overrides and sets OpenSSL's file containing trusted certificates πΈ. Same heads-up as above, bestie: unless the child environment is explicitly set, this variable gets inherited by any child processes, and if they use OpenSSL, it may cause them to trust the same CAs as node π.
TZ
The TZ environment variable specifies the timezone configuration π. Node.js doesn't support all the various ways TZ is handled in other environments, but it does support basic timezone IDs β such as 'Etc/UTC', 'Europe/Paris', or 'America/New_York'. It may support a few other abbreviations or aliases, but these are strongly discouraged and not guaranteed. Periodt.
$ TZ=Europe/Dublin node -pe "new Date().toString()"
Wed May 12 2021 20:30:48 GMT+0100 (Irish Standard Time)
UV_THREADPOOL_SIZE = size
Sets the number of threads used in libuv's threadpool to size threads π§΅. Asynchronous system APIs are used by Node.js whenever possible, but where they don't exist, libuv's threadpool is used to create asynchronous node APIs based on synchronous system APIs. The Node.js APIs that use the threadpool are:
- all
fsAPIs, other than the file watcher APIs and those that are explicitly synchronous - asynchronous
cryptoAPIs such ascrypto.pbkdf2(),crypto.scrypt(),crypto.randomBytes(),crypto.randomFill(),crypto.generateKeyPair() dns.lookup()- all
zlibAPIs, other than those that are explicitly synchronous
Because libuv's threadpool has a fixed size, it means that if for whatever reason any of these APIs takes a long time, other (seemingly unrelated) APIs that run in libuv's threadpool will experience degraded performance π. To mitigate this, one potential solution is to increase the size of libuv's threadpool by setting the 'UV_THREADPOOL_SIZE' environment variable to a value greater than 4 (its current default value).
β οΈ Fair warning though: setting this from inside the process using process.env.UV_THREADPOOL_SIZE=size is not guaranteed to work, because the threadpool would have been created as part of the runtime initialisation, way before user code is run. So like... set it in your actual environment, bestie π
.
For more information, see the libuv threadpool documentation.
π BUGS
Bugs are tracked in GitHub Issues: https://github.com/nodejs/node/issues β come through, report responsibly π«Ά.
Β©οΈ COPYRIGHT
Copyright Node.js contributors. Node.js is available under the MIT license π.
Node.js also includes external libraries that are available under a variety of licenses. See https://github.com/nodejs/node/blob/HEAD/LICENSE for the full license text.
π SEE ALSO
- Website: https://nodejs.org/
- Documentation: https://nodejs.org/api/
- GitHub repository and issue tracker: https://github.com/nodejs/node
And that's a wrap on NODE(1), bestie ππ β this page is dated $Mdocdate$ and it's the NODE(1) manual, so go forth, read your env vars, and please leave NODE_TLS_REJECT_UNAUTHORIZED alone. Slay responsibly πβ¨
π¦ where this page comes from
- alpine 3.24: nodejs-current-doc 26.12.1-r0 Β· MIT
- arch rolling: nodejs 26.13.0-1 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms