Node.js v26.11.1 documentation
- Node.js v26.11.1
- Table of contents
- Command-line API
- Synopsis
- Program entry point
- Options
-----abort-on-uncaught-exception--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--bench-isolation=mode--bench-name-pattern=pattern--bench-reporter-destination=destination--bench-reporter=reporter--bench-samples=count--bench-warmup=count--build-sea=config--build-snapshot--build-snapshot-config-c,--check--completion-bash-C condition,--conditions=condition--cpu-prof--cpu-prof-dir--cpu-prof-interval--cpu-prof-name--diagnostic-dir=directory--disable-proto=mode--disable-sigusr1--disable-warning=code-or-type--disable-wasm-trap-handler--disallow-code-generation-from-strings--dns-result-order=order--enable-fips--enable-fips-indicator-events--enable-source-maps--entry-url--env-file-if-exists=file--env-file=file-e,--eval "script"--experimental-addon-modules--experimental-bench--experimental-config-file=path,--experimental-config-file--experimental-default-config-file--experimental-dtls--experimental-eventsource--experimental-import-meta-resolve--experimental-import-text--experimental-inspector-network-resource--experimental-loader=module--experimental-network-inspection--experimental-package-map=<path>--experimental-print-required-tla--experimental-quic--experimental-sea-config--experimental-shadow-realm--experimental-storage-inspection--experimental-stream-iter--experimental-test-coverage--experimental-test-module-mocks--experimental-test-tag-filter='<expr>'--experimental-vfs--experimental-vm-modules--experimental-wasi-unstable-preview1--experimental-web-worker--experimental-worker-inspection--force-context-aware--force-fips[=mode]--force-node-api-uncaught-exceptions-policy--frozen-intrinsics--heap-prof--heap-prof-dir--heap-prof-interval--heap-prof-name--heapsnapshot-near-heap-limit=max_count--heapsnapshot-signal=signal-h,--help--icu-data-dir=file--import=module--input-type=type--insecure-http-parser--inspect-brk[=[host:]port]--inspect-port=[host:]port--inspect-publish-uid=stderr,http--inspect-wait[=[host:]port]--inspect[=[host:]port]-i,--interactive--jitless--localstorage-file=file--max-http-header-size=size--max-old-space-size-percentage=percentage--network-family-autoselection-attempt-timeout--no-addons--no-async-context-frame--no-deprecation--no-experimental-detect-module--no-experimental-ffi--no-experimental-global-navigator--no-experimental-repl-await--no-experimental-require-module--no-experimental-sqlite--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-require-module--no-strip-types--no-warnings--no-worker-snapshot--node-memory-debug--openssl-config=file--openssl-legacy-provider--openssl-shared-config--pending-deprecation--permission--permission-audit--preserve-symlinks--preserve-symlinks-main-p,--print "script"--process-timeout=duration--prof--prof-process--redirect-warnings=file--report-compact--report-dir=directory,--report-directory=directory--report-exclude-env--report-exclude-network--report-filename=filename--report-on-fatalerror--report-on-process-timeout--report-on-signal--report-signal=signal--report-uncaught-exception-r,--require module--run--secure-heap-min=n--secure-heap=n--snapshot-blob=path--test--test-concurrency--test-coverage-branches=threshold--test-coverage-exclude--test-coverage-functions=threshold--test-coverage-include--test-coverage-include-all--test-coverage-lines=threshold--test-force-exit--test-global-setup=module--test-isolation=mode--test-name-pattern--test-only--test-random-seed--test-randomize--test-reporter--test-reporter-destination--test-rerun-failures--test-shard--test-skip-pattern--test-timeout--test-update-snapshots--throw-deprecation--title=title--tls-cipher-list=list--tls-keylog=file--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--trace-env-js-stack--trace-env-native-stack--trace-event-categories--trace-event-file-pattern--trace-events-enabled--trace-exit--trace-require-module=mode--trace-sigint--trace-sync-io--trace-tls--trace-uncaught--trace-warnings--track-heap-objects--unhandled-rejections=mode--use-bundled-ca,--use-openssl-ca--use-env-proxy--use-largepages=mode--use-system-ca--v8-options--v8-pool-size=num-v,--version--vfs-load=source--watch--watch-kill-signal--watch-path--watch-preserve-output--zero-fill-buffers
- Environment variables
FORCE_COLOR=[1, 2, 3]NODE_COMPILE_CACHE=dirNODE_COMPILE_CACHE_PORTABLE=1NODE_COMPILE_CACHE_READONLY=1NODE_DEBUG=module[,…]NODE_DEBUG_NATIVE=module[,…]NODE_DISABLE_COLORS=1NODE_DISABLE_COMPILE_CACHE=1NODE_EXTRA_CA_CERTS=fileNODE_ICU_DATA=fileNODE_NO_WARNINGS=1NODE_OPTIONS=options...NODE_PATH=path[:…]NODE_PENDING_DEPRECATION=1NODE_PENDING_PIPE_INSTANCES=instancesNODE_PRESERVE_SYMLINKS=1NODE_REDIRECT_WARNINGS=fileNODE_REPL_EXTERNAL_MODULE=fileNODE_REPL_HISTORY=fileNODE_SKIP_PLATFORM_CHECK=valueNODE_TEST_CONTEXT=valueNODE_TLS_REJECT_UNAUTHORIZED=valueNODE_USE_ENV_PROXY=1NODE_USE_SYSTEM_CA=1NODE_V8_COVERAGE=dirNO_COLOR=<any>OPENSSL_CONF=fileSSL_CERT_DIR=dirSSL_CERT_FILE=fileTZUV_THREADPOOL_SIZE=size
- Useful V8 options
--abort-on-uncaught-exception--disallow-code-generation-from-strings--enable-etw-stack-walking--expose-gc--harmony-shadow-realm--heap-snapshot-on-oom--interpreted-frames-native-stack--jitless--max-heap-size--max-old-space-size=SIZE(in MiB)--max-semi-space-size=SIZE(in MiB)--perf-basic-prof--perf-basic-prof-only-functions--perf-prof--perf-prof-unwinding-info--prof--security-revert--stack-trace-limit=limit
- Console
- Class:
Consolenew Console(stdout[, stderr][, ignoreErrors])new Console(options)console.assert(value[, ...message])console.clear()console.count([label])console.countReset([label])console.debug(data[, ...args])console.dir(obj[, options])console.dirxml(...data)console.error([data][, ...args])console.group([...label])console.groupCollapsed()console.groupEnd()console.info([data][, ...args])console.log([data][, ...args])console.table(tabularData[, properties])console.time([label])console.timeEnd([label])console.timeLog([label][, ...data])console.trace([message][, ...args])console.warn([data][, ...args])
- Inspector only methods
- Class:
- Crypto
- Determining if crypto support is unavailable
- Asymmetric key types
- Class:
Certificate - Class:
Cipheriv - Class:
Decipheriv - Class:
DiffieHellmandiffieHellman.computeSecret(otherPublicKey[, inputEncoding][, outputEncoding])diffieHellman.generateKeys([encoding])diffieHellman.getGenerator([encoding])diffieHellman.getPrime([encoding])diffieHellman.getPrivateKey([encoding])diffieHellman.getPublicKey([encoding])diffieHellman.setPrivateKey(privateKey[, encoding])diffieHellman.setPublicKey(publicKey[, encoding])diffieHellman.verifyError
- Class:
DiffieHellmanGroup - Class:
ECDH- Static method:
ECDH.convertKey(key, curve[, inputEncoding[, outputEncoding[, format]]]) ecdh.computeSecret(otherPublicKey[, inputEncoding][, outputEncoding])ecdh.generateKeys([encoding[, format]])ecdh.getPrivateKey([encoding])ecdh.getPublicKey([encoding][, format])ecdh.setPrivateKey(privateKey[, encoding])ecdh.setPublicKey(publicKey[, encoding])
- Static method:
- Class:
Hash - Class:
Hmac - Class:
KeyObject - Class:
Mac - Class:
Sign - Class:
Verify - Class:
X509Certificatenew X509Certificate(buffer)x509.cax509.checkEmail(email[, options])x509.checkHost(name[, options])x509.checkIP(ip)x509.checkIssued(otherCert)x509.checkPrivateKey(privateKey)x509.fingerprintx509.fingerprint256x509.fingerprint512x509.infoAccessx509.issuerx509.issuerCertificatex509.keyUsagex509.publicKeyx509.rawx509.serialNumberx509.subjectx509.subjectAltNamex509.toJSON()x509.toLegacyObject()x509.toString()x509.validFromx509.validFromDatex509.validTox509.validToDatex509.signatureAlgorithmx509.signatureAlgorithmOidx509.verify(publicKey)
node:cryptomodule methods and propertiescrypto.argon2(algorithm, parameters, callback)crypto.argon2Sync(algorithm, parameters)crypto.checkPrime(candidate[, options], callback)crypto.checkPrimeSync(candidate[, options])crypto.constantscrypto.createCipheriv(algorithm, key, iv[, options])crypto.createDecipheriv(algorithm, key, iv[, options])crypto.createDiffieHellman(prime[, primeEncoding][, generator][, generatorEncoding])crypto.createDiffieHellman(primeLength[, generator])crypto.createDiffieHellmanGroup(name)crypto.createECDH(curveName)crypto.createHash(algorithm[, options])crypto.createHmac(algorithm, key[, options])crypto.createMac(algorithm, key[, options])crypto.createPrivateKey(key)crypto.createPublicKey(key)crypto.createSecretKey(key[, encoding])crypto.createSign(algorithm[, options])crypto.createVerify(algorithm[, options])crypto.decapsulate(key, ciphertext[, callback])crypto.diffieHellman(options[, callback])crypto.encapsulate(key[, callback])crypto.fipscrypto.generateKey(type, options, callback)crypto.generateKeyPair(type, options, callback)crypto.generateKeyPairSync(type, options)crypto.generateKeySync(type, options)crypto.generatePrime(size[, options], callback)crypto.generatePrimeSync(size[, options])crypto.getCipherInfo(nameOrNid[, options])crypto.getCiphers()crypto.getCurves()crypto.getDiffieHellman(groupName)crypto.getFips()crypto.getHashes()crypto.getMacs()crypto.getRandomValues(typedArray)crypto.hash(algorithm, data[, options])crypto.hkdf(digest, ikm, salt, info, keylen, callback)crypto.hkdfSync(digest, ikm, salt, info, keylen)crypto.parsePKCS12(bundle[, options])crypto.pbkdf2(password, salt, iterations, keylen, digest, callback)crypto.pbkdf2Sync(password, salt, iterations, keylen, digest)crypto.privateDecrypt(privateKey, buffer)crypto.privateEncrypt(privateKey, buffer)crypto.publicDecrypt(key, buffer)crypto.publicEncrypt(key, buffer)crypto.randomBytes(size[, callback])crypto.randomFill(buffer[, offset][, size], callback)crypto.randomFillSync(buffer[, offset][, size])crypto.randomInt([min, ]max[, callback])crypto.randomUUID([options])crypto.randomUUIDv7([options])crypto.scrypt(password, salt, keylen[, options], callback)crypto.scryptSync(password, salt, keylen[, options])crypto.secureHeapUsed()crypto.setEngine(engine[, flags])crypto.setFips(bool)crypto.sign(algorithm, data, key[, callback])crypto.subtlecrypto.timingSafeEqual(a, b)crypto.verify(algorithm, data, key, signature[, callback])crypto.webcrypto
- Notes
- Crypto constants
- Deprecated APIs
- Revoking deprecations
- List of deprecated APIs
- DEP0001:
http.OutgoingMessage.prototype.flush - DEP0002:
require('_linklist') - DEP0003:
_writableState.buffer - DEP0004:
CryptoStream.prototype.readyState - DEP0005:
Buffer()constructor - DEP0006:
child_processoptions.customFds - DEP0007: Replace
clusterworker.suicidewithworker.exitedAfterDisconnect - DEP0008:
require('node:constants') - DEP0009:
crypto.pbkdf2without digest - DEP0010:
crypto.createCredentials - DEP0011:
crypto.Credentials - DEP0012:
Domain.dispose - DEP0013:
fsasynchronous function without callback - DEP0014:
fs.readlegacy String interface - DEP0015:
fs.readSynclegacy String interface - DEP0016:
GLOBAL/root - DEP0017:
Intl.v8BreakIterator - DEP0018: Unhandled promise rejections
- DEP0019:
require('.')resolved outside directory - DEP0020:
Server.connections - DEP0021:
Server.listenFD - DEP0022:
os.tmpDir() - DEP0023:
os.getNetworkInterfaces() - DEP0024:
REPLServer.prototype.convertToContext() - DEP0025:
require('node:sys') - DEP0026:
util.print() - DEP0027:
util.puts() - DEP0028:
util.debug() - DEP0029:
util.error() - DEP0030:
SlowBuffer - DEP0031:
ecdh.setPublicKey() - DEP0032:
node:domainmodule - DEP0033:
EventEmitter.listenerCount() - DEP0034:
fs.exists(path, callback) - DEP0035:
fs.lchmod(path, mode, callback) - DEP0036:
fs.lchmodSync(path, mode) - DEP0037:
fs.lchown(path, uid, gid, callback) - DEP0038:
fs.lchownSync(path, uid, gid) - DEP0039:
require.extensions - DEP0040:
node:punycodemodule - DEP0041:
NODE_REPL_HISTORY_FILEenvironment variable - DEP0042:
tls.CryptoStream - DEP0043:
tls.SecurePair - DEP0044:
util.isArray() - DEP0045:
util.isBoolean() - DEP0046:
util.isBuffer() - DEP0047:
util.isDate() - DEP0048:
util.isError() - DEP0049:
util.isFunction() - DEP0050:
util.isNull() - DEP0051:
util.isNullOrUndefined() - DEP0052:
util.isNumber() - DEP0053:
util.isObject() - DEP0054:
util.isPrimitive() - DEP0055:
util.isRegExp() - DEP0056:
util.isString() - DEP0057:
util.isSymbol() - DEP0058:
util.isUndefined() - DEP0059:
util.log() - DEP0060:
util._extend() - DEP0061:
fs.SyncWriteStream - DEP0062:
node --debug - DEP0063:
ServerResponse.prototype.writeHeader() - DEP0064:
tls.createSecurePair() - DEP0065:
repl.REPL_MODE_MAGICandNODE_REPL_MODE=magic - DEP0066:
OutgoingMessage.prototype._headers, OutgoingMessage.prototype._headerNames - DEP0067:
OutgoingMessage.prototype._renderHeaders - DEP0068:
node debug - DEP0069:
vm.runInDebugContext(string) - DEP0070:
async_hooks.currentId() - DEP0071:
async_hooks.triggerId() - DEP0072:
async_hooks.AsyncResource.triggerId() - DEP0073: Several internal properties of
net.Server - DEP0074:
REPLServer.bufferedCommand - DEP0075:
REPLServer.parseREPLKeyword() - DEP0076:
tls.parseCertString() - DEP0077:
Module._debug() - DEP0078:
REPLServer.turnOffEditorMode() - DEP0079: Custom inspection function on objects via
.inspect() - DEP0080:
path._makeLong() - DEP0081:
fs.truncate()using a file descriptor - DEP0082:
REPLServer.prototype.memory() - DEP0083: Disabling ECDH by setting
ecdhCurvetofalse - DEP0084: requiring bundled internal dependencies
- DEP0085: AsyncHooks sensitive API
- DEP0086: Remove
runInAsyncIdScope - DEP0089:
require('node:assert') - DEP0090: Invalid GCM authentication tag lengths
- DEP0091:
crypto.DEFAULT_ENCODING - DEP0092: Top-level
thisbound tomodule.exports - DEP0093:
crypto.fipsis deprecated and replaced - DEP0094: Using
assert.fail()with more than one argument - DEP0095:
timers.enroll() - DEP0096:
timers.unenroll() - DEP0097:
MakeCallbackwithdomainproperty - DEP0098: AsyncHooks embedder
AsyncResource.emitBeforeandAsyncResource.emitAfterAPIs - DEP0099: Async context-unaware
node::MakeCallbackC++ APIs - DEP0100:
process.assert() - DEP0101:
--with-lttng - DEP0102: Using
noAssertinBuffer#(read|write)operations - DEP0103:
process.binding('util').is[...]typechecks - DEP0104:
process.envstring coercion - DEP0105:
decipher.finaltol - DEP0106:
crypto.createCipherandcrypto.createDecipher - DEP0107:
tls.convertNPNProtocols() - DEP0108:
zlib.bytesRead - DEP0109:
http,https, andtlssupport for invalid URLs - DEP0110:
vm.Scriptcached data - DEP0111:
process.binding() - DEP0112:
dgramprivate APIs - DEP0113:
Cipher.setAuthTag(),Decipher.getAuthTag() - DEP0114:
crypto._toBuf() - DEP0115:
crypto.prng(),crypto.pseudoRandomBytes(),crypto.rng() - DEP0116: Legacy URL API
- DEP0117: Native crypto handles
- DEP0118:
dns.lookup()support for a falsy host name - DEP0119:
process.binding('uv').errname()private API - DEP0120: Windows Performance Counter support
- DEP0121:
net._setSimultaneousAccepts() - DEP0122:
tlsServer.prototype.setOptions() - DEP0123: setting the TLS ServerName to an IP address
- DEP0124: using
REPLServer.rli - DEP0125:
require('node:_stream_wrap') - DEP0126:
timers.active() - DEP0127:
timers._unrefActive() - DEP0128: modules with an invalid
mainentry and anindex.jsfile - DEP0129:
ChildProcess._channel - DEP0130:
Module.createRequireFromPath() - DEP0131: Legacy HTTP parser
- DEP0132:
worker.terminate()with callback - DEP0133:
httpconnection - DEP0134:
process._tickCallback - DEP0135:
WriteStream.open()andReadStream.open()are internal - DEP0136:
httpfinished - DEP0137: Closing fs.FileHandle on garbage collection
- DEP0138:
process.mainModule - DEP0139:
process.umask()with no arguments - DEP0140: Use
request.destroy()instead ofrequest.abort() - DEP0141:
repl.inputStreamandrepl.outputStream - DEP0142:
repl._builtinLibs - DEP0143:
Transform._transformState - DEP0144:
module.parent - DEP0145:
socket.bufferSize - DEP0146:
new crypto.Certificate() - DEP0147:
fs.rmdir(path, { recursive: true }) - DEP0148: Folder mappings in
"exports"(trailing"/") - DEP0149:
http.IncomingMessage#connection - DEP0150: Changing the value of
process.config - DEP0151: Main index lookup and extension searching
- DEP0152: Extension PerformanceEntry properties
- DEP0153:
dns.lookupanddnsPromises.lookupoptions type coercion - DEP0154: RSA-PSS generate key pair options
- DEP0155: Trailing slashes in pattern specifier resolutions
- DEP0156:
.abortedproperty and'abort','aborted'event inhttp - DEP0157: Thenable support in streams
- DEP0158:
buffer.slice(start, end) - DEP0159:
ERR_INVALID_CALLBACK - DEP0160:
process.on('multipleResolves', handler) - DEP0161:
process._getActiveRequests()andprocess._getActiveHandles() - DEP0162:
fs.write(),fs.writeFileSync()coercion to string - DEP0163:
channel.subscribe(onMessage),channel.unsubscribe(onMessage) - DEP0164:
process.exit(code),process.exitCodecoercion to integer - DEP0165:
--trace-atomics-wait - DEP0166: Double slashes in imports and exports targets
- DEP0167: Weak
DiffieHellmanGroupinstances (modp1,modp2,modp5) - DEP0168: Unhandled exception in Node-API callbacks
- DEP0169: Insecure url.parse()
- DEP0170: Invalid port when using
url.parse() - DEP0171: Setters for
http.IncomingMessageheaders and trailers - DEP0172: The
asyncResourceproperty ofAsyncResourcebound functions - DEP0173: the
assert.CallTrackerclass - DEP0174: calling
promisifyon a function that returns aPromise - DEP0175:
util.toUSVString - DEP0176:
fs.F_OK,fs.R_OK,fs.W_OK,fs.X_OK - DEP0177:
util.types.isWebAssemblyCompiledModule - DEP0178:
dirent.path - DEP0179:
Hashconstructor - DEP0180:
fs.Statsconstructor - DEP0181:
Hmacconstructor - DEP0182: Short GCM authentication tags without explicit
authTagLength - DEP0183: OpenSSL engine-based APIs
- DEP0184: Instantiating
node:zlibclasses withoutnew - DEP0185: Instantiating
node:replclasses withoutnew - DEP0187: Passing invalid argument types to
fs.existsSync - DEP0188:
process.features.ipv6andprocess.features.uv - DEP0189:
process.features.tls_* - DEP0190: Passing
argstonode:child_processexecFile/spawnwithshelloption - DEP0191:
repl.builtinModules - DEP0192:
require('node:_tls_common')andrequire('node:_tls_wrap') - DEP0193:
require('node:_stream_*') - DEP0194: HTTP/2 priority signaling
- DEP0195: Instantiating
node:httpclasses withoutnew - DEP0196: Calling
node:child_processfunctions withoptions.shellas an empty string - DEP0197:
util.types.isNativeError() - DEP0198: Creating SHAKE-128 and SHAKE-256 digests without an explicit
options.outputLength - DEP0199:
require('node:_http_*') - DEP0200: Closing fs.Dir on garbage collection
- DEP0201: Passing
options.typetoDuplex.toWeb() - DEP0202:
Http1IncomingMessageandHttp1ServerResponseoptions of HTTP/2 servers - DEP0203: Passing
CryptoKeytonode:cryptoAPIs - DEP0204:
KeyObject.from()with non-extractableCryptoKey - DEP0205:
module.register() - DEP0206: Calling
digest()on an already-finalizedHmacinstance - DEP0208:
Server.prototype._listen2 - DEP0209: Using
AbortSignalto dispose of resources - DEP0210:
sqlite.DatabaseSync - DEP0211:
sqlite.StatementSync
- DEP0001:
- Diagnostics Channel
- Public API
- Overview
- Class:
Channel - Class:
RunStoresScope - Class:
TracingChanneltracingChannel.subscribe(subscribers)tracingChannel.unsubscribe(subscribers)tracingChannel.traceSync(fn[, context[, thisArg[, ...args]]])tracingChannel.tracePromise(fn[, context[, thisArg[, ...args]]])tracingChannel.traceCallback(fn[, position[, context[, thisArg[, ...args]]]])tracingChannel.hasSubscribers
- Class:
BoundedChannel - Class:
BoundedChannelScope - BoundedChannel Channels
- TracingChannel Channels
- Built-in Channels
- Console
- Crypto
- HTTP
- HTTP/2
- Event:
'http2.client.stream.created' - Event:
'http2.client.stream.start' - Event:
'http2.client.stream.error' - Event:
'http2.client.stream.finish' - Event:
'http2.client.stream.bodyChunkSent' - Event:
'http2.client.stream.bodySent' - Event:
'http2.client.stream.close' - Event:
'http2.server.stream.created' - Event:
'http2.server.stream.start' - Event:
'http2.server.stream.error' - Event:
'http2.server.stream.finish' - Event:
'http2.server.stream.close'
- Event:
- Modules
- NET
- UDP
- Process
- Web Locks
- Worker Thread
- SQLite
- Public API
- DNS
- Class:
dns.Resolver dns.getServers()dns.lookup(hostname[, options], callback)dns.lookupService(address, port, callback)dns.resolve(hostname[, rrtype], callback)dns.resolve4(hostname[, options], callback)dns.resolve6(hostname[, options], callback)dns.resolveAny(hostname, callback)dns.resolveCname(hostname, callback)dns.resolveCaa(hostname, callback)dns.resolveMx(hostname, callback)dns.resolveNaptr(hostname, callback)dns.resolveNs(hostname, callback)dns.resolvePtr(hostname, callback)dns.resolveSoa(hostname, callback)dns.resolveSrv(hostname, callback)dns.resolveTlsa(hostname, callback)dns.resolveTxt(hostname, callback)dns.reverse(ip, callback)dns.setDefaultResultOrder(order)dns.getDefaultResultOrder()dns.setServers(servers)- DNS promises API
- Class:
dnsPromises.Resolver resolver.cancel()dnsPromises.getServers()dnsPromises.lookup(hostname[, options])dnsPromises.lookupService(address, port)dnsPromises.resolve(hostname[, rrtype])dnsPromises.resolve4(hostname[, options])dnsPromises.resolve6(hostname[, options])dnsPromises.resolveAny(hostname)dnsPromises.resolveCaa(hostname)dnsPromises.resolveCname(hostname)dnsPromises.resolveMx(hostname)dnsPromises.resolveNaptr(hostname)dnsPromises.resolveNs(hostname)dnsPromises.resolvePtr(hostname)dnsPromises.resolveSoa(hostname)dnsPromises.resolveSrv(hostname)dnsPromises.resolveTlsa(hostname)dnsPromises.resolveTxt(hostname)dnsPromises.reverse(ip)dnsPromises.setDefaultResultOrder(order)dnsPromises.getDefaultResultOrder()dnsPromises.setServers(servers)
- Class:
- Error codes
- Implementation considerations
- Class:
- Domain
- DTLS
- Permission model
- DTLS vs TLS
dtls.listen(callback, options)dtls.connect(host, port[, options])dtls.createSecureContext([options])- Server Name Indication
- Denial of service
- Handshake timeout
- Pre-shared keys
- Session resumption
- Class:
DTLSSecureContext - Class:
DTLSEndpoint - Class:
DTLSEndpoint.StatsendpointStats.createdAtendpointStats.destroyedAtendpointStats.bytesReceivedendpointStats.bytesSentendpointStats.packetsReceivedendpointStats.packetsSentendpointStats.serverSessionsendpointStats.clientSessionsendpointStats.serverBusyCountendpointStats.serverRejectedCountendpointStats.serverRefusedCountendpointStats.isConnected
- Class:
DTLSSessionsession.send(data)session.close()session.destroy([error])session.destroyedsession.endpointsession.servernamesession.openedsession.closedsession.remoteAddresssession.protocolsession.ciphersession.peerCertificatesession.peerX509Certificatesession.sessionsession.reusedsession.authorizedsession.authorizationErrorsession.alpnProtocolsession.srtpProfilesession.statssession.exportKeyingMaterial(length, label[, context])- Callback properties
session[Symbol.asyncDispose]()
- Class:
DTLSSession.Stats - DTLS-SRTP example
- MTU considerations
- Inspector
- Promises API
- Callback API
- Common Objects
- Integration with DevTools
inspector.Network.dataReceived([params])inspector.Network.dataSent([params])inspector.Network.requestWillBeSent([params])inspector.Network.responseReceived([params])inspector.Network.loadingFinished([params])inspector.Network.loadingFailed([params])inspector.Network.webSocketCreated([params])inspector.Network.webSocketHandshakeResponseReceived([params])inspector.Network.webSocketClosed([params])inspector.NetworkResources.putinspector.DOMStorage.domStorageItemAddedinspector.DOMStorage.domStorageItemRemovedinspector.DOMStorage.domStorageItemUpdatedinspector.DOMStorage.domStorageItemsClearedinspector.DOMStorage.registerStorage
- Support of breakpoints
- Iterable Streams
- Concepts
- The
stream/itermodule - Sources
- Pipelines
- Push streams
- Duplex channels
- Consumers
- Utilities
- Multi-consumer
- Compression and decompression transforms
- Classic stream interop
- Protocol symbols
- Modules:
node:moduleAPI- Class:
Module module.builtinModulesmodule.createRequire(filename)module.findPackageJSON(specifier[, base])module.isBuiltin(moduleName)module.register(specifier[, parentURL][, options])module.registerHooks(options)module.stripTypeScriptTypes(code[, options])module.syncBuiltinESMExports()- Module compile cache
- Customization Hooks
- Synchronous customization hooks
- Asynchronous customization hooks
- Caveats of asynchronous customization hooks
- Registration of asynchronous customization hooks
- Chaining of asynchronous customization hooks
- Communication with asynchronous module customization hooks
- Asynchronous hooks accepted by
module.register() initialize()- Asynchronous
resolve(specifier, context, nextResolve) - Asynchronous
load(url, context, nextLoad)
- Examples
- Source Map Support
- Class:
- Modules: CommonJS modules
- Enabling
- Accessing the main module
- Package manager tips
- Loading ECMAScript modules using
require() - All together
- Caching
- Built-in modules
- Cycles
- File modules
- Folders as modules
- Loading from
node_modulesfolders - Loading from the global folders
- The module wrapper
- The module scope
- The
moduleobject - The
Moduleobject - Source map v3 support
- Modules: ECMAScript modules
- Modules: Packages
- Introduction
- Determining module system
- Package entry points
- Dual CommonJS/ES module packages
- Package maps
- Node.js
package.jsonfield definitions
- Net
- IPC support
- Class:
net.BlockListblockList.addAddress(address[, type])blockList.addAddresses(addresses[, type])blockList.addCIDR(cidr)blockList.addCIDRs(cidrs)blockList.addRange(start, end[, type])blockList.addSubnet(net, prefix[, type])blockList.check(address[, type])blockList.clear()blockList.fromJSON(value)BlockList.isBlockList(value)BlockList.PRIVATE_RANGESblockList.removeAddress(address[, type])blockList.removeCIDR(cidr)blockList.removeRange(start, end[, type])blockList.removeSubnet(net, prefix[, type])blockList.rulesblockList.sizeblockList.toJSON()
- Class:
net.SocketAddress - Class:
net.Servernew net.Server([options][, connectionListener])- Event:
'close' - Event:
'connection' - Event:
'error' - Event:
'listening' - Event:
'drop' server.address()server.close([callback])server[Symbol.asyncDispose]()server.getConnections(callback)server.listen()server.listeningserver.maxConnectionsserver.dropMaxConnectionserver.ref()server.unref()
- Class:
net.Socket- Transferring TCP handles to other threads
new net.Socket([options])- Event:
'close' - Event:
'connect' - Event:
'connectionAttempt' - Event:
'connectionAttemptFailed' - Event:
'connectionAttemptTimeout' - Event:
'data' - Event:
'drain' - Event:
'end' - Event:
'error' - Event:
'lookup' - Event:
'ready' - Event:
'timeout' socket.address()socket.autoSelectFamilyAttemptedAddressessocket.bufferSizesocket.bytesReadsocket.bytesWrittensocket.connect()socket.connectingsocket.destroy([error])socket.destroyedsocket.destroySoon()socket.end([data[, encoding]][, callback])socket.localAddresssocket.localPortsocket.localFamilysocket.pause()socket.pendingsocket.ref()socket.remoteAddresssocket.remoteFamilysocket.remotePortsocket.serversocket.resetAndDestroy()socket.resume()socket.setEncoding([encoding])socket.setKeepAlive()socket.setNoDelay([noDelay])socket.setTimeout(timeout[, callback])socket.getTypeOfService()socket.setTypeOfService(tos)socket.timeoutsocket.unref()socket.write(data[, encoding][, callback])socket.readyState
- Class:
net.BoundSocket net.connect()net.createConnection()net.createServer([options][, connectionListener])net.getDefaultAutoSelectFamily()net.setDefaultAutoSelectFamily(value)net.getDefaultAutoSelectFamilyAttemptTimeout()net.setDefaultAutoSelectFamilyAttemptTimeout(value)net.isIP(input)net.isIPv4(input)net.isIPv6(input)
- Node-API
- Writing addons in various programming languages
- Implications of ABI stability
- Building
- Usage
- Node-API version matrix
- Environment life cycle APIs
- Basic Node-API data types
- Error handling
- Object lifetime management
- Module registration
- Working with JavaScript values
- Enum types
- Object creation functions
napi_create_arraynapi_create_array_with_lengthnapi_create_arraybuffernapi_create_buffernapi_create_buffer_copynapi_create_datenapi_create_externalnapi_create_external_arraybuffernode_api_create_external_sharedarraybuffernapi_create_external_buffernapi_create_objectnode_api_create_object_with_propertiesnapi_create_symbolnode_api_symbol_fornapi_create_typedarraynode_api_create_buffer_from_arraybuffernapi_create_dataview
- Functions to convert from C types to Node-API
napi_create_int32napi_create_uint32napi_create_int64napi_create_doublenapi_create_bigint_int64napi_create_bigint_uint64napi_create_bigint_wordsnapi_create_string_latin1node_api_create_external_string_latin1napi_create_string_utf16node_api_create_external_string_utf16napi_create_string_utf8
- Functions to create optimized property keys
- Functions to convert from Node-API to C types
napi_get_array_lengthnapi_get_arraybuffer_infonapi_get_buffer_infonapi_get_prototypenapi_get_typedarray_infonapi_get_dataview_infonapi_get_date_valuenapi_get_value_boolnapi_get_value_doublenapi_get_value_bigint_int64napi_get_value_bigint_uint64napi_get_value_bigint_wordsnapi_get_value_externalnapi_get_value_int32napi_get_value_int64napi_get_value_string_latin1napi_get_value_string_utf8napi_get_value_string_utf16napi_get_value_uint32
- Functions to get global instances
- Working with JavaScript values and abstract operations
napi_coerce_to_boolnapi_coerce_to_numbernapi_coerce_to_objectnapi_coerce_to_stringnapi_typeofnapi_instanceofnapi_is_arraynapi_is_arraybuffernapi_is_buffernapi_is_datenapi_is_errornapi_is_typedarraynapi_is_dataviewnapi_strict_equalsnapi_detach_arraybuffernapi_is_detached_arraybuffernode_api_is_sharedarraybuffernode_api_create_sharedarraybuffer
- Working with JavaScript properties
- Structures
- Functions
napi_get_property_namesnapi_get_all_property_namesnapi_set_propertynapi_get_propertynapi_has_propertynapi_delete_propertynapi_has_own_propertynapi_set_named_propertynapi_get_named_propertynapi_has_named_propertynapi_set_elementnapi_get_elementnapi_has_elementnapi_delete_elementnapi_define_propertiesnapi_object_freezenapi_object_sealnode_api_set_prototype
- Working with JavaScript functions
- Object wrap
- Simple asynchronous operations
- Custom asynchronous operations
- Version management
- Memory management
- Promises
- Script execution
- libuv event loop
- Asynchronous thread-safe function calls
- Calling a thread-safe function
- Reference counting of thread-safe functions
- Deciding whether to keep the process running
napi_create_threadsafe_functionnapi_get_threadsafe_function_contextnapi_call_threadsafe_functionnapi_acquire_threadsafe_functionnapi_release_threadsafe_functionnapi_ref_threadsafe_functionnapi_unref_threadsafe_function
- Miscellaneous utilities
- SQLite
- Type conversion between JavaScript and SQLite
- Class:
Databasenew Database(path[, options])database.aggregate(name, options)database.close()database.loadExtension(path[, entryPoint])database.enableLoadExtension(allow)database.enableDefensive(active)database.location([dbName])database.exec(sql)database.function(name[, options], fn)database.setAuthorizer(callback)database.isOpendatabase.isTransactiondatabase.limitsdatabase.open()database.serialize([dbName])database.deserialize(buffer[, options])database.prepare(sql[, options])database.createTagStore([maxSize])database.createModule(name, options)database.createSession([options])database.applyChangeset(changeset[, options])database[Symbol.dispose]()
- Class:
Session - Class:
Statement- Binding parameters
statement.all([namedParameters][, ...anonymousParameters])statement.close()statement.columns()statement.expandedSQLstatement.get([namedParameters][, ...anonymousParameters])statement.iterate([namedParameters][, ...anonymousParameters])statement.resetStats()statement.run([namedParameters][, ...anonymousParameters])statement.setAllowBareNamedParameters(enabled)statement.setAllowUnknownNamedParameters(enabled)statement.setReturnArrays(enabled)statement.setReadBigInts(enabled)statement.sourceSQLstatement[Symbol.dispose]()statement.stat(counter)
- Class:
SQLTagStore sqlite.backup(sourceDb, path[, options])sqlite.constants
- Stream
- Organization of this document
- Types of streams
- API for stream consumers
- Writable streams
- Class:
stream.Writable- Event:
'close' - Event:
'drain' - Event:
'error' - Event:
'finish' - Event:
'pipe' - Event:
'unpipe' writable.cork()writable.destroy([error])writable.closedwritable.destroyedwritable.end([chunk[, encoding]][, callback])writable.setDefaultEncoding(encoding)writable.uncork()writable.writablewritable.writableAbortedwritable.writableEndedwritable.writableCorkedwritable.erroredwritable.writableFinishedwritable.writableHighWaterMarkwritable.writableLengthwritable.writableNeedDrainwritable.writableObjectModewritable[Symbol.asyncDispose]()writable.write(chunk[, encoding][, callback])
- Event:
- Class:
- Readable streams
- Two reading modes
- Three states
- Choose one API style
- Class:
stream.Readable- Event:
'close' - Event:
'data' - Event:
'end' - Event:
'error' - Event:
'pause' - Event:
'readable' - Event:
'resume' readable.destroy([error])readable.closedreadable.destroyedreadable.isPaused()readable.pause()readable.pipe(destination[, options])readable.read([size])readable.readablereadable.readableAbortedreadable.readableDidReadreadable.readableEncodingreadable.readableEndedreadable.erroredreadable.readableFlowingreadable.readableHighWaterMarkreadable.readableLengthreadable.readableObjectModereadable.resume()readable.setEncoding(encoding)readable.unpipe([destination])readable.unshift(chunk[, encoding])readable.wrap(stream)readable[Symbol.asyncIterator]()readable[Symbol.for('Stream.toAsyncStreamable')]()readable[Symbol.asyncDispose]()readable.compose(stream[, options])readable.iterator([options])readable.map(fn[, options])readable.filter(fn[, options])readable.forEach(fn[, options])readable.toArray([options])readable.some(fn[, options])readable.find(fn[, options])readable.every(fn[, options])readable.flatMap(fn[, options])readable.drop(limit[, options])readable.take(limit[, options])readable.reduce(fn[, initial[, options]])
- Event:
- Duplex and transform streams
stream.finished(stream[, options], callback)stream.pipeline(source[, ...transforms], destination, callback)stream.pipeline(streams, callback)stream.compose(...streams)stream.isDestroyed(stream)stream.isErrored(stream)stream.isReadable(stream)stream.isWritable(stream)stream.Readable.from(iterable[, options])stream.Readable.fromWeb(readableStream[, options])stream.Readable.isDisturbed(stream)stream.Readable.toWeb(streamReadable[, options])stream.Writable.fromWeb(writableStream[, options])stream.Writable.toWeb(streamWritable)stream.Duplex.from(src)stream.Duplex.fromWeb(pair[, options])stream.Duplex.toWeb(streamDuplex[, options])stream.addAbortSignal(signal, stream)stream.getDefaultHighWaterMark(objectMode)stream.setDefaultHighWaterMark(objectMode, value)
- Writable streams
- API for stream implementers
- Additional notes
- Test runner
- Subtests
- Rerunning failed tests
describe()andit()aliases- Skipping tests
- TODO tests
- Expecting tests to fail
onlytests- Filtering tests by name
- Test tags
- Extraneous asynchronous activity
- Watch mode
- Global setup and teardown
- Running tests from the command line
- Collecting code coverage
- Mocking
- Snapshot testing
- Test reporters
run([options])suite([name][, options][, fn])suite.skip([name][, options][, fn])suite.todo([name][, options][, fn])suite.only([name][, options][, fn])test([name][, options][, fn])test.skip([name][, options][, fn])test.todo([name][, options][, fn])test.only([name][, options][, fn])describe([name][, options][, fn])describe.skip([name][, options][, fn])describe.todo([name][, options][, fn])describe.only([name][, options][, fn])it([name][, options][, fn])it.skip([name][, options][, fn])it.todo([name][, options][, fn])it.only([name][, options][, fn])before([fn][, options])after([fn][, options])beforeEach([fn][, options])afterEach([fn][, options])assertsnapshot- Class:
MockFunctionContext - Class:
MockModuleContext - Class:
MockPropertyContext - Class:
MockTrackermock.fn([original[, implementation]][, options])mock.getter(object, methodName[, implementation][, options])mock.method(object, methodName[, implementation][, options])mock.module(specifier[, options])mock.property(object, propertyName[, value])mock.reset()mock.restoreAll()mock.setter(object, methodName[, implementation][, options])
- Class:
MockTimers - Class:
TestsStream- Event lifecycle
- Event:
'test:coverage' - Event:
'test:complete' - Event:
'test:dequeue' - Event:
'test:diagnostic' - Event:
'test:enqueue' - Event:
'test:fail' - Event:
'test:interrupted' - Event:
'test:log' - Event:
'test:pass' - Event:
'test:plan' - Event:
'test:start' - Event:
'test:stderr' - Event:
'test:stdout' - Event:
'test:summary' - Event:
'test:watch:drained' - Event:
'test:watch:restarted'
getTestContext()- Test instrumentation and OpenTelemetry
- Class:
TestContextcontext.before([fn][, options])context.beforeEach([fn][, options])context.after([fn][, options])context.afterEach([fn][, options])context.assertcontext.diagnostic(message)context.log(message[, data])context.filePathcontext.fullNamecontext.namecontext.passedcontext.errorcontext.attemptcontext.tagscontext.workerIdcontext.plan(count[,options])context.runOnly(shouldRunOnlyTests)context.signalcontext.skip([message])context.todo([message])context.test([name][, options][, fn])context.waitFor(condition[, options])
- Class:
SuiteContext
- TLS (SSL)
- Determining if crypto support is unavailable
- TLS/SSL concepts
- Modifying the default TLS cipher suite
- OpenSSL security level
- X509 certificate error codes
- Class:
tls.Server- Event:
'connection' - Event:
'keylog' - Event:
'newSession' - Event:
'OCSPRequest' - Event:
'resumeSession' - Event:
'secureConnection' - Event:
'tlsClientError' server.addContext(hostname, context)server.address()server.close([callback])server.getTicketKeys()server.listen()server.setSecureContext(options)server.setTicketKeys(keys)
- Event:
- Class:
tls.TLSSocketnew tls.TLSSocket(socket[, options])- Event:
'keylog' - Event:
'OCSPResponse' - Event:
'secure' - Event:
'secureConnect' - Event:
'session' tlsSocket.address()tlsSocket.alpnProtocoltlsSocket.authorizationErrortlsSocket.authorizedtlsSocket.disableRenegotiation()tlsSocket.enableTrace()tlsSocket.encryptedtlsSocket.exportKeyingMaterial(length, label[, context])tlsSocket.getCertificate()tlsSocket.getCipher()tlsSocket.getEphemeralKeyInfo()tlsSocket.getFinished()tlsSocket.getPeerCertificate([detailed])tlsSocket.getPeerFinished()tlsSocket.getPeerX509Certificate()tlsSocket.getProtocol()tlsSocket.getSession()tlsSocket.getSharedSigalgs()tlsSocket.getTLSTicket()tlsSocket.getX509Certificate()tlsSocket.isSessionReused()tlsSocket.localAddresstlsSocket.localPorttlsSocket.remoteAddresstlsSocket.remoteFamilytlsSocket.remotePorttlsSocket.renegotiate(options, callback)tlsSocket.servernametlsSocket.setKeyCert(context)tlsSocket.setMaxSendFragment(size)
tls.checkServerIdentity(hostname, cert)tls.connect(options[, callback])tls.connect(path[, options][, callback])tls.connect(port[, host][, options][, callback])tls.createSecureContext([options])tls.createServer([options][, secureConnectionListener])tls.setDefaultCACertificates(certs)tls.getCACertificates([type])tls.getCiphers()tls.getCertificateCompressionAlgorithms()tls.rootCertificatestls.DEFAULT_ECDH_CURVEtls.DEFAULT_MAX_VERSIONtls.DEFAULT_MIN_VERSIONtls.DEFAULT_CIPHERS
- TTY
- Class:
tty.ReadStream - Class:
tty.WriteStreamnew tty.ReadStream(fd[, options])new tty.WriteStream(fd)- Event:
'resize' writeStream.clearLine(dir[, callback])writeStream.clearScreenDown([callback])writeStream.columnswriteStream.cursorTo(x[, y][, callback])writeStream.getColorDepth([env])writeStream.getWindowSize()writeStream.hasColors([count][, env])writeStream.isTTYwriteStream.moveCursor(dx, dy[, callback])writeStream.rows
tty.isatty(fd)
- Class:
- UDP/datagram sockets
- Class:
dgram.Socket- Event:
'close' - Event:
'connect' - Event:
'error' - Event:
'listening' - Event:
'message' socket.addMembership(multicastAddress[, multicastInterface])socket.addSourceSpecificMembership(sourceAddress, groupAddress[, multicastInterface])socket.address()socket.bind([port][, address][, callback])socket.bind(options[, callback])socket.bindSync([options])socket.close([callback])socket[Symbol.asyncDispose]()socket.connect(port[, address][, callback])socket.connectSync(port[, address])socket.disconnect()socket.dropMembership(multicastAddress[, multicastInterface])socket.dropSourceSpecificMembership(sourceAddress, groupAddress[, multicastInterface])socket.getRecvBufferSize()socket.getSendBufferSize()socket.getSendQueueSize()socket.getSendQueueCount()socket.ref()socket.remoteAddress()socket.send(msg[, offset, length][, port][, address][, callback])socket.setBroadcast(flag)socket.setMulticastInterface(multicastInterface)socket.setMulticastLoopback(flag)socket.setMulticastTTL(ttl)socket.setRecvBufferSize(size)socket.setSendBufferSize(size)socket.setTTL(ttl)socket.unref()
- Event:
node:dgrammodule functions
- Class:
- URL
- URL strings and URL objects
- The WHATWG URL API
- Class:
URL - Class:
URLPattern - Class:
URLSearchParamsnew URLSearchParams()new URLSearchParams(string)new URLSearchParams(obj)new URLSearchParams(iterable)urlSearchParams.append(name, value)urlSearchParams.delete(name[, value])urlSearchParams.entries()urlSearchParams.forEach(fn[, thisArg])urlSearchParams.get(name)urlSearchParams.getAll(name)urlSearchParams.has(name[, value])urlSearchParams.keys()urlSearchParams.set(name, value)urlSearchParams.sizeurlSearchParams.sort()urlSearchParams.toString()urlSearchParams.values()urlSearchParams[Symbol.iterator]()
url.domainToASCII(domain)url.domainToUnicode(domain)url.fileURLToPath(url[, options])url.fileURLToPathBuffer(url[, options])url.format(URL[, options])url.pathToFileURL(path[, options])url.urlToHttpOptions(url)
- Class:
- Legacy URL API
- Percent-encoding in URLs
- Assert
- Strict assertion mode
- Legacy assertion mode
- Class:
assert.AssertionError - Class:
assert.Assert assert(value[, message])assert.deepEqual(actual, expected[, message])assert.deepStrictEqual(actual, expected[, message])assert.doesNotMatch(string, regexp[, message])assert.doesNotReject(asyncFn[, error][, message])assert.doesNotThrow(fn[, error][, message])assert.equal(actual, expected[, message])assert.fail([message])assert.ifError(value)assert.match(string, regexp[, message])assert.notDeepEqual(actual, expected[, message])assert.notDeepStrictEqual(actual, expected[, message])assert.notEqual(actual, expected[, message])assert.notStrictEqual(actual, expected[, message])assert.ok(value[, message])assert.rejects(asyncFn[, error][, message])assert.strictEqual(actual, expected[, message])assert.throws(fn[, error][, message])assert.partialDeepStrictEqual(actual, expected[, message])
- Async hooks
- Terminology
- Overview
async_hooks.createHook(options)- Class:
AsyncHook - Promise execution tracking
- JavaScript embedder API
- Class:
AsyncLocalStorage
- Asynchronous context tracking
- Introduction
- Class:
AsyncLocalStoragenew AsyncLocalStorage([options])- Static method:
AsyncLocalStorage.bind(fn) - Static method:
AsyncLocalStorage.snapshot() asyncLocalStorage.disable()asyncLocalStorage.getStore()asyncLocalStorage.enterWith(store)asyncLocalStorage.nameasyncLocalStorage.run(store, callback[, ...args])asyncLocalStorage.exit(callback[, ...args])asyncLocalStorage.withScope(store)- Usage with
async/await - Troubleshooting: Context loss
- Class:
RunScope - Class:
AsyncResourcenew AsyncResource(type[, options])- Static method:
AsyncResource.bind(fn[, type[, thisArg]]) asyncResource.bind(fn[, thisArg])asyncResource.runInAsyncScope(fn[, thisArg, ...args])asyncResource.emitDestroy()asyncResource.asyncId()asyncResource.triggerAsyncId()- Using
AsyncResourcefor aWorkerthread pool - Integrating
AsyncResourcewithEventEmitter
- Benchmark runner
- Example benchmark
- Measurement model
- Reusable runners
- Command-line runner
- Benchmark reporters
createRunner([options])bench([name][, options], fn)suite([name][, options], fn)describe([name][, options], fn)before(fn)after(fn)beforeEach(fn)afterEach(fn)run([options])runFile(path[, options])- Class:
BenchContext - Class:
BenchmarksStream - Sample result
- Benchmark result
- Buffer
- Buffers and character encodings
- Buffers and TypedArrays
- Buffers and iteration
- Class:
Blob - Class:
Buffer- Static method:
Buffer.alloc(size[, fill[, encoding]]) - Static method:
Buffer.allocUnsafe(size[, alignment]) - Static method:
Buffer.allocUnsafeSlow(size[, alignment]) - Static method:
Buffer.byteLength(string[, encoding]) - Static method:
Buffer.stringLength(input[, encoding]) - Static method:
Buffer.compare(buf1, buf2) - Static method:
Buffer.concat(list[, totalLength]) - Static method:
Buffer.copyBytesFrom(view[, offset[, length]]) - Static method:
Buffer.from(array) - Static method:
Buffer.from(arrayBuffer[, byteOffset[, length]]) - Static method:
Buffer.from(buffer) - Static method:
Buffer.from(object[, offsetOrEncoding[, length]]) - Static method:
Buffer.from(string[, encoding]) - Static method:
Buffer.isBuffer(obj) - Static method:
Buffer.isEncoding(encoding) Buffer.poolSizebuf[index]buf.bufferbuf.byteOffsetbuf.compare(target[, targetStart[, targetEnd[, sourceStart[, sourceEnd]]]])buf.copy(target[, targetStart[, sourceStart[, sourceEnd]]])buf.entries()buf.equals(otherBuffer)buf.fill(value[, offset[, end]][, encoding])buf.includes(value[, start[, end]][, encoding])buf.indexOf(value[, start[, end]][, encoding])buf.keys()buf.lastIndexOf(value[, start[, end]][, encoding])buf.lengthbuf.parentbuf.readBigInt64BE([offset])buf.readBigInt64LE([offset])buf.readBigUInt64BE([offset])buf.readBigUInt64LE([offset])buf.readDoubleBE([offset])buf.readDoubleLE([offset])buf.readFloatBE([offset])buf.readFloatLE([offset])buf.readInt8([offset])buf.readInt16BE([offset])buf.readInt16LE([offset])buf.readInt32BE([offset])buf.readInt32LE([offset])buf.readIntBE(offset, byteLength)buf.readIntLE(offset, byteLength)buf.readUInt8([offset])buf.readUInt16BE([offset])buf.readUInt16LE([offset])buf.readUInt32BE([offset])buf.readUInt32LE([offset])buf.readUIntBE(offset, byteLength)buf.readUIntLE(offset, byteLength)buf.subarray([start[, end]])buf.slice([start[, end]])buf.swap16()buf.swap32()buf.swap64()buf.toJSON()buf.toString([encoding[, start[, end]]])buf.values()buf.write(string[, offset[, length]][, encoding])buf.writeBigInt64BE(value[, offset])buf.writeBigInt64LE(value[, offset])buf.writeBigUInt64BE(value[, offset])buf.writeBigUInt64LE(value[, offset])buf.writeDoubleBE(value[, offset])buf.writeDoubleLE(value[, offset])buf.writeFloatBE(value[, offset])buf.writeFloatLE(value[, offset])buf.writeInt8(value[, offset])buf.writeInt16BE(value[, offset])buf.writeInt16LE(value[, offset])buf.writeInt32BE(value[, offset])buf.writeInt32LE(value[, offset])buf.writeIntBE(value, offset, byteLength)buf.writeIntLE(value, offset, byteLength)buf.writeUInt8(value[, offset])buf.writeUInt16BE(value[, offset])buf.writeUInt16LE(value[, offset])buf.writeUInt32BE(value[, offset])buf.writeUInt32LE(value[, offset])buf.writeUIntBE(value, offset, byteLength)buf.writeUIntLE(value, offset, byteLength)new Buffer(array)new Buffer(arrayBuffer[, byteOffset[, length]])new Buffer(buffer)new Buffer(size)new Buffer(string[, encoding])
- Static method:
- Class:
File node:buffermodule APIsBuffer.from(),Buffer.alloc(), andBuffer.allocUnsafe()
- Child process
- Asynchronous process creation
- Synchronous process creation
- Class:
ChildProcess- Event:
'close' - Event:
'disconnect' - Event:
'error' - Event:
'exit' - Event:
'message' - Event:
'spawn' subprocess.channelsubprocess.connectedsubprocess.disconnect()subprocess.exitCodesubprocess.kill([signal])subprocess[Symbol.dispose]()subprocess.killedsubprocess.pidsubprocess.ref()subprocess.send(message[, sendHandle[, options]][, callback])subprocess.signalCodesubprocess.spawnargssubprocess.spawnfilesubprocess.stderrsubprocess.stdinsubprocess.stdiosubprocess.stdoutsubprocess.unref()
- Event:
maxBufferand Unicode- Shell requirements
- Default Windows shell
- Advanced serialization
- Cluster
- How it works
- Class:
Worker - Event:
'disconnect' - Event:
'exit' - Event:
'fork' - Event:
'listening' - Event:
'message' - Event:
'online' - Event:
'setup' cluster.disconnect([callback])cluster.fork([env])cluster.isMastercluster.isPrimarycluster.isWorkercluster.schedulingPolicycluster.settingscluster.setupMaster([settings])cluster.setupPrimary([settings])cluster.workercluster.workers
- OS
os.EOLos.availableParallelism()os.arch()os.constantsos.cpus()os.devNullos.endianness()os.freemem()os.getPriority([pid])os.homedir()os.hostname()os.loadavg()os.machine()os.networkInterfaces()os.platform()os.release()os.setPriority([pid, ]priority)os.tmpdir()os.totalmem()os.type()os.uptime()os.userInfo([options])os.version()- OS constants
- Path
- Windows vs. POSIX
path.basename(path[, suffix])path.delimiterpath.dirname(path)path.extname(path)path.format(pathObject)path.matchesGlob(path, pattern)path.isAbsolute(path)path.join([...paths])path.normalize(path)path.parse(path)path.posixpath.relative(from, to)path.resolve([...paths])path.seppath.toNamespacedPath(path)path.win32
- Performance measurement APIs
perf_hooks.performanceperformance.clearMarks([name])performance.clearMeasures([name])performance.clearResourceTimings([name])performance.eventLoopUtilization([utilization1[, utilization2]])performance.getEntries()performance.getEntriesByName(name[, type])performance.getEntriesByType(type)performance.mark(name[, options])performance.markResourceTiming(timingInfo, requestedUrl, initiatorType, global, cacheMode, bodyInfo, responseStatus[, deliveryType])performance.measure(name[, startMarkOrOptions[, endMark]])performance.nodeTimingperformance.now()performance.setResourceTimingBufferSize(maxSize)performance.timeOriginperformance.timerify(fn[, options])performance.toJSON()
- Class:
PerformanceEntry - Class:
PerformanceMark - Class:
PerformanceMeasure - Class:
PerformanceNodeEntry - Class:
PerformanceNodeTimingperformanceNodeTiming.bootstrapCompleteperformanceNodeTiming.environmentperformanceNodeTiming.idleTimeperformanceNodeTiming.loopExitperformanceNodeTiming.loopStartperformanceNodeTiming.nodeStartperformanceNodeTiming.uvMetricsInfoperformanceNodeTiming.uvMetricsInfoBigIntperformanceNodeTiming.v8Start
- Class:
PerformanceResourceTimingperformanceResourceTiming.workerStartperformanceResourceTiming.redirectStartperformanceResourceTiming.redirectEndperformanceResourceTiming.fetchStartperformanceResourceTiming.domainLookupStartperformanceResourceTiming.domainLookupEndperformanceResourceTiming.connectStartperformanceResourceTiming.connectEndperformanceResourceTiming.secureConnectionStartperformanceResourceTiming.requestStartperformanceResourceTiming.finalResponseHeadersStartperformanceResourceTiming.firstInterimResponseStartperformanceResourceTiming.responseStartperformanceResourceTiming.responseEndperformanceResourceTiming.transferSizeperformanceResourceTiming.encodedBodySizeperformanceResourceTiming.decodedBodySizeperformanceResourceTiming.renderBlockingStatusperformanceResourceTiming.contentTypeperformanceResourceTiming.contentEncodingperformanceResourceTiming.toJSON()
- Class:
PerformanceObserver - Class:
PerformanceObserverEntryList perf_hooks.createHistogram([options])perf_hooks.createSlidingWindowHistogram(options)perf_hooks.importHistogram(data)perf_hooks.eventLoopUtilization([utilization1[, utilization2]])perf_hooks.monitorEventLoopDelay([options])perf_hooks.timerify(fn[, options])- Class:
Histogramhistogram.burnRate(sloTarget)histogram.counthistogram.countBigInthistogram.ccdf(value)histogram.cdf(value)histogram.cliffsD(other)histogram.cohensD(other)histogram.countAt(value)histogram.diff(other)histogram.exceedshistogram.exceedsBigInthistogram.export()histogram.ewmaMeanhistogram.ewmaStddevhistogram.ewmaErrorRatehistogram.ksTest(other)histogram.kurtosishistogram.linearBuckets(stepSize)histogram.logBuckets(firstBucket, base)histogram.mannWhitneyTest(other)histogram.maxhistogram.maxBigInthistogram.meanhistogram.meanCI([options])histogram.minhistogram.minBigInthistogram.percentile(percentile)histogram.percentileBigInt(percentile)histogram.percentileCI(percentile[, options])histogram.percentileshistogram.percentilesBigInthistogram.percentilesAt(percentiles)histogram.qrde([options])histogram.reset()histogram.resetCounthistogram.skewnesshistogram.snapshot()histogram.stddevhistogram.welchTest(other[, options])
- Class:
ELDHistogram extends Histogram - Class:
RecordableHistogram extends Histogram - Class:
SlidingWindowHistogram - Histogram analysis examples
- Examples
- Permissions
- Process
- Process events
process.abort()process.addUncaughtExceptionCaptureCallback(fn)process.allowedNodeEnvironmentFlagsprocess.archprocess.argvprocess.argv0process.availableMemory()process.channelprocess.chdir(directory)process.configprocess.connectedprocess.constrainedMemory()process.cpuUsage([previousValue])process.cwd()process.debugPortprocess.disconnect()process.dlopen(module, filename[, flags])process.emitWarning(warning[, options])process.emitWarning(warning[, type[, code]][, ctor])process.envprocess.execArgvprocess.execPathprocess.execve(file[, args[, env]])process.exit([code])process.exitCodeprocess.features.cached_builtinsprocess.features.debugprocess.features.inspectorprocess.features.ipv6process.features.require_moduleprocess.features.tlsprocess.features.tls_alpnprocess.features.tls_ocspprocess.features.tls_sniprocess.features.typescriptprocess.features.uvprocess.finalization.register(ref, callback)process.finalization.registerBeforeExit(ref, callback)process.finalization.unregister(ref)process.getActiveResourcesInfo()process.getBuiltinModule(id)process.getegid()process.geteuid()process.getgid()process.getgroups()process.getuid()process.hasUncaughtExceptionCaptureCallback()process.hrtime([time])process.hrtime.bigint()process.initgroups(user, extraGroup)process.kill(pid[, signal])process.loadEnvFile(path)process.mainModuleprocess.memoryUsage()process.memoryUsage.rss()process.nextTick(callback[, ...args])process.noDeprecationprocess.permissionprocess.pidprocess.platformprocess.ppidprocess.ref(maybeRefable)process.releaseprocess.reportprocess.report.compactprocess.report.directoryprocess.report.filenameprocess.report.getReport([err])process.report.reportOnFatalErrorprocess.report.reportOnSignalprocess.report.reportOnUncaughtExceptionprocess.report.excludeEnvprocess.report.signalprocess.report.writeReport([filename][, err])
process.resourceUsage()process.send(message[, sendHandle[, options]][, callback])process.setegid(id)process.seteuid(id)process.setgid(id)process.setgroups(groups)process.setuid(id)process.setSourceMapsEnabled(val)process.setUncaughtExceptionCaptureCallback(fn)process.sourceMapsEnabledprocess.stderrprocess.stdinprocess.stdoutprocess.throwDeprecationprocess.threadCpuUsage([previousValue])process.titleprocess.traceDeprecationprocess.traceProcessWarningsprocess.umask()process.umask(mask)process.unref(maybeRefable)process.uptime()process.versionprocess.versions- Exit codes
- Readline
- Class:
InterfaceConstructor- Event:
'close' - Event:
'error' - Event:
'line' - Event:
'history' - Event:
'pause' - Event:
'resume' - Event:
'SIGCONT' - Event:
'SIGINT' - Event:
'SIGTSTP' rl.close()rl[Symbol.dispose]()rl.pause()rl.prompt([preserveCursor])rl.resume()rl.setPrompt(prompt)rl.getPrompt()rl.write(data[, key])rl[Symbol.asyncIterator]()rl.linerl.cursorrl.getCursorPos()
- Event:
- Promises API
- Callback API
readline.emitKeypressEvents(stream[, interface])- Example: Tiny CLI
- Example: Read file stream line-by-Line
- TTY keybindings
- Class:
- REPL
- Single executable applications
- Generating single executable applications with
--build-sea - Single-executable application API
- In the injected main script
- Module format of the injected main script
- Module loading in the injected main script
require()in the injected main script__filenameandmodule.filenamein the injected main script__dirnamein the injected main scriptimport.metain the injected main scriptimport()in the injected main script- Using native addons in the injected main script
- Notes
- Generating single executable applications with
- Util
util.callbackify(original)util.convertProcessSignalToExitCode(signal)util.debuglog(section[, callback])util.debug(section)util.deprecate(fn, msg[, code[, options]])util.debounce(fn, wait[, options])util.throttle(fn, limit, interval[, options])util.diff(actual, expected)util.format(format[, ...args])util.formatWithOptions(inspectOptions, format[, ...args])util.getCallSites([frameCount][, options])util.getSystemErrorName(err)util.getSystemErrorMap()util.getSystemErrorMessage(err)util.setTraceSigInt(enable)util.inherits(constructor, superConstructor)util.inspect(object[, options])util.inspect(object[, showHidden[, depth[, colors]]])util.isDeepStrictEqual(val1, val2[, options])util.isPartialDeepStrictEqual(val1, val2)util.markPromiseAsHandled(promise)- Class:
util.MIMEType - Class:
util.MIMEParams util.parseArgs([config])util.parseEnv(content)util.promisify(original)util.stripVTControlCharacters(str)util.styleText(format, text[, options])- Class:
util.TextDecoder - Class:
util.TextEncoder util.toUSVString(string)util.transferableAbortController()util.transferableAbortSignal(signal)util.aborted(signal, resource)util.typesutil.types.isAnyArrayBuffer(value)util.types.isArrayBufferView(value)util.types.isArgumentsObject(value)util.types.isArrayBuffer(value)util.types.isAsyncFunction(value)util.types.isBigInt64Array(value)util.types.isBigIntObject(value)util.types.isBigUint64Array(value)util.types.isBooleanObject(value)util.types.isBoxedPrimitive(value)util.types.isCryptoKey(value)util.types.isDataView(value)util.types.isDate(value)util.types.isExternal(value)util.types.isFloat16Array(value)util.types.isFloat32Array(value)util.types.isFloat64Array(value)util.types.isGeneratorFunction(value)util.types.isGeneratorObject(value)util.types.isInt8Array(value)util.types.isInt16Array(value)util.types.isInt32Array(value)util.types.isKeyObject(value)util.types.isMap(value)util.types.isMapIterator(value)util.types.isModuleNamespaceObject(value)util.types.isNativeError(value)util.types.isNumberObject(value)util.types.isPromise(value)util.types.isProxy(value)util.types.isRegExp(value)util.types.isSet(value)util.types.isSetIterator(value)util.types.isSharedArrayBuffer(value)util.types.isStringObject(value)util.types.isSymbolObject(value)util.types.isTypedArray(value)util.types.isUint8Array(value)util.types.isUint8ClampedArray(value)util.types.isUint16Array(value)util.types.isUint32Array(value)util.types.isWeakMap(value)util.types.isWeakSet(value)
- Deprecated APIs
- V8
v8.cachedDataVersionTag()v8.getHeapCodeStatistics()v8.getHeapSnapshot([options])v8.getHeapSpaceStatistics()v8.getHeapStatistics()v8.getCppHeapStatistics([detailLevel])v8.queryObjects(ctor[, options])v8.setFlagsFromString(flags)v8.stopCoverage()v8.takeCoverage()v8.writeHeapSnapshot([filename[,options]])v8.setHeapSnapshotNearHeapLimit(limit)- Serialization API
v8.serialize(value)v8.deserialize(buffer)- Class:
v8.Serializernew Serializer()serializer.writeHeader()serializer.writeValue(value)serializer.releaseBuffer()serializer.transferArrayBuffer(id, arrayBuffer)serializer.writeUint32(value)serializer.writeUint64(hi, lo)serializer.writeDouble(value)serializer.writeRawBytes(buffer)serializer._writeHostObject(object)serializer._getDataCloneError(message)serializer._getSharedArrayBufferId(sharedArrayBuffer)serializer._setTreatArrayBufferViewsAsHostObjects(flag)
- Class:
v8.Deserializernew Deserializer(buffer)deserializer.readHeader()deserializer.readValue()deserializer.transferArrayBuffer(id, arrayBuffer)deserializer.getWireFormatVersion()deserializer.readUint32()deserializer.readUint64()deserializer.readDouble()deserializer.readRawBytes(length)deserializer._readHostObject()
- Class:
v8.DefaultSerializer - Class:
v8.DefaultDeserializer
- Promise hooks
- Startup Snapshot API
- Class:
v8.GCProfiler - Class:
SyncCPUProfileHandle - Class:
SyncHeapProfileHandle - Class:
CPUProfileHandle - Class:
HeapProfileHandle v8.isStringOneByteRepresentation(content)v8.startCpuProfile([options])v8.startHeapProfile([options])v8.setHeapProfileNearHeapLimit(limit)
- Virtual File System
- Security
- Basic usage
vfs.create([provider][, options])vfs.registerProvider(entry)vfs.vfsBase()- Class:
VirtualFileSystem - The reserved root directory
- Module loader integration
- Use with Single Executable Applications
- Class:
VirtualProvider - Class:
MemoryProvider - Class:
RealFSProvider - Class:
ZipProvider - Implementation details
- VM (executing JavaScript)
- Class:
vm.Script - Class:
vm.Module - Class:
vm.SourceTextModule - Class:
vm.SyntheticModule - Type:
ModuleRequest vm.compileFunction(code[, params[, options]])vm.constantsvm.createContext([contextObject[, options]])vm.isContext(object)vm.measureMemory([options])vm.runInContext(code, contextifiedObject[, options])vm.runInNewContext(code[, contextObject[, options]])vm.runInThisContext(code[, options])- Example: Running an HTTP server within a VM
- What does it mean to "contextify" an object?
- Timeout interactions with asynchronous tasks and Promises
- Support of dynamic
import()in compilation APIs
- Class:
- Web Crypto API
- Modern Algorithms in the Web Cryptography API
- Secure Curves in the Web Cryptography API
- Examples
- Algorithm support
- Class:
Crypto - Class:
CryptoKey - Class:
CryptoKeyPair - Class:
SubtleCrypto- Static method:
SubtleCrypto.supports(operation, algorithm[, lengthOrAdditionalAlgorithm]) subtle.decapsulateBits(decapsulationAlgorithm, decapsulationKey, ciphertext)subtle.decapsulateKey(decapsulationAlgorithm, decapsulationKey, ciphertext, sharedKeyAlgorithm, extractable, keyUsages)subtle.decrypt(algorithm, key, data)subtle.deriveBits(algorithm, baseKey[, length])subtle.deriveKey(algorithm, baseKey, derivedKeyType, extractable, keyUsages)subtle.digest(algorithm, data)subtle.encapsulateBits(encapsulationAlgorithm, encapsulationKey)subtle.encapsulateKey(encapsulationAlgorithm, encapsulationKey, sharedKeyAlgorithm, extractable, keyUsages)subtle.encrypt(algorithm, key, data)subtle.exportKey(format, key)subtle.getPublicKey(key, keyUsages)subtle.generateKey(algorithm, extractable, keyUsages)subtle.importKey(format, keyData, algorithm, extractable, keyUsages)subtle.sign(algorithm, key, data)subtle.unwrapKey(format, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages)subtle.verify(algorithm, key, signature, data)subtle.wrapKey(format, key, wrappingKey, wrapAlgorithm)
- Static method:
- Algorithm parameters
- Class:
Algorithm - Class:
AeadParams - Class:
AesDerivedKeyParams - Class:
AesCbcParams - Class:
AesCtrParams - Class:
AesKeyAlgorithm - Class:
AesKeyGenParams - Class:
Argon2Params - Class:
ContextParams - Class:
CShakeParams - Class:
EcdhKeyDeriveParams - Class:
EcdsaParams - Class:
EcKeyAlgorithm - Class:
EcKeyGenParams - Class:
EcKeyImportParams - Class:
EncapsulatedBits - Class:
EncapsulatedKey - Class:
HkdfParams - Class:
HmacImportParams - Class:
HmacKeyAlgorithm - Class:
HmacKeyGenParams - Class:
KeyAlgorithm - Class:
KangarooTwelveParams - Class:
KmacImportParams - Class:
KmacKeyAlgorithm - Class:
KmacKeyGenParams - Class:
KmacParams - Class:
Pbkdf2Params - Class:
RsaHashedImportParams - Class:
RsaHashedKeyAlgorithm - Class:
RsaHashedKeyGenParams - Class:
RsaOaepParams - Class:
RsaPssParams - Class:
TurboShakeParams
- Class:
- Web Streams API
- Overview
- API
ReadableStreamTee(stream[, cloneForBranch2])- Class:
ReadableStreamnew ReadableStream([underlyingSource [, strategy]])readableStream.lockedreadableStream.cancel([reason])readableStream.getReader([options])readableStream.pipeThrough(transform[, options])readableStream.pipeTo(destination[, options])readableStream.tee()readableStream.values([options])- Async Iteration
- Transferring with
postMessage()
ReadableStream.from(iterable)- Class:
ReadableStreamDefaultReader - Class:
ReadableStreamBYOBReader - Class:
ReadableStreamDefaultController - Class:
ReadableByteStreamController - Class:
ReadableStreamBYOBRequest - Class:
WritableStream - Class:
WritableStreamDefaultWriternew WritableStreamDefaultWriter(stream)writableStreamDefaultWriter.abort([reason])writableStreamDefaultWriter.close()writableStreamDefaultWriter.closedwritableStreamDefaultWriter.desiredSizewritableStreamDefaultWriter.readywritableStreamDefaultWriter.releaseLock()writableStreamDefaultWriter.write([chunk])
- Class:
WritableStreamDefaultController - Class:
TransformStream - Class:
TransformStreamDefaultController - Class:
ByteLengthQueuingStrategy - Class:
CountQueuingStrategy - Class:
TextEncoderStream - Class:
TextDecoderStream - Class:
CompressionStream - Class:
DecompressionStream - Utility Consumers
- Worker threads
worker_threads.getEnvironmentData(key)worker_threads.isInternalThreadworker_threads.isMainThreadworker_threads.markAsUntransferable(object)worker_threads.isMarkedAsUntransferable(object)worker_threads.markAsUncloneable(object)worker_threads.moveMessagePortToContext(port, contextifiedSandbox)worker_threads.parentPortworker_threads.postMessageToThread(threadId, value[, transferList][, timeout])worker_threads.receiveMessageOnPort(port)worker_threads.resourceLimitsworker_threads.SHARE_ENVworker_threads.setEnvironmentData(key[, value])worker_threads.threadIdworker_threads.threadNameworker_threads.workerDataworker_threads.locks- Class:
BroadcastChannel extends EventTarget - Class:
MessageChannel - Class:
MessagePort - Class:
Workernew Worker(filename[, options])- Event:
'error' - Event:
'exit' - Event:
'message' - Event:
'messageerror' - Event:
'online' worker.cpuUsage([prev])worker.getHeapSnapshot([options])worker.getHeapStatistics()worker.performanceworker.postMessage(value[, transferList])worker.ref()worker.resourceLimitsworker.startCpuProfile([options])worker.startHeapProfile([options])worker.stderrworker.stdinworker.stdoutworker.terminate()worker.threadIdworker.threadNameworker.unref()worker[Symbol.asyncDispose]()
- Notes
- Zlib
- Threadpool usage and performance considerations
- Compressing HTTP requests and responses
- Memory usage tuning
- Flushing
- Constants
- Class:
Options - Class:
BrotliOptions - Class:
zlib.BrotliCompress - Class:
zlib.BrotliDecompress - Class:
zlib.Deflate - Class:
zlib.DeflateRaw - Class:
zlib.Gunzip - Class:
zlib.Gzip - Class:
zlib.Inflate - Class:
zlib.InflateRaw - Class:
zlib.Unzip - Class:
zlib.ZipBuffernew zlib.ZipBuffer(buffer)zipBuffer.add(filename, data[, options])zipBuffer.addSync(filename, data[, options])zipBuffer.addEntry(entry)zipBuffer.clear()zipBuffer.commentzipBuffer.delete(name)zipBuffer.entries()zipBuffer.forEach(callback[, thisArg])zipBuffer.get(name)zipBuffer.has(name)zipBuffer.keys()zipBuffer.sizezipBuffer.toBuffer([options])zipBuffer.toBufferSync([options])zipBuffer.values()zipBuffer.writable
- Class:
zlib.ZipEntry- Static method:
zlib.ZipEntry.create(filename, data[, options]) - Static method:
zlib.ZipEntry.createStream(filename, source[, options]) - Static method:
zlib.ZipEntry.createSymlink(filename, target[, options]) - Static method:
zlib.ZipEntry.createSync(filename, data[, options]) - Static method:
zlib.ZipEntry.read(buffer) zipEntry.commentzipEntry.compressedzipEntry.compressedSizezipEntry.content([options])zipEntry.contentSync([options])zipEntry.contentIterator([options])zipEntry.crc32zipEntry.flagszipEntry.isDirectoryzipEntry.isFilezipEntry.isSymlinkzipEntry.modezipEntry.modifiedzipEntry.methodzipEntry.namezipEntry.nameBufferzipEntry.rawContentzipEntry.size
- Static method:
- Class:
zlib.ZipFile- Static method:
zlib.ZipFile.open(filename[, options]) - Static method:
zlib.ZipFile.openSync(filename[, options]) zipFile.add(filename, data[, options])zipFile.addEntry(entry)zipFile.addEntrySync(entry)zipFile.addSync(filename, data[, options])zipFile.close()zipFile.closeSync()zipFile.commentzipFile.compact([comment])zipFile.compactSync([comment])zipFile.delete(name)zipFile.deleteSync(name)zipFile.entries()zipFile.entriesSync()zipFile.forEach(callback[, thisArg])zipFile.forEachSync(callback[, thisArg])zipFile.get(name)zipFile.getSync(name)zipFile.has(name)zipFile.keys()zipFile.sizezipFile.stream(name[, options])zipFile.values()zipFile.valuesSync()zipFile.writable
- Static method:
- Class:
zlib.ZlibBase - Class:
ZstdOptions - Class:
zlib.ZstdCompress - Class:
zlib.ZstdDecompress zlib.constantszlib.crc32(data[, value])zlib.createBrotliCompress([options])zlib.createBrotliDecompress([options])zlib.createDeflate([options])zlib.createDeflateRaw([options])zlib.createGunzip([options])zlib.createGzip([options])zlib.createInflate([options])zlib.createInflateRaw([options])zlib.createUnzip([options])zlib.createZipArchive(entries[, options])zlib.createZipArchiveSync(entries[, options])zlib.zipFiles(files[, options])zlib.createZstdCompress([options])zlib.createZstdDecompress([options])zlib.getMaxZipContentSize()zlib.setMaxZipContentSize(size)- Convenience methods
zlib.brotliCompress(buffer[, options], callback)zlib.brotliCompressSync(buffer[, options])zlib.brotliDecompress(buffer[, options], callback)zlib.brotliDecompressSync(buffer[, options])zlib.deflate(buffer[, options], callback)zlib.deflateSync(buffer[, options])zlib.deflateRaw(buffer[, options], callback)zlib.deflateRawSync(buffer[, options])zlib.gunzip(buffer[, options], callback)zlib.gunzipSync(buffer[, options])zlib.gzip(buffer[, options], callback)zlib.gzipSync(buffer[, options])zlib.inflate(buffer[, options], callback)zlib.inflateSync(buffer[, options])zlib.inflateRaw(buffer[, options], callback)zlib.inflateRawSync(buffer[, options])zlib.unzip(buffer[, options], callback)zlib.unzipSync(buffer[, options])zlib.zstdCompress(buffer[, options], callback)zlib.zstdCompressSync(buffer[, options])zlib.zstdDecompress(buffer[, options], callback)zlib.zstdDecompressSync(buffer[, options])
- Iterable Compression
compressBrotli([options])compressBrotliSync([options])compressDeflate([options])compressDeflateSync([options])compressGzip([options])compressGzipSync([options])compressZstd([options])compressZstdSync([options])decompressBrotli([options])decompressBrotliSync([options])decompressDeflate([options])decompressDeflateSync([options])decompressGzip([options])decompressGzipSync([options])decompressZstd([options])decompressZstdSync([options])
- Errors
- Error propagation and interception
- Class:
Error - Class:
AssertionError - Class:
DOMException - Class:
RangeError - Class:
ReferenceError - Class:
SyntaxError - Class:
SystemError - Class:
TypeError - Exceptions vs. errors
- OpenSSL errors
- Node.js error codes
ABORT_ERRERR_ACCESS_DENIEDERR_AMBIGUOUS_ARGUMENTERR_ARG_NOT_ITERABLEERR_ASSERTIONERR_ASYNC_CALLBACKERR_ASYNC_LOADER_REQUEST_NEVER_SETTLEDERR_ASYNC_TYPEERR_BROTLI_COMPRESSION_FAILEDERR_BROTLI_INVALID_PARAMERR_BUFFER_CONTEXT_NOT_AVAILABLEERR_BUFFER_OUT_OF_BOUNDSERR_BUFFER_TOO_LARGEERR_CANNOT_WATCH_SIGINTERR_CHILD_CLOSED_BEFORE_REPLYERR_CHILD_PROCESS_IPC_REQUIREDERR_CHILD_PROCESS_STDIO_MAXBUFFERERR_CLOSED_MESSAGE_PORTERR_CONSOLE_WRITABLE_STREAMERR_CONSTRUCT_CALL_INVALIDERR_CONSTRUCT_CALL_REQUIREDERR_CONTEXT_NOT_INITIALIZEDERR_CPU_PROFILE_ALREADY_STARTEDERR_CPU_PROFILE_NOT_STARTEDERR_CPU_PROFILE_TOO_MANYERR_CRYPTO_ARGON2_NOT_SUPPORTEDERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTEDERR_CRYPTO_ECDH_INVALID_FORMATERR_CRYPTO_ECDH_INVALID_PUBLIC_KEYERR_CRYPTO_ENGINE_UNKNOWNERR_CRYPTO_FIPS_FORCEDERR_CRYPTO_FIPS_UNAVAILABLEERR_CRYPTO_HASH_FINALIZEDERR_CRYPTO_HASH_UPDATE_FAILEDERR_CRYPTO_INCOMPATIBLE_KEYERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONSERR_CRYPTO_INITIALIZATION_FAILEDERR_CRYPTO_INVALID_AUTH_TAGERR_CRYPTO_INVALID_COUNTERERR_CRYPTO_INVALID_CURVEERR_CRYPTO_INVALID_DIGESTERR_CRYPTO_INVALID_IVERR_CRYPTO_INVALID_JWKERR_CRYPTO_INVALID_KEYLENERR_CRYPTO_INVALID_KEYPAIRERR_CRYPTO_INVALID_KEYTYPEERR_CRYPTO_INVALID_KEY_OBJECT_TYPEERR_CRYPTO_INVALID_MACERR_CRYPTO_INVALID_MESSAGELENERR_CRYPTO_INVALID_SCRYPT_PARAMSERR_CRYPTO_INVALID_STATEERR_CRYPTO_INVALID_TAG_LENGTHERR_CRYPTO_JOB_INIT_FAILEDERR_CRYPTO_JWK_UNSUPPORTED_CURVEERR_CRYPTO_JWK_UNSUPPORTED_KEY_TYPEERR_CRYPTO_KEM_NOT_SUPPORTEDERR_CRYPTO_MAC_FINALIZEDERR_CRYPTO_MAC_NOT_SUPPORTEDERR_CRYPTO_MAC_UPDATE_FAILEDERR_CRYPTO_OPERATION_FAILEDERR_CRYPTO_PBKDF2_ERRORERR_CRYPTO_SCRYPT_NOT_SUPPORTEDERR_CRYPTO_SIGN_KEY_REQUIREDERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTHERR_CRYPTO_UNKNOWN_CIPHERERR_CRYPTO_UNKNOWN_DH_GROUPERR_CRYPTO_UNSUPPORTED_OPERATIONERR_DEBUGGER_ERRORERR_DEBUGGER_STARTUP_ERRORERR_DIR_CLOSEDERR_DIR_CONCURRENT_OPERATIONERR_DLOPEN_DISABLEDERR_DLOPEN_FAILEDERR_DNS_SET_SERVERS_FAILEDERR_DOMAIN_CALLBACK_NOT_AVAILABLEERR_DOMAIN_CANNOT_SET_UNCAUGHT_EXCEPTION_CAPTUREERR_DUPLICATE_STARTUP_SNAPSHOT_MAIN_FUNCTIONERR_ENCODING_INVALID_ENCODED_DATAERR_ENCODING_NOT_SUPPORTEDERR_EVAL_ESM_CANNOT_PRINTERR_EVENT_RECURSIONERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLEERR_FALSY_VALUE_REJECTIONERR_FEATURE_UNAVAILABLE_ON_PLATFORMERR_FFI_CALL_FAILEDERR_FFI_INVALID_POINTERERR_FFI_LIBRARY_CLOSEDERR_FS_CP_DIR_TO_NON_DIRERR_FS_CP_EEXISTERR_FS_CP_EINVALERR_FS_CP_FIFO_PIPEERR_FS_CP_NON_DIR_TO_DIRERR_FS_CP_SOCKETERR_FS_CP_SYMLINK_TO_SUBDIRECTORYERR_FS_CP_UNKNOWNERR_FS_EISDIRERR_FS_FILE_TOO_LARGEERR_FS_WATCH_QUEUE_OVERFLOWERR_HTTP2_ALTSVC_INVALID_ORIGINERR_HTTP2_ALTSVC_LENGTHERR_HTTP2_CONNECT_AUTHORITYERR_HTTP2_CONNECT_PATHERR_HTTP2_CONNECT_SCHEMEERR_HTTP2_ERRORERR_HTTP2_GOAWAY_SESSIONERR_HTTP2_HEADERS_AFTER_RESPONDERR_HTTP2_HEADERS_SENTERR_HTTP2_HEADER_SINGLE_VALUEERR_HTTP2_INFO_STATUS_NOT_ALLOWEDERR_HTTP2_INVALID_CONNECTION_HEADERSERR_HTTP2_INVALID_HEADER_VALUEERR_HTTP2_INVALID_INFO_STATUSERR_HTTP2_INVALID_ORIGINERR_HTTP2_INVALID_PACKED_SETTINGS_LENGTHERR_HTTP2_INVALID_PSEUDOHEADERERR_HTTP2_INVALID_SESSIONERR_HTTP2_INVALID_SETTING_VALUEERR_HTTP2_INVALID_STREAMERR_HTTP2_MAX_PENDING_SETTINGS_ACKERR_HTTP2_NESTED_PUSHERR_HTTP2_NO_MEMERR_HTTP2_NO_SOCKET_MANIPULATIONERR_HTTP2_ORIGIN_LENGTHERR_HTTP2_OUT_OF_STREAMSERR_HTTP2_PAYLOAD_FORBIDDENERR_HTTP2_PING_CANCELERR_HTTP2_PING_LENGTHERR_HTTP2_PSEUDOHEADER_NOT_ALLOWEDERR_HTTP2_PUSH_DISABLEDERR_HTTP2_SEND_FILEERR_HTTP2_SEND_FILE_NOSEEKERR_HTTP2_SESSION_ERRORERR_HTTP2_SETTINGS_CANCELERR_HTTP2_SOCKET_BOUNDERR_HTTP2_SOCKET_UNBOUNDERR_HTTP2_STATUS_101ERR_HTTP2_STATUS_INVALIDERR_HTTP2_STREAM_CANCELERR_HTTP2_STREAM_ERRORERR_HTTP2_STREAM_SELF_DEPENDENCYERR_HTTP2_TOO_MANY_CUSTOM_SETTINGSERR_HTTP2_TOO_MANY_INVALID_FRAMESERR_HTTP2_TOO_MANY_ORIGINSERR_HTTP2_TRAILERS_ALREADY_SENTERR_HTTP2_TRAILERS_NOT_READYERR_HTTP2_UNSUPPORTED_PROTOCOLERR_HTTP_BODY_NOT_ALLOWEDERR_HTTP_CONTENT_LENGTH_MISMATCHERR_HTTP_HEADERS_SENTERR_HTTP_INVALID_HEADER_VALUEERR_HTTP_INVALID_STATUS_CODEERR_HTTP_REQUEST_TIMEOUTERR_HTTP_SOCKET_ASSIGNEDERR_HTTP_SOCKET_ENCODINGERR_HTTP_TRAILER_INVALIDERR_ILLEGAL_CONSTRUCTORERR_IMPORT_ATTRIBUTE_MISSINGERR_IMPORT_ATTRIBUTE_TYPE_INCOMPATIBLEERR_IMPORT_ATTRIBUTE_UNSUPPORTEDERR_INCOMPATIBLE_OPTION_PAIRERR_INPUT_TYPE_NOT_ALLOWEDERR_INSPECTOR_ALREADY_ACTIVATEDERR_INSPECTOR_ALREADY_CONNECTEDERR_INSPECTOR_CLOSEDERR_INSPECTOR_COMMANDERR_INSPECTOR_NOT_ACTIVEERR_INSPECTOR_NOT_AVAILABLEERR_INSPECTOR_NOT_CONNECTEDERR_INSPECTOR_NOT_WORKERERR_INTERNAL_ASSERTIONERR_INVALID_ADDRESSERR_INVALID_ADDRESS_FAMILYERR_INVALID_ARG_TYPEERR_INVALID_ARG_VALUEERR_INVALID_ASYNC_IDERR_INVALID_BUFFER_SIZEERR_INVALID_CHARERR_INVALID_CURSOR_POSERR_INVALID_FDERR_INVALID_FD_TYPEERR_INVALID_FILE_URL_HOSTERR_INVALID_FILE_URL_PATHERR_INVALID_HANDLE_TYPEERR_INVALID_HTTP_TOKENERR_INVALID_IP_ADDRESSERR_INVALID_MIME_SYNTAXERR_INVALID_MODULEERR_INVALID_MODULE_SPECIFIERERR_INVALID_OBJECT_DEFINE_PROPERTYERR_INVALID_PACKAGE_CONFIGERR_INVALID_PACKAGE_TARGETERR_INVALID_PROTOCOLERR_INVALID_REPL_EVAL_CONFIGERR_INVALID_REPL_INPUTERR_INVALID_RETURN_PROPERTYERR_INVALID_RETURN_PROPERTY_VALUEERR_INVALID_RETURN_VALUEERR_INVALID_STATEERR_INVALID_SYNC_FORK_INPUTERR_INVALID_THISERR_INVALID_TUPLEERR_INVALID_TYPESCRIPT_SYNTAXERR_INVALID_URIERR_INVALID_URLERR_INVALID_URL_PATTERNERR_INVALID_URL_SCHEMEERR_IPC_CHANNEL_CLOSEDERR_IPC_DISCONNECTEDERR_IPC_ONE_PIPEERR_IPC_SYNC_FORKERR_IP_BLOCKEDERR_LOADER_CHAIN_INCOMPLETEERR_LOAD_SQLITE_EXTENSIONERR_MEMORY_ALLOCATION_FAILEDERR_MESSAGE_TARGET_CONTEXT_UNAVAILABLEERR_METHOD_NOT_IMPLEMENTEDERR_MISSING_ARGSERR_MISSING_OPTIONERR_MISSING_PASSPHRASEERR_MISSING_PLATFORM_FOR_WORKERERR_MODULE_LINK_MISMATCHERR_MODULE_NOT_FOUNDERR_MULTIPLE_CALLBACKERR_NAPI_CONS_FUNCTIONERR_NAPI_INVALID_DATAVIEW_ARGSERR_NAPI_INVALID_TYPEDARRAY_ALIGNMENTERR_NAPI_INVALID_TYPEDARRAY_LENGTHERR_NAPI_TSFN_CALL_JSERR_NAPI_TSFN_GET_UNDEFINEDERR_NON_CONTEXT_AWARE_DISABLEDERR_NOT_BUILDING_SNAPSHOTERR_NOT_IN_SINGLE_EXECUTABLE_APPLICATIONERR_NOT_SUPPORTED_IN_SNAPSHOTERR_NO_CRYPTOERR_NO_ICUERR_NO_TEMPORALERR_NO_TYPESCRIPTERR_OPERATION_FAILEDERR_OPTIONS_BEFORE_BOOTSTRAPPINGERR_OUT_OF_RANGEERR_PACKAGE_IMPORT_NOT_DEFINEDERR_PACKAGE_MAP_EXTERNAL_FILEERR_PACKAGE_MAP_INVALIDERR_PACKAGE_MAP_KEY_NOT_FOUNDERR_PACKAGE_PATH_NOT_EXPORTEDERR_PARSE_ARGS_INVALID_OPTION_VALUEERR_PARSE_ARGS_UNEXPECTED_POSITIONALERR_PARSE_ARGS_UNKNOWN_OPTIONERR_PERFORMANCE_INVALID_TIMESTAMPERR_PERFORMANCE_MEASURE_INVALID_OPTIONSERR_PROTO_ACCESSERR_PROXY_INVALID_CONFIGERR_PROXY_TUNNELERR_QUIC_APPLICATION_ERRORERR_QUIC_CONNECTION_FAILEDERR_QUIC_ENDPOINT_CLOSEDERR_QUIC_OPEN_STREAM_FAILEDERR_QUIC_STREAM_ABORTEDERR_QUIC_STREAM_RESETERR_QUIC_TRANSPORT_ERRORERR_QUIC_VERSION_NEGOTIATION_ERRORERR_REQUIRE_ASYNC_MODULEERR_REQUIRE_CYCLE_MODULEERR_REQUIRE_ESMERR_REQUIRE_ESM_RACE_CONDITIONERR_SCRIPT_EXECUTION_INTERRUPTEDERR_SCRIPT_EXECUTION_TIMEOUTERR_SERVER_ALREADY_LISTENERR_SERVER_NOT_RUNNINGERR_SINGLE_EXECUTABLE_APPLICATION_ASSET_NOT_FOUNDERR_SOCKET_ALREADY_BOUNDERR_SOCKET_BAD_BUFFER_SIZEERR_SOCKET_BAD_PORTERR_SOCKET_BAD_TYPEERR_SOCKET_BUFFER_SIZEERR_SOCKET_CLOSEDERR_SOCKET_CLOSED_BEFORE_CONNECTIONERR_SOCKET_CONNECTION_TIMEOUTERR_SOCKET_DGRAM_IS_CONNECTEDERR_SOCKET_DGRAM_NOT_CONNECTEDERR_SOCKET_DGRAM_NOT_RUNNINGERR_SOCKET_HANDLE_ADOPTEDERR_SOURCE_MAP_CORRUPTERR_SOURCE_MAP_MISSING_SOURCEERR_SOURCE_PHASE_NOT_DEFINEDERR_SQLITE_ERRORERR_SRI_PARSEERR_STREAM_ALREADY_FINISHEDERR_STREAM_CANNOT_PIPEERR_STREAM_DESTROYEDERR_STREAM_ITER_MISSING_FLAGERR_STREAM_NULL_VALUESERR_STREAM_PREMATURE_CLOSEERR_STREAM_PUSH_AFTER_EOFERR_STREAM_UNABLE_TO_PIPEERR_STREAM_UNSHIFT_AFTER_END_EVENTERR_STREAM_WRAPERR_STREAM_WRITE_AFTER_ENDERR_STRING_TOO_LONGERR_SYNTHETICERR_SYSTEM_ERRORERR_TEST_FAILUREERR_THROTTLEDERR_TLS_ALPN_CALLBACK_INVALID_RESULTERR_TLS_ALPN_CALLBACK_WITH_PROTOCOLSERR_TLS_CERT_ALTNAME_FORMATERR_TLS_CERT_ALTNAME_INVALIDERR_TLS_DH_PARAM_SIZEERR_TLS_HANDSHAKE_TIMEOUTERR_TLS_INVALID_CONTEXTERR_TLS_INVALID_PROTOCOL_METHODERR_TLS_INVALID_PROTOCOL_VERSIONERR_TLS_INVALID_STATEERR_TLS_PROTOCOL_VERSION_CONFLICTERR_TLS_PSK_SET_IDENTITY_HINT_FAILEDERR_TLS_RENEGOTIATION_DISABLEDERR_TLS_RENEGOTIATION_UNSUPPORTEDERR_TLS_REQUIRED_SERVER_NAMEERR_TLS_SESSION_ATTACKERR_TLS_SNI_FROM_SERVERERR_TRACE_EVENTS_CATEGORY_REQUIREDERR_TRACE_EVENTS_UNAVAILABLEERR_TRAILING_JUNK_AFTER_STREAM_ENDERR_TRANSFORM_ALREADY_TRANSFORMINGERR_TRANSFORM_WITH_LENGTH_0ERR_TTY_INIT_FAILEDERR_UNAVAILABLE_DURING_EXITERR_UNCAUGHT_EXCEPTION_CAPTURE_ALREADY_SETERR_UNESCAPED_CHARACTERSERR_UNHANDLED_ERRORERR_UNKNOWN_BUILTIN_MODULEERR_UNKNOWN_CREDENTIALERR_UNKNOWN_ENCODINGERR_UNKNOWN_FILE_EXTENSIONERR_UNKNOWN_MODULE_FORMATERR_UNKNOWN_SIGNALERR_UNSUPPORTED_DIR_IMPORTERR_UNSUPPORTED_ESM_URL_SCHEMEERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPINGERR_UNSUPPORTED_RESOLVE_REQUESTERR_UNSUPPORTED_TYPESCRIPT_SYNTAXERR_USE_AFTER_CLOSEERR_VALID_PERFORMANCE_ENTRY_TYPEERR_VFS_INVALID_TARGETERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSINGERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAGERR_VM_MODULE_ALREADY_LINKEDERR_VM_MODULE_CACHED_DATA_REJECTEDERR_VM_MODULE_CANNOT_CREATE_CACHED_DATAERR_VM_MODULE_DIFFERENT_CONTEXTERR_VM_MODULE_LINK_FAILUREERR_VM_MODULE_NOT_MODULEERR_VM_MODULE_STATUSERR_WASI_ALREADY_STARTEDERR_WASI_NOT_STARTEDERR_WEBASSEMBLY_NOT_SUPPORTEDERR_WEBASSEMBLY_RESPONSEERR_WORKER_HANDLE_NOT_TRANSFERABLEERR_WORKER_INIT_FAILEDERR_WORKER_INVALID_EXEC_ARGVERR_WORKER_MESSAGING_ERROREDERR_WORKER_MESSAGING_FAILEDERR_WORKER_MESSAGING_SAME_THREADERR_WORKER_MESSAGING_TIMEOUTERR_WORKER_NOT_RUNNINGERR_WORKER_OUT_OF_MEMORYERR_WORKER_PATHERR_WORKER_UNSERIALIZABLE_ERRORERR_WORKER_UNSUPPORTED_OPERATIONERR_ZIP_ARCHIVE_TOO_LARGEERR_ZIP_ENTRY_CORRUPTERR_ZIP_ENTRY_NOT_FOUNDERR_ZIP_ENTRY_TOO_LARGEERR_ZIP_INVALID_ARCHIVEERR_ZIP_NOT_WRITABLEERR_ZIP_UNSUPPORTED_FEATUREERR_ZLIB_INITIALIZATION_FAILEDERR_ZSTD_INVALID_PARAMHPE_CHUNK_EXTENSIONS_OVERFLOWHPE_HEADER_OVERFLOWHPE_UNEXPECTED_CONTENT_LENGTHMODULE_NOT_FOUND
- Legacy Node.js error codes
ERR_CANNOT_TRANSFER_OBJECTERR_CPU_USAGEERR_CRYPTO_HASH_DIGEST_NO_UTF16ERR_CRYPTO_SCRYPT_INVALID_PARAMETERERR_FS_INVALID_SYMLINK_TYPEERR_HTTP2_FRAME_ERRORERR_HTTP2_HEADERS_OBJECTERR_HTTP2_HEADER_REQUIREDERR_HTTP2_INFO_HEADERS_AFTER_RESPONDERR_HTTP2_STREAM_CLOSEDERR_HTTP_INVALID_CHARERR_IMPORT_ASSERTION_TYPE_FAILEDERR_IMPORT_ASSERTION_TYPE_MISSINGERR_IMPORT_ASSERTION_TYPE_UNSUPPORTEDERR_INDEX_OUT_OF_RANGEERR_INVALID_OPT_VALUEERR_INVALID_OPT_VALUE_ENCODINGERR_INVALID_PERFORMANCE_MARKERR_INVALID_TRANSFER_OBJECTERR_MANIFEST_ASSERT_INTEGRITYERR_MANIFEST_DEPENDENCY_MISSINGERR_MANIFEST_INTEGRITY_MISMATCHERR_MANIFEST_INVALID_RESOURCE_FIELDERR_MANIFEST_INVALID_SPECIFIERERR_MANIFEST_PARSE_POLICYERR_MANIFEST_TDZERR_MANIFEST_UNKNOWN_ONERRORERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LISTERR_MISSING_TRANSFERABLE_IN_TRANSFER_LISTERR_NAPI_CONS_PROTOTYPE_OBJECTERR_NAPI_TSFN_START_IDLE_LOOPERR_NAPI_TSFN_STOP_IDLE_LOOPERR_NO_LONGER_SUPPORTEDERR_OUTOFMEMORYERR_PARSE_HISTORY_DATAERR_SOCKET_CANNOT_SENDERR_STDERR_CLOSEERR_STDOUT_CLOSEERR_STREAM_READ_NOT_IMPLEMENTEDERR_TAP_LEXER_ERRORERR_TAP_PARSER_ERRORERR_TAP_VALIDATION_ERRORERR_TLS_RENEGOTIATION_FAILEDERR_TRANSFERRING_EXTERNALIZED_SHAREDARRAYBUFFERERR_UNKNOWN_STDIN_TYPEERR_UNKNOWN_STREAM_TYPEERR_V8BREAKITERATORERR_VALUE_OUT_OF_RANGEERR_VM_MODULE_LINKING_ERROREDERR_VM_MODULE_NOT_LINKEDERR_WORKER_UNSUPPORTED_EXTENSIONERR_ZLIB_BINDING_CLOSED
- OpenSSL Error Codes
- Events
- Passing arguments and
thisto listeners - Asynchronous vs. synchronous
- Handling events only once
- Error events
- Capture rejections of promises
- Class:
EventEmitter- Event:
'newListener' - Event:
'removeListener' emitter.addListener(eventName, listener)emitter.emit(eventName[, ...args])emitter.eventNames()emitter.getMaxListeners()emitter.listenerCount(eventName[, listener])emitter.listeners(eventName)emitter.off(eventName, listener)emitter.on(eventName, listener)emitter.once(eventName, listener)emitter.prependListener(eventName, listener)emitter.prependOnceListener(eventName, listener)emitter.removeAllListeners([eventName])emitter.removeListener(eventName, listener)emitter.setMaxListeners(n)emitter.rawListeners(eventName)emitter[Symbol.for('nodejs.rejection')](err, eventName[, ...args])
- Event:
events.defaultMaxListenersevents.errorMonitorevents.getEventListeners(emitterOrTarget, eventName)events.getMaxListeners(emitterOrTarget)events.once(emitter, name[, options])events.captureRejectionsevents.captureRejectionSymbolevents.listenerCount(emitterOrTarget, eventName)events.on(emitter, eventName[, options])events.setMaxListeners(n[, ...eventTargets])events.addAbortListener(signal, listener)- Class:
events.EventEmitterAsyncResource extends EventEmitter EventTargetandEventAPI- Node.js
EventTargetvs. DOMEventTarget NodeEventTargetvs.EventEmitter- Event listener
EventTargeterror handling- Class:
Eventevent.bubblesevent.cancelBubbleevent.cancelableevent.composedevent.composedPath()event.currentTargetevent.defaultPreventedevent.eventPhaseevent.initEvent(type[, bubbles[, cancelable]])event.isTrustedevent.preventDefault()event.returnValueevent.srcElementevent.stopImmediatePropagation()event.stopPropagation()event.targetevent.timeStampevent.type
- Class:
EventTarget - Class:
CustomEvent - Class:
NodeEventTargetnodeEventTarget.addListener(type, listener)nodeEventTarget.emit(type, arg)nodeEventTarget.eventNames()nodeEventTarget.listenerCount(type)nodeEventTarget.setMaxListeners(n)nodeEventTarget.getMaxListeners()nodeEventTarget.off(type, listener[, options])nodeEventTarget.on(type, listener)nodeEventTarget.once(type, listener)nodeEventTarget.removeAllListeners([type])nodeEventTarget.removeListener(type, listener[, options])
- Node.js
- Passing arguments and
- FFI
- Overview
- Type names
- Signature objects
ffi.suffixffi.dlopen(path[, definitions])ffi.dlclose(handle)ffi.dlsym(handle, symbol)- Class:
DynamicLibrarynew DynamicLibrary(path)library.pathlibrary.functionslibrary.symbolslibrary.close()library[Symbol.dispose]()library.getFunction(name, signature)library.getFunctions([definitions])library.getSymbol(name)library.getSymbols()library.registerCallback([signature,] callback)library.unregisterCallback(pointer)library.refCallback(pointer)library.unrefCallback(pointer)
- Calling native functions
- Call paths
- Primitive memory access helpers
ffi.toString(pointer)ffi.toBuffer(pointer, length[, copy])ffi.toArrayBuffer(pointer, length[, copy])ffi.exportString(string, pointer, length[, encoding])ffi.exportBuffer(buffer, pointer, length)ffi.exportArrayBuffer(arrayBuffer, pointer, length)ffi.exportArrayBufferView(arrayBufferView, pointer, length)ffi.getRawPointer(source)ffi.getCurrentEventLoop()- Safety notes
- File system
- Promise example
- Callback example
- Synchronous example
- Promises API
- Class:
FileHandle- Event:
'close' filehandle.appendFile(data[, options])filehandle.chmod(mode)filehandle.chown(uid, gid)filehandle.close()filehandle.createReadStream([options])filehandle.createWriteStream([options])filehandle.datasync()filehandle.fdfilehandle.pull([...transforms][, options])filehandle.pullSync([...transforms][, options])filehandle.read(buffer, offset, length, position)filehandle.read([options])filehandle.read(buffer[, options])filehandle.readableWebStream([options])filehandle.readFile(options)filehandle.readLines([options])filehandle.readv(buffers[, position])filehandle.stat([options])filehandle.sync()filehandle.truncate(len)filehandle.utimes(atime, mtime)filehandle.write(buffer, offset[, length[, position]])filehandle.write(buffer[, options])filehandle.write(string[, position[, encoding]])filehandle.writeFile(data, options)filehandle.writev(buffers[, position])filehandle.writer([options])filehandle[Symbol.asyncDispose]()
- Event:
fsPromises.access(path[, mode])fsPromises.appendFile(path, data[, options])fsPromises.chmod(path, mode)fsPromises.chown(path, uid, gid)fsPromises.copyFile(src, dest[, mode])fsPromises.cp(src, dest[, options])fsPromises.glob(pattern[, options])fsPromises.lchmod(path, mode)fsPromises.lchown(path, uid, gid)fsPromises.lutimes(path, atime, mtime)fsPromises.link(existingPath, newPath)fsPromises.lstat(path[, options])fsPromises.mkdir(path[, options])fsPromises.mkdtemp(prefix[, options])fsPromises.mkdtempDisposable(prefix[, options])fsPromises.open(path, flags[, mode])fsPromises.opendir(path[, options])fsPromises.readdir(path[, options])fsPromises.readFile(path[, options])fsPromises.readlink(path[, options])fsPromises.realpath(path[, options])fsPromises.rename(oldPath, newPath)fsPromises.rmdir(path[, options])fsPromises.rm(path[, options])fsPromises.stat(path[, options])fsPromises.statfs(path[, options])fsPromises.symlink(target, path[, type])fsPromises.truncate(path[, len])fsPromises.unlink(path)fsPromises.utimes(path, atime, mtime)fsPromises.watch(filename[, options])fsPromises.writeFile(file, data[, options])fsPromises.constants
- Class:
- Callback API
fs.access(path[, mode], callback)fs.appendFile(path, data[, options], callback)fs.chmod(path, mode, callback)fs.chown(path, uid, gid, callback)fs.close(fd[, callback])fs.copyFile(src, dest[, mode], callback)fs.cp(src, dest[, options], callback)fs.createReadStream(path[, options])fs.createWriteStream(path[, options])fs.exists(path, callback)fs.fchmod(fd, mode, callback)fs.fchown(fd, uid, gid, callback)fs.fdatasync(fd, callback)fs.fstat(fd[, options], callback)fs.fsync(fd, callback)fs.ftruncate(fd[, len], callback)fs.futimes(fd, atime, mtime, callback)fs.glob(pattern[, options], callback)fs.lchmod(path, mode, callback)fs.lchown(path, uid, gid, callback)fs.lutimes(path, atime, mtime, callback)fs.link(existingPath, newPath, callback)fs.lstat(path[, options], callback)fs.mkdir(path[, options], callback)fs.mkdtemp(prefix[, options], callback)fs.open(path[, flags[, mode]], callback)fs.openAsBlob(path[, options])fs.opendir(path[, options], callback)fs.read(fd, buffer, offset, length, position, callback)fs.read(fd[, options], callback)fs.read(fd, buffer[, options], callback)fs.readdir(path[, options], callback)fs.readFile(path[, options], callback)fs.readlink(path[, options], callback)fs.readv(fd, buffers[, position], callback)fs.realpath(path[, options], callback)fs.realpath.native(path[, options], callback)fs.rename(oldPath, newPath, callback)fs.rmdir(path[, options], callback)fs.rm(path[, options], callback)fs.stat(path[, options], callback)fs.statfs(path[, options], callback)fs.symlink(target, path[, type], callback)fs.truncate(path[, len], callback)fs.unlink(path, callback)fs.unwatchFile(filename[, listener])fs.utimes(path, atime, mtime, callback)fs.watch(filename[, options][, listener])fs.watchFile(filename[, options], listener)fs.write(fd, buffer, offset[, length[, position]], callback)fs.write(fd, buffer[, options], callback)fs.write(fd, string[, position[, encoding]], callback)fs.writeFile(file, data[, options], callback)fs.writev(fd, buffers[, position], callback)
- Synchronous API
fs.accessSync(path[, mode])fs.appendFileSync(path, data[, options])fs.chmodSync(path, mode)fs.chownSync(path, uid, gid)fs.closeSync(fd)fs.copyFileSync(src, dest[, mode])fs.cpSync(src, dest[, options])fs.existsSync(path)fs.fchmodSync(fd, mode)fs.fchownSync(fd, uid, gid)fs.fdatasyncSync(fd)fs.fstatSync(fd[, options])fs.fsyncSync(fd)fs.ftruncateSync(fd[, len])fs.futimesSync(fd, atime, mtime)fs.globSync(pattern[, options])fs.lchmodSync(path, mode)fs.lchownSync(path, uid, gid)fs.lutimesSync(path, atime, mtime)fs.linkSync(existingPath, newPath)fs.lstatSync(path[, options])fs.mkdirSync(path[, options])fs.mkdtempSync(prefix[, options])fs.mkdtempDisposableSync(prefix[, options])fs.openAsBlobSync(path[, options])fs.opendirSync(path[, options])fs.openSync(path[, flags[, mode]])fs.readdirSync(path[, options])fs.readFileSync(path[, options])fs.readlinkSync(path[, options])fs.readSync(fd, buffer, offset, length[, position])fs.readSync(fd, buffer[, options])fs.readvSync(fd, buffers[, position])fs.realpathSync(path[, options])fs.realpathSync.native(path[, options])fs.renameSync(oldPath, newPath)fs.rmdirSync(path[, options])fs.rmSync(path[, options])fs.statSync(path[, options])fs.statfsSync(path[, options])fs.symlinkSync(target, path[, type])fs.truncateSync(path[, len])fs.unlinkSync(path)fs.utimesSync(path, atime, mtime)fs.writeFileSync(file, data[, options])fs.writeSync(fd, buffer, offset[, length[, position]])fs.writeSync(fd, buffer[, options])fs.writeSync(fd, string[, position[, encoding]])fs.writevSync(fd, buffers[, position])
- Common Objects
- Class:
fs.Dir - Class:
fs.Dirent - Class:
fs.FSWatcher - Class:
fs.StatWatcher - Class:
fs.ReadStream - Class:
fs.Statsstats.isBlockDevice()stats.isCharacterDevice()stats.isDirectory()stats.isFIFO()stats.isFile()stats.isSocket()stats.isSymbolicLink()stats.devstats.inostats.modestats.nlinkstats.uidstats.gidstats.rdevstats.sizestats.blksizestats.blocksstats.atimeMsstats.mtimeMsstats.ctimeMsstats.birthtimeMsstats.atimeNsstats.mtimeNsstats.ctimeNsstats.birthtimeNsstats.atimestats.mtimestats.ctimestats.birthtime- Stat time values
- Class:
fs.StatFs - Class:
fs.Utf8Stream- Event:
'close' - Event:
'drain' - Event:
'drop' - Event:
'error' - Event:
'finish' - Event:
'ready' - Event:
'write' new fs.Utf8Stream([options])utf8Stream.appendutf8Stream.contentModeutf8Stream.destroy()utf8Stream.end()utf8Stream.fdutf8Stream.fileutf8Stream.flush(callback)utf8Stream.flushSync()utf8Stream.fsyncutf8Stream.maxLengthutf8Stream.minLengthutf8Stream.mkdirutf8Stream.modeutf8Stream.periodicFlushutf8Stream.reopen(file)utf8Stream.syncutf8Stream.write(data)utf8Stream.writingutf8Stream[Symbol.dispose]()
- Event:
- Class:
fs.WriteStream fs.constants
- Class:
- Notes
- Global objects
__dirname__filename- Class:
AbortController - Class:
AbortSignal atob(data)- Class:
Blob - Class:
BroadcastChannel btoa(data)- Class:
Buffer - Class:
ByteLengthQueuingStrategy clearImmediate(immediateObject)clearInterval(intervalObject)clearTimeout(timeoutObject)- Class:
CloseEvent - Class:
CompressionStream console- Class:
CountQueuingStrategy - Class:
Crypto crypto- Class:
CryptoKey - Class:
CustomEvent - Class:
DecompressionStream - Class:
DOMException ErrorEvent- Class:
Event - Class:
EventSource - Class:
EventTarget exportsfetch- Class:
File - Class:
FormData global- Class:
Headers localStorage- Class:
MessageChannel - Class:
MessageEvent - Class:
MessagePort module- Class:
Navigator navigatorperformance- Class:
PerformanceEntry - Class:
PerformanceMark - Class:
PerformanceMeasure - Class:
PerformanceObserver - Class:
PerformanceObserverEntryList - Class:
PerformanceResourceTiming processqueueMicrotask(callback)- Class:
QuotaExceededError - Class:
ReadableByteStreamController - Class:
ReadableStream - Class:
ReadableStreamBYOBReader - Class:
ReadableStreamBYOBRequest - Class:
ReadableStreamDefaultController - Class:
ReadableStreamDefaultReader - Class:
Request require()- Class:
Response sessionStoragesetImmediate(callback[, ...args])setInterval(callback, delay[, ...args])setTimeout(callback, delay[, ...args])- Class:
Storage structuredClone(value[, options])- Class:
SubtleCrypto - Class:
TextDecoder - Class:
TextDecoderStream - Class:
TextEncoder - Class:
TextEncoderStream - Class:
TransformStream - Class:
TransformStreamDefaultController - Class:
URL - Class:
URLPattern - Class:
URLSearchParams - Class:
WebAssembly - Class:
WebSocket - Class:
Worker - Class:
WritableStream - Class:
WritableStreamDefaultController - Class:
WritableStreamDefaultWriter
- HTTP
- Class:
http.Agent- Response ordering with connection reuse
new Agent([options])agent.createConnection(options[, callback])agent.keepSocketAlive(socket)agent.reuseSocket(socket, request)agent.destroy()agent.freeSocketsagent.getName([options])agent.maxFreeSocketsagent.maxSocketsagent.maxTotalSocketsagent.requestsagent.sockets
- Class:
http.ClientRequest- Event:
'abort' - Event:
'close' - Event:
'connect' - Event:
'continue' - Event:
'finish' - Event:
'information' - Event:
'response' - Event:
'socket' - Event:
'timeout' - Event:
'upgrade' request.abort()request.abortedrequest.connectionrequest.cork()request.end([data[, encoding]][, callback])request.destroy([error])request.finishedrequest.flushHeaders()request.getHeader(name)request.getHeaderNames()request.getHeaders()request.getRawHeaderNames()request.hasHeader(name)request.maxHeadersCountrequest.pathrequest.methodrequest.hostrequest.protocolrequest.removeHeader(name)request.reusedSocketrequest.setHeader(name, value)request.setNoDelay([noDelay])request.setSocketKeepAlive([enable][, initialDelay])request.setTimeout(timeout[, callback])request.socketrequest.uncork()request.writableEndedrequest.writableFinishedrequest.write(chunk[, encoding][, callback])
- Event:
- Class:
http.Server- Event:
'checkContinue' - Event:
'checkExpectation' - Event:
'clientError' - Event:
'close' - Event:
'connect' - Event:
'connection' - Event:
'dropRequest' - Event:
'request' - Event:
'upgrade' server.close([callback])server.closeAllConnections()server.closeIdleConnections()server.headersTimeoutserver.listen()server.listeningserver.maxHeadersCountserver.requestTimeoutserver.setTimeout([msecs][, callback])server.maxRequestsPerSocketserver.timeoutserver.keepAliveTimeoutserver.keepAliveTimeoutBufferserver[Symbol.asyncDispose]()
- Event:
- Class:
http.ServerResponse- Event:
'close' - Event:
'finish' response.addTrailers(headers)response.connectionresponse.cork()response.end([data[, encoding]][, callback])response.finishedresponse.flushHeaders()response.getHeader(name)response.getHeaderNames()response.getHeaders()response.hasHeader(name)response.headersSentresponse.removeHeader(name)response.reqresponse.sendDateresponse.setHeader(name, value)response.setTimeout(msecs[, callback])response.socketresponse.statusCoderesponse.statusMessageresponse.strictContentLengthresponse.uncork()response.writableEndedresponse.writableFinishedresponse.write(chunk[, encoding][, callback])response.writeContinue()response.writeEarlyHints(hints[, callback])response.writeHead(statusCode[, statusMessage][, headers])response.writeInformation(statusCode[, headers][, callback])response.writeProcessing()
- Event:
- Class:
http.IncomingMessage- Event:
'aborted' - Event:
'close' message.abortedmessage.completemessage.connectionmessage.destroy([error])message.headersmessage.headersDistinctmessage.httpVersionmessage.methodmessage.rawHeadersmessage.rawTrailersmessage.setTimeout(msecs[, callback])message.signalmessage.socketmessage.statusCodemessage.statusMessagemessage.trailersmessage.trailersDistinctmessage.url
- Event:
- Class:
http.OutgoingMessage- Event:
'drain' - Event:
'finish' - Event:
'prefinish' outgoingMessage.addTrailers(headers)outgoingMessage.appendHeader(name, value)outgoingMessage.connectionoutgoingMessage.cork()outgoingMessage.destroy([error])outgoingMessage.end(chunk[, encoding][, callback])outgoingMessage.flushHeaders()outgoingMessage.getHeader(name)outgoingMessage.getHeaderNames()outgoingMessage.getHeaders()outgoingMessage.hasHeader(name)outgoingMessage.headersSentoutgoingMessage.pipe()outgoingMessage.removeHeader(name)outgoingMessage.setHeader(name, value)outgoingMessage.setHeaders(headers)outgoingMessage.setTimeout(msecs[, callback])outgoingMessage.socketoutgoingMessage.uncork()outgoingMessage.writableCorkedoutgoingMessage.writableEndedoutgoingMessage.writableFinishedoutgoingMessage.writableHighWaterMarkoutgoingMessage.writableLengthoutgoingMessage.writableObjectModeoutgoingMessage.write(chunk[, encoding][, callback])
- Event:
http.METHODShttp.STATUS_CODEShttp.createServer([options][, requestListener])http.get(options[, callback])http.get(url[, options][, callback])http.globalAgenthttp.maxHeaderSizehttp.request(options[, callback])http.request(url[, options][, callback])http.isValidHeaderName(name)http.isValidHeaderValue(value[, options])http.validateHeaderName(name[, label])http.validateHeaderValue(name, value)http.setMaxIdleHTTPParsers(max)http.setGlobalProxyFromEnv([proxyEnv])- Class:
WebSocket - Built-in Proxy Support
- Class:
- HTTP/2
- Determining if crypto support is unavailable
- Core API
- Server-side example
- Client-side example
- Class:
Http2SessionHttp2Sessionand sockets- Event:
'close' - Event:
'connect' - Event:
'error' - Event:
'frameError' - Event:
'goaway' - Event:
'localSettings' - Event:
'ping' - Event:
'remoteSettings' - Event:
'stream' - Event:
'timeout' http2session.alpnProtocolhttp2session.close([callback])http2session.closedhttp2session.connectinghttp2session.destroy([error][, code])http2session.destroyedhttp2session.encryptedhttp2session.goaway([code[, lastStreamID[, opaqueData]]])http2session.localSettingshttp2session.originSethttp2session.pendingSettingsAckhttp2session.ping([payload, ]callback)http2session.ref()http2session.remoteSettingshttp2session.setLocalWindowSize(windowSize)http2session.setTimeout(msecs, callback)http2session.sockethttp2session.statehttp2session.settings([settings][, callback])http2session.typehttp2session.unref()
- Class:
ServerHttp2Session - Class:
ClientHttp2Session - Class:
Http2StreamHttp2StreamLifecycle- Event:
'aborted' - Event:
'close' - Event:
'error' - Event:
'frameError' - Event:
'ready' - Event:
'timeout' - Event:
'trailers' - Event:
'wantTrailers' http2stream.abortedhttp2stream.bufferSizehttp2stream.close(code[, callback])http2stream.closedhttp2stream.destroyedhttp2stream.endAfterHeadershttp2stream.idhttp2stream.pendinghttp2stream.priority(options)http2stream.rstCodehttp2stream.sentHeadershttp2stream.sentInfoHeadershttp2stream.sentTrailershttp2stream.sessionhttp2stream.setTimeout(msecs, callback)http2stream.statehttp2stream.sendTrailers(headers)
- Class:
ClientHttp2Stream - Class:
ServerHttp2Stream - Class:
Http2Server - Class:
Http2SecureServer http2.createServer([options][, onRequestHandler])http2.createSecureServer(options[, onRequestHandler])http2.connect(authority[, options][, listener])http2.constantshttp2.getDefaultSettings()http2.getPackedSettings([settings])http2.getUnpackedSettings(buf)http2.performServerHandshake(socket[, options])http2.sensitiveHeaders- Headers object
- Settings object
- Error handling
- Invalid character handling in header names and values
- Push streams on the client
- Supporting the
CONNECTmethod - The extended
CONNECTprotocol
- Compatibility API
- ALPN negotiation
- Class:
http2.Http2ServerRequest- Event:
'aborted' - Event:
'close' request.abortedrequest.authorityrequest.completerequest.connectionrequest.destroy([error])request.headersrequest.httpVersionrequest.methodrequest.rawHeadersrequest.rawTrailersrequest.schemerequest.setTimeout(msecs, callback)request.socketrequest.streamrequest.trailersrequest.url
- Event:
- Class:
http2.Http2ServerResponse- Event:
'close' - Event:
'finish' response.addTrailers(headers)response.appendHeader(name, value)response.connectionresponse.createPushResponse(headers, callback)response.end([data[, encoding]][, callback])response.finishedresponse.getHeader(name)response.getHeaderNames()response.getHeaders()response.hasHeader(name)response.headersSentresponse.removeHeader(name)response.reqresponse.sendDateresponse.setHeader(name, value)response.setTimeout(msecs[, callback])response.socketresponse.statusCoderesponse.statusMessageresponse.streamresponse.writableEndedresponse.write(chunk[, encoding][, callback])response.writeContinue()response.writeEarlyHints(hints)response.writeInformation(statusCode[, headers])response.writeHead(statusCode[, statusMessage][, headers])
- Event:
- Collecting HTTP/2 performance metrics
- Note on
:authorityandhost
- HTTPS
- Command-line API
- Other versions
- Options
Command-line API#
Node.js comes with a variety of CLI options. These options expose built-in debugging, multiple ways to execute scripts, and other helpful runtime options.
To view this documentation as a manual page in a terminal, run man node.
Synopsis#
node [options] [V8 options] [<program-entry-point> | -e "script" | -] [--] [arguments]
node inspect [<program-entry-point> | -e "script" | <host>:<port>] …
node --v8-options
Execute without arguments to start the REPL.
For more info about node inspect, see the debugger documentation.
Program entry point#
The program entry point is a specifier-like string. If the string is not an
absolute path, it's resolved as a relative path from the current working
directory. That entry point string is then resolved as if it's been requested
by require() from the current working directory. If no corresponding file
is found, an error is thrown.
By default, the resolved path is also loaded as if it's been requested by require(),
unless one of the conditions below apply—then it's loaded as if it's been requested
by import():
- The program was started with a command-line flag that forces the entry
point to be loaded with ECMAScript module loader, such as
--import. - The file has an
.mjs,.mtsor.wasmextension. - The file does not have a
.cjsextension, and the nearest parentpackage.jsonfile contains a top-level"type"field with a value of"module".
See module resolution and loading for more details.
Options#
Stability: 2 - Stable
All options, including V8 options, allow words to be separated by both
dashes (-) or underscores (_). For example, --pending-deprecation is
equivalent to --pending_deprecation.
If an option that takes a single value (such as --max-http-header-size) is
passed more than once, then the last passed value is used. Options from the
command line take precedence over options passed through the NODE_OPTIONS
environment variable.
-#
Alias for stdin. Analogous to the use of - in other command-line utilities,
meaning that the script is read from stdin, and the rest of the options
are passed to that script.
--#
Indicate the end of node options. Pass the rest of the arguments to the script. If no script filename or eval/print script is supplied prior to this, then the next argument is used as a script filename.
--abort-on-uncaught-exception#
Aborting instead of exiting causes a core file to be generated for post-mortem
analysis using a debugger (such as lldb, gdb, and mdb).
If this flag is passed, the behavior can still be set to not abort through
process.setUncaughtExceptionCaptureCallback() (and through usage of the
node:domain module that uses it).
--allow-addons#
Stability: 1.1 - Active development
When using the Permission Model, the process will not be able to use
native addons by default.
Attempts to do so will throw an ERR_DLOPEN_DISABLED unless the
user explicitly passes the --allow-addons flag when starting Node.js.
Example:
// 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#
Stability: 1.1 - Active development
When using the Permission Model, the process will not be able to spawn any
child process by default.
Attempts to do so will throw an ERR_ACCESS_DENIED unless the
user explicitly passes the --allow-child-process flag when starting Node.js.
Example:
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'
}
The child_process.fork() API inherits the execution arguments from the
parent process. This means that 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.
This behavior also applies to child_process.spawn(), but in that case, the
flags are propagated via the NODE_OPTIONS environment variable rather than
directly through the process arguments.
--allow-ffi#
Stability: 1.1 - Active development
When using the Permission Model, the process will not be able to use FFI
APIs by default. Attempts to use FFI APIs will throw an ERR_ACCESS_DENIED
exception unless the user explicitly passes the --allow-ffi flag when
starting Node.js. The node:ffi module is only available in builds with
FFI support.
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 the --allow-fs-read flag are:
*- To allow allFileSystemReadoperations.- 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.
The initializer module and custom --require modules has a 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#
Stability: 1.1 - Active development
When using the Permission Model, a virtual file system cannot be
mounted by default: vfs.mount() throws ERR_INVALID_STATE unless the
user explicitly passes the --allow-fs-vfs flag when starting Node.js.
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-read or
--allow-fs-write.
$ 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 the --allow-fs-write flag are:
*- To allow allFileSystemWriteoperations.- Multiple paths can be allowed using multiple
--allow-fs-writeflags. Example--allow-fs-write=/folder1/ --allow-fs-write=/folder2/
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#
Stability: 1.0 - Early development
When using the Permission Model, the process will not be able to connect through inspector protocol.
Attempts to do so will throw an ERR_ACCESS_DENIED unless the
user explicitly passes the --allow-inspector flag when 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#
Stability: 1.1 - Active development
When using the Permission Model, the process will not be able to access
network by default.
Attempts to do so will throw an ERR_ACCESS_DENIED unless the
user explicitly passes the --allow-net flag when 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#
Stability: 1.1 - Active development
When using the Permission Model, the process will not be able to use
OpenSSL STORE loaders by default, for example to load a private key from a
<URL> passed to crypto.createPrivateKey(). Attempts to do so will throw
an ERR_ACCESS_DENIED unless the user explicitly passes the
--allow-openssl-store flag. This permission can be dropped at runtime via
permission.drop().
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 the fs.read, fs.write, or net permission scopes.
--allow-wasi#
Stability: 1.1 - Active development
When using the Permission Model, the process will not be capable of creating
any WASI instances by default.
For security reasons, the call will throw an ERR_ACCESS_DENIED unless the
user explicitly passes the flag --allow-wasi in 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#
Stability: 1.1 - Active development
When using the Permission Model, the process will not be able to create any
worker threads by default.
For security reasons, the call will throw an ERR_ACCESS_DENIED unless the
user explicitly pass the flag --allow-worker in 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
Error: Access to this API has been restricted
at node:internal/main/run_main_module:17:47 {
code: 'ERR_ACCESS_DENIED',
permission: 'WorkerThreads'
}
--bench#
Stability: 1 - Experimental
Starts the Node.js command-line benchmark runner. At least one explicit file or glob pattern is required:
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.
Quote glob patterns to prevent expansion by the shell. Matching files are
sorted and executed serially. By default, each file runs in a separate child
process. Benchmark files declare benchmarks using node:bench; they must not
call run() themselves. See the benchmark runner documentation for more
details.
This flag cannot be combined with --test, --watch, --watch-path,
--check, --eval, or --interactive.
--bench-isolation=mode#
Stability: 1 - Experimental
Configures benchmark file isolation. When mode is 'process', each matching
file runs in a separate child process. This is the default. Files are still run
serially so their measured work does not overlap.
When mode is 'none', all matching files and benchmarks run serially in the
benchmark runner process. This reduces startup overhead but allows module,
heap, and process state to carry between files. User writes to stdout or stderr
also share destinations with benchmark reporters in this mode.
The supported modes are 'process' and 'none'.
--bench-name-pattern=pattern#
Stability: 1 - Experimental
Only runs benchmarks whose full hierarchical name matches the JavaScript
regular expression pattern. Non-matching benchmarks are reported as skipped.
--bench-reporter-destination=destination#
Stability: 1 - Experimental
Specifies the destination for the corresponding benchmark reporter. The value
can be stdout, stderr, or a file path. A single reporter defaults to
stdout when no destination is specified.
--bench-reporter=reporter#
Stability: 1 - Experimental
Specifies a benchmark reporter. The built-in reporters are spec and json.
The json reporter emits newline-delimited JSON. A custom reporter can be
specified using a module specifier resolved from the current working directory.
This option can be repeated. When multiple reporters are specified, each must
have a corresponding --bench-reporter-destination. The default reporter is
spec.
--bench-samples=count#
Stability: 1 - Experimental
Overrides the maximum number of measured callback invocations for every
selected benchmark. A benchmark may finish earlier by calling
context.done(). count must be an integer between 1 and 4294967295.
--bench-warmup=count#
Stability: 1 - Experimental
Overrides the number of unreported warmup callback invocations for every
selected benchmark. count must be an integer between 0 and 4294967295.
--build-sea=config#
Stability: 1.1 - Active development
Generates a single executable application from a JSON configuration file. The argument must be a path to the configuration file. If the path is not absolute, it is resolved relative to the current working directory.
For configuration fields, cross-platform notes, and asset APIs, see the single executable application documentation.
--build-snapshot#
Generates a snapshot blob when the process exits and writes it to
disk, which can be loaded later with --snapshot-blob.
When building the snapshot, if --snapshot-blob is not specified,
the generated blob will be written, by default, to snapshot.blob
in the current working directory. Otherwise it will be written to
the path specified by --snapshot-blob.
$ 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 be used to specify an entry point at
snapshot building time, thus avoiding the need of an additional entry
script at deserialization time:
$ 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 information, check out the v8.startupSnapshot API documentation.
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.
As it's complicated to ensure the serializablility of all built-in modules,
which are also growing over time, 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 would be to delay loading that module until
runtime, using either v8.startupSnapshot.setDeserializeMainFunction() or
v8.startupSnapshot.addDeserializeCallback(). If serialization for
an additional module during the snapshot building process is needed,
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 which 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 withbuilderas 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 be interpreted as regular command line arguments.
-c, --check#
Syntax check the script without executing.
--completion-bash#
Print source-able bash completion script for Node.js.
node --completion-bash > node_bash_completion
source node_bash_completion
-C condition, --conditions=condition#
Provide custom conditional exports resolution conditions.
Any number of custom string condition names are permitted.
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
--cpu-prof#
Starts the V8 CPU profiler on start up, and writes the CPU profile to disk before exit.
If --cpu-prof-dir is not specified, the generated profile is placed
in the current working directory.
If --cpu-prof-name is not specified, the generated profile is
named CPU.${yyyymmdd}.${hhmmss}.${pid}.${tid}.${seq}.cpuprofile.
$ node --cpu-prof index.js
$ ls *.cpuprofile
CPU.20190409.202950.15293.0.0.cpuprofile
If --cpu-prof-name is specified, the provided value is used as a template
for the file name. The following placeholder is supported and will be
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#
Specify the directory where the CPU profiles generated by --cpu-prof will
be placed.
The default value is controlled by the
--diagnostic-dir command-line option.
--cpu-prof-interval#
Specify the sampling interval in microseconds for the CPU profiles generated
by --cpu-prof. The default is 1000 microseconds.
--cpu-prof-name#
Specify the file name of the CPU profile generated by --cpu-prof.
--diagnostic-dir=directory#
Set the directory to which all diagnostic output files are written. Defaults to current working directory.
Affects the default output directory of:
--disable-proto=mode#
Disable 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.
--disable-sigusr1#
Disable the ability of starting a debugging session by sending a
SIGUSR1 signal to the process.
--disable-warning=code-or-type#
Stability: 2 - Stable
Disable 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#
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. This 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 is 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 the application 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.
--disallow-code-generation-from-strings#
Make built-in language features like eval and new Function that generate
code from strings throw an exception instead. This does not affect the Node.js
node:vm module.
--dns-result-order=order#
Set the default value of order in dns.lookup() and
dnsPromises.lookup(). The value could be:
ipv4first: sets defaultordertoipv4first.ipv6first: sets defaultordertoipv6first.verbatim: sets defaultordertoverbatim.
The default is verbatim and dns.setDefaultResultOrder() have higher
priority than --dns-result-order.
--enable-fips#
Enable 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#
Publish OpenSSL FIPS indicator results to the
'crypto.fips.indicator' diagnostics channel. This option requires OpenSSL
3.4 or later. It does not enable FIPS mode or change whether an operation
is permitted.
--enable-source-maps#
Enable Source Map support for stack traces.
When using a transpiler, such as TypeScript, 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. Call and return the results of the original
Error.prepareStackTrace in the 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
when Error.stack is accessed. If you access Error.stack frequently
in your application, take into account the performance implications
of --enable-source-maps.
--entry-url#
Stability: 1 - Experimental
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.
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#
Behavior is the same as --env-file, but an error is not thrown if the file
does not exist.
--env-file=file#
Loads environment variables from a file relative to the current directory,
making them available to applications on process.env. The environment
variables which configure Node.js, such as NODE_OPTIONS,
are parsed and applied. If the same variable is defined in the environment and
in the file, the value from the environment takes precedence.
You can pass multiple --env-file arguments. Subsequent files override
pre-existing variables defined in previous files.
An error is thrown if the file does not exist.
node --env-file=.env --env-file=.development.env index.js
The format of the file should be 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: `, " 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.
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, you
can 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, using cmd.exe a 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-types flag is provided.
--experimental-addon-modules#
Stability: 1.2 - Release candidate
Enable experimental import support for .node addons.
--experimental-bench#
Stability: 1 - Experimental
Enable the experimental node:bench module and command-line benchmark runner.
--experimental-config-file=path, --experimental-config-file#
Stability: 1.2 - Release candidate
If present, Node.js will look for a configuration file at the specified path.
If the path is not specified, Node.js will look for a node.config.json file
in the current working directory.
To specify a custom path, use the --experimental-config-file=path form.
The space-separated --experimental-config-file path form is not supported.
The alias --experimental-default-config-file is equivalent to
--experimental-config-file without an argument.
Node.js will read the configuration file and apply the settings. The
configuration file should be a JSON file with the following structure. vX.Y.Z
in the $schema must be replaced with the version of Node.js you are 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"
}
}
}
]
}
When configs is used, the top level may only contain $schema and
configs. Each configs item must define an integer nodeVersion and an
object config. A single top-level config does not require nodeVersion, but
if present it must match the current Node.js major version.
When a namespace is present in the
configuration file, Node.js automatically enables the corresponding flag
(e.g., --test, --watch, --permission). This allows you to configure
subsystem-specific options without explicitly passing the flag on the command line.
For example:
{
"test": {
"test-isolation": "process"
}
}
is equivalent to:
node --test --test-isolation=process
To disable the automatic flag while still using namespace options, you can
explicitly set the flag to false within the namespace:
{
"test": {
"test": false,
"test-isolation": "process"
}
}
No-op flags are not supported. Not all V8 flags are currently supported.
It is possible to use the official JSON schema to validate the configuration file, which may vary depending on the Node.js version. Each key in the configuration file corresponds to a flag that can be passed as a command-line argument. The value of the key is the value that would be passed to the flag.
For example, the configuration file above is equivalent to the following command-line arguments:
node --import amaro/strip --watch-path=src --watch-preserve-output --test-isolation=process
The priority in configuration is as follows:
- NODE_OPTIONS and command-line options
- Dotenv NODE_OPTIONS
- Configuration file
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.
Keys cannot be duplicated within the same or different namespaces.
The configuration parser will throw an error if the configuration file contains unknown keys or keys that cannot be used in a namespace.
Node.js will not sanitize or perform validation on the user-provided configuration, so NEVER use untrusted configuration files.
--experimental-default-config-file#
Stability: 1.0 - Early development
This flag is an alias for --experimental-config-file without an argument.
If present, Node.js will look for a
node.config.json file in the current working directory and load it as a
configuration file.
--experimental-dtls#
Stability: 1 - Experimental
Enable experimental support for the DTLS protocol. See the dtls documentation for details.
--experimental-eventsource#
Enable exposition of EventSource Web API on the global scope.
--experimental-import-meta-resolve#
Enable experimental import.meta.resolve() parent URL support, which allows
passing a second parentURL argument for contextual resolution.
Previously gated the entire import.meta.resolve feature.
--experimental-import-text#
Stability: 1.0 - Early development
Enable experimental support for importing modules with
with { type: 'text' }.
--experimental-inspector-network-resource#
Stability: 1.1 - Active Development
Enable experimental support for inspector network resources.
--experimental-loader=module#
This flag is discouraged and may be removed in a future version of Node.js. Please use
--importwithregister()instead.
Specify the module containing exported asynchronous module customization hooks.
module may be any string accepted as an import specifier.
This feature requires --allow-worker if used with the Permission Model.
--experimental-network-inspection#
Stability: 1 - Experimental
Enable experimental support for the network inspection with Chrome DevTools.
--experimental-package-map=<path>#
Stability: 1 - Experimental
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 be require()'d because it contains any top-level await,
this flag allows Node.js to locate and print their locations.
--experimental-quic#
Stability: 1.1 - Active development
Enable experimental support for the QUIC protocol.
--experimental-sea-config#
Stability: 1 - Experimental
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 enable ShadowRealm support.
--experimental-storage-inspection#
Stability: 1.1 - Active Development
Enable experimental support for storage inspection
--experimental-stream-iter#
Stability: 1 - Experimental
Enable the experimental node:stream/iter module.
--experimental-test-coverage#
When used in conjunction with the node:test module, 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#
Stability: 1.0 - Early development
Enable module mocking in the test runner.
This feature requires --allow-worker if used with the Permission Model.
--experimental-test-tag-filter='<expr>'#
Stability: 1.0 - Early development
Run only tests that match the provided boolean tag-filter expression. Tests
declare tags via the tags option on test(), it(), suite(), or
describe(). 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: not binds tighter than and, which binds
tighter than or. 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.
--experimental-vfs#
Stability: 1 - Experimental
Enable the experimental node:vfs module.
--experimental-vm-modules#
Enable experimental ES Module support in the node:vm module.
--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#
Stability: 1.1 - Active Development
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-fips apply.
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#
Enforces uncaughtException event 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#
Stability: 1 - Experimental
Enable experimental frozen intrinsics like Array and Object.
Only the root context is supported. There is no guarantee that
globalThis.Array is indeed the default intrinsic reference. Code may break
under this flag.
To allow polyfills to be added,
--require and --import both 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-dir is not specified, the generated profile is placed
in the current working directory.
If --heap-prof-name is not specified, the generated profile is
named Heap.${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-prof will
be placed.
The default value is controlled by the
--diagnostic-dir command-line option.
--heap-prof-interval#
Specify the average sampling interval in bytes for the heap profiles generated
by --heap-prof. The default is 512 * 1024 bytes.
--heap-prof-name#
Specify the file name of the heap profile generated by --heap-prof.
--heapsnapshot-near-heap-limit=max_count#
Writes a V8 heap snapshot to disk when the V8 heap usage is approaching the
heap limit. count should be a non-negative integer (in which case
Node.js will write no more than max_count snapshots to disk).
When generating snapshots, garbage collection may be triggered and bring
the heap usage down. Therefore multiple snapshots may be written to disk
before the Node.js instance finally runs out of memory. These heap snapshots
can be compared to determine what objects are being allocated during the
time consecutive snapshots are taken. It's not guaranteed that Node.js will
write exactly max_count snapshots to disk, but it will try
its best to generate at least one and up to max_count snapshots before the
Node.js instance runs out of memory when max_count is greater than 0.
Generating V8 snapshots takes time and memory (both 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. 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#
Enables a signal handler that causes the Node.js process to write a heap dump
when the specified signal is received. signal must be a valid signal name.
Disabled by default.
$ 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#
Print node command-line options. The output of this option is less detailed than this document.
--icu-data-dir=file#
Specify ICU data load path. (Overrides NODE_ICU_DATA.)
--import=module#
Stability: 1 - Experimental
Preload 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 in NODE_OPTIONS.
Follows ECMAScript module resolution rules.
Use --require to load a CommonJS module.
Modules preloaded with --require will run before modules preloaded with --import.
Modules are preloaded into the main thread as well as any worker threads, forked processes, or clustered processes.
--input-type=type#
This configures Node.js to interpret --eval or 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-module is passed.
If --input-type is 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. Usage of --input-type=module with
--print will throw an error, as --print does not support ES module
syntax.
--insecure-http-parser#
Enable 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
chunkedhas 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.
All the above will expose your application to request smuggling or poisoning attack. Avoid using this option.
--inspect-brk[=[host:]port]#
Activate inspector on host:port and break at start of user script.
Default host:port is 127.0.0.1:9229. If port 0 is specified,
a random available port will be used.
See V8 Inspector integration for Node.js for further explanation on Node.js debugger.
See the security warning below regarding the host
parameter usage.
--inspect-port=[host:]port#
Set the host:port to be used when the inspector is activated.
Useful when activating the inspector by sending the SIGUSR1 signal.
Except when --disable-sigusr1 is passed.
Default host is 127.0.0.1. If port 0 is specified,
a random available port will be used.
See the security warning below regarding the host
parameter usage.
--inspect-publish-uid=stderr,http#
Specify ways of the inspector web socket url exposure.
By default inspector websocket url is available in stderr and under /json/list
endpoint on http://host:port/json/list.
--inspect-wait[=[host:]port]#
Activate inspector on host:port and wait for debugger to be attached.
Default host:port is 127.0.0.1:9229. If port 0 is specified,
a random available port will be used.
See V8 Inspector integration for Node.js for further explanation on Node.js debugger.
See the security warning below regarding the host
parameter usage.
--inspect[=[host:]port]#
Activate inspector on host:port. Default is 127.0.0.1:9229. If port 0 is
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. 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 Node.js debugger.
Warning: binding inspector to a public IP:port combination is insecure#
Binding the inspector to a public IP (including 0.0.0.0) with an open port is
insecure, as it allows external hosts to connect to the inspector and perform
a remote code execution attack.
If specifying a host, make sure that either:
- The host is not accessible from public networks.
- A firewall disallows unwanted connections on the port.
More specifically, --inspect=0.0.0.0 is insecure if the port (9229 by
default) is not firewall-protected.
See the debugging security implications section for more information.
-i, --interactive#
Opens the REPL even if stdin does not appear to be a terminal.
--jitless#
Stability: 1 - Experimental. This flag is inherited from V8 and is subject to change upstream.
Disable 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.
--localstorage-file=file#
Stability: 1.2 - Release candidate.
The file used to store localStorage data. If the file does not exist, it is
created the first time localStorage is accessed. The same file may be shared
between multiple Node.js processes concurrently.
--max-http-header-size=size#
Specify the maximum size, in bytes, of HTTP headers. Defaults to 16 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-size when both are specified.
The percentage parameter 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, see net.getDefaultAutoSelectFamilyAttemptTimeout().
--no-addons#
Disable the node-addons exports condition as well as disable loading
native addons. When --no-addons is specified, calling process.dlopen or
requiring a native C++ addon will fail and throw an exception.
--no-async-context-frame#
Disables the use of AsyncLocalStorage backed by AsyncContextFrame and
uses the prior implementation which relied on async_hooks. The previous model
is retained for compatibility with Electron and for cases where the context
flow may differ. However, if a difference in flow is found please report it.
--no-deprecation#
Silence deprecation warnings.
--no-experimental-detect-module#
Disable using syntax detection to determine module type.
--no-experimental-ffi#
Stability: 1 - Experimental
Disable the experimental node:ffi module.
This flag is only available in builds with FFI support.
--no-experimental-global-navigator#
Stability: 1 - Experimental
Disable exposition of Navigator API on the global scope.
--no-experimental-repl-await#
Use this flag to disable top-level await in REPL.
--no-experimental-require-module#
Stability: 3 - Legacy: Use --no-require-module instead.
Legacy alias for --no-require-module.
--no-experimental-sqlite#
Disable the experimental node:sqlite module.
--no-experimental-websocket#
Disable exposition of <WebSocket> on the global scope.
--no-experimental-webstorage#
Stability: 1.2 - Release candidate.
Disable Web Storage support.
--no-extra-info-on-fatal-exception#
Hide extra information on fatal exception that causes exit.
--no-force-async-hooks-checks#
Disables runtime checks for async_hooks. These will still be enabled
dynamically when async_hooks is enabled.
--no-global-search-paths#
Do not search modules from global paths like $HOME/.node_modules and
$NODE_PATH.
--no-network-family-autoselection#
Disables the family autoselection algorithm unless connection options explicitly enables it.
--no-require-module#
Disable support for loading a synchronous ES module graph in require().
--no-strip-types#
Disable type-stripping for TypeScript files. For more information, see the TypeScript type-stripping documentation.
--no-warnings#
Silence all process warnings (including deprecations).
--no-worker-snapshot#
Stability: 1 - Experimental
Start worker threads by running the internal bootstrap from scratch instead of deserializing the bootstrapped context from the built-in startup snapshot.
--node-memory-debug#
Enable extra debug checks for memory leaks in Node.js internals. This is usually only useful for developers debugging Node.js itself.
--openssl-config=file#
Load an OpenSSL configuration file on startup. The file can activate an OpenSSL 3 FIPS provider or configure a FIPS-capable OpenSSL 1.1.1 build. See FIPS mode.
This option takes precedence over the OPENSSL_CONF environment variable.
--openssl-legacy-provider#
Enable OpenSSL 3.0 legacy provider. For more information please see OSSL_PROVIDER-legacy.
--openssl-shared-config#
Enable OpenSSL default configuration section, openssl_conf to be read from
the OpenSSL configuration file. The default configuration file is named
openssl.cnf but this can be changed using the environment variable
OPENSSL_CONF, or by using the command line option --openssl-config.
The location of the default OpenSSL configuration file depends on how OpenSSL
is being linked to Node.js. Sharing the OpenSSL configuration may have unwanted
implications and it is recommended to use a configuration section specific to
Node.js which is nodejs_conf and is default when this option is not used.
--pending-deprecation#
Emit pending deprecation warnings.
Pending deprecations are generally identical to a runtime deprecation with the
notable exception that they are turned off by default and will not be emitted
unless either the --pending-deprecation command-line flag, or the
NODE_PENDING_DEPRECATION=1 environment variable, is set. Pending deprecations
are used to provide a kind of selective "early warning" mechanism that
developers may leverage to detect deprecated API usage.
--permission#
Enable the Permission Model for current process. When enabled, the following permissions are restricted:
See also
--permission-auditfor an audit-only mode that logs violations without denying access.
- 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
--permission-audit#
Enable audit mode for the permission model. When enabled, permission checks
are performed but access is not denied — no ERR_ACCESS_DENIED error is
thrown. Instead, each permission violation is published through the
node:diagnostics_channel module, and execution continues normally.
This flag does not require --permission to be specified. The
--allow-* flags are not needed in audit mode, since no
access is denied.
Audit mode is useful for discovering what permissions your application
requires before deploying 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.
--preserve-symlinks#
Instructs the module loader to preserve symbolic links when resolving and caching modules.
By default, when Node.js loads a module from a path that is symbolically linked
to a different on-disk location, Node.js will dereference the link and use 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, this default behavior
is acceptable. However, when using symbolically linked peer dependencies, as
illustrated in the example below, the default behavior causes an exception to
be thrown if moduleA attempts to require moduleB as 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 instructs Node.js to use the
symlink path for modules as opposed to the real path, allowing symbolically
linked peer dependencies to 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).
The --preserve-symlinks flag does not apply to the main module, which allows
node --preserve-symlinks node_module/.bin/<foo> to work. To apply the same
behavior for the main module, also use --preserve-symlinks-main.
--preserve-symlinks-main#
Instructs the module loader to preserve symbolic links when resolving and
caching the main module (require.main).
This flag exists so that the main module can be opted-in to the same behavior
that --preserve-symlinks gives to all other imports; they are separate flags,
however, for backward compatibility with older Node.js versions.
--preserve-symlinks-main does not imply --preserve-symlinks; use
--preserve-symlinks-main in addition to
--preserve-symlinks when it is not desirable to follow symlinks before
resolving relative paths.
See --preserve-symlinks for more information.
-p, --print "script"#
Identical to -e but prints the result.
--process-timeout=duration#
Stability: 1.1 - Active development
Exits the process with code 124 if it is still running after duration,
measured from the start of the process. duration is a positive integer
followed by a unit: ms, s, m, or h, for example 500ms, 30s, 5m, or
1h. The exit code matches the one used by the timeout(1) command.
Before exiting, Node.js prints what the main thread was doing and which resources were keeping the event loop alive to stderr:
$ 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)
If the main thread was executing JavaScript, its stack trace is printed instead.
Use --report-on-process-timeout to also generate a diagnostic report.
The process exits without emitting the 'beforeExit' and 'exit' events, as
the JavaScript code may be what keeps the process running. Code coverage and
profiles, such as those enabled with NODE_V8_COVERAGE=dir or
--cpu-prof, are still written.
If the main thread does not respond within two seconds, for example because it
is blocked in a synchronous operation such as child_process.execSync(),
Node.js exits immediately without printing the stack trace and resources.
This option is not allowed in NODE_OPTIONS, and 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() and
session.connectToMainThread() throw, and requests to activate the
inspector with SIGUSR1 are ignored.
Child processes that inherit process.execArgv, such as those created with
child_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.
--prof-process#
Process V8 profiler output generated using the V8 option --prof.
--redirect-warnings=file#
Write process warnings to the given file instead of printing to stderr. The file will be created if it does not exist, and will be appended to if it does. If an error occurs while attempting to write the warning to the file, the warning will be written to stderr instead.
The file name may be an absolute path. If it is not, the default directory it
will be written to is controlled by the
--diagnostic-dir command-line option.
--report-compact#
Write reports in a compact format, single-line JSON, more easily consumable by log processing systems than the default multi-line format designed for human consumption.
--report-dir=directory, --report-directory=directory#
Location at which the report will be generated.
--report-exclude-env#
When --report-exclude-env is passed the diagnostic report generated will not
contain the environmentVariables data.
--report-exclude-network#
Exclude header.networkInterfaces from the diagnostic report. By default
this is not set and the network interfaces are included.
--report-filename=filename#
Name of the file to which the report will be written.
If the filename is set to 'stdout' or 'stderr', the report is written to
the stdout or stderr of the process respectively.
--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. Useful to inspect various diagnostic data elements such as heap, stack, event loop state, resource consumption etc. to reason about the fatal error.
--report-on-process-timeout#
Stability: 1.1 - Active development
Enables the report to be generated when --process-timeout expires, 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 are blocked in a synchronous operation such
as child_process.execSync(), are left out of it.
--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 the signal for report generation (not supported on Windows).
Default signal is SIGUSR2.
--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.
-r, --require module#
Preload the specified module at startup.
Follows require()'s module resolution
rules. module may be either a path to a file, or a node module name.
Modules preloaded with --require will run before modules preloaded with --import.
Modules are preloaded into the main thread as well as any worker threads, forked processes, or clustered processes.
--run#
This runs a specified command from a package.json's "scripts" object.
If a missing "command" is provided, it will list the available scripts.
Passing --run without 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
Intentional limitations#
node --run is not meant to match the behaviors of npm run or of the run
commands of other package managers. The Node.js implementation is intentionally
more limited, in order to focus on top performance for the most common use
cases.
Some features of other run implementations that are intentionally excluded
are:
- Running
preorpostscripts in addition to the specified script. - Defining package manager-specific environment variables.
Environment variables#
The following environment variables are set when running a script with --run:
NODE_RUN_SCRIPT_NAME: The name of the script being run. For example, if--runis used to runtest, the value of this variable will betest.NODE_RUN_PACKAGE_JSON_PATH: The path to thepackage.jsonthat is being processed.
Environment variables loaded from a file with --env-file are not applied
to the command executed by --run.
--secure-heap-min=n#
When using --secure-heap, the --secure-heap-min flag specifies the
minimum allocation from the secure heap. The minimum value is 2.
The maximum value is the lesser of --secure-heap or 2147483647.
The value given must be a power of two.
--secure-heap=n#
Initializes an OpenSSL secure heap of n bytes. 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#
Stability: 1 - Experimental
When used with --build-snapshot, --snapshot-blob specifies the path
where the generated snapshot blob is written to. If not specified, the
generated blob is written to snapshot.blob in 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.
--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-isolation is set to 'none', this flag is ignored and
concurrency is one. Otherwise, concurrency defaults to
os.availableParallelism() - 1.
--test-coverage-branches=threshold#
Stability: 1 - Experimental
Require a minimum percent of covered branches. If code coverage does not reach
the threshold specified, the process will exit with code 1.
--test-coverage-exclude#
Stability: 1 - Experimental
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-exclude and --test-coverage-include are 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#
Stability: 1 - Experimental
Require a minimum percent of covered functions. If code coverage does not reach
the threshold specified, the process will exit with code 1.
--test-coverage-include#
Stability: 1 - Experimental
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-exclude and --test-coverage-include are provided,
files must meet both criteria to be included in the coverage report.
--test-coverage-include-all#
Stability: 1 - Experimental
Includes source files that were never loaded by the test run in the coverage report, where they are reported as having zero coverage.
Candidate files are searched for in the current working directory, and are
subject to the same --test-coverage-include and --test-coverage-exclude
filtering as the rest of the report.
--test-coverage-lines=threshold#
Stability: 1 - Experimental
Require a minimum percent of covered lines. If code coverage does not reach
the threshold specified, the process will exit with code 1.
--test-force-exit#
Configures the test runner to exit the process once all known tests have finished executing even if the event loop would otherwise remain active.
--test-global-setup=module#
Stability: 1.0 - Early development
Specify a module that will be evaluated before all tests are executed and can be used to setup global state or fixtures for tests.
See the documentation on global setup and teardown for more details.
--test-isolation=mode#
Configures the type of test isolation used in the test runner. When mode is
'process', each test file is run in a 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 --test flag is not
present. See the test runner execution model section for more information.
--test-name-pattern#
A regular expression that configures the test runner to only execute tests whose name matches the provided pattern. See the documentation on filtering tests by name for more details.
If both --test-name-pattern and --test-skip-pattern are supplied,
tests must satisfy both requirements in order to be executed.
--test-only#
Configures the test runner to only execute top level tests that have the only
option set. This flag is not necessary when test isolation is disabled.
--test-random-seed#
Set 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 between 0 and 4294967295.
This flag cannot be used with --watch or --test-rerun-failures.
--test-randomize#
Randomize test execution order. This 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.
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 --watch or --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 allowing the test runner to persist the state of the test suite between runs. The test runner will use this file to determine which tests have already succeeded or failed, allowing for re-running of failed tests without having to re-run the entire test suite. 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 a format of <index>/<total>, where
indexis a positive integer, index of divided parts.totalis a positive integer, total of divided part.
This command will divide all tests files into total equal parts,
and will run only those that happen to be in an index part.
For example, to split your tests 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 provided pattern. See the documentation on filtering tests by name for more details.
If both --test-name-pattern and --test-skip-pattern are supplied,
tests must satisfy both requirements in order to be executed.
--test-timeout#
A number of milliseconds the test execution will fail after. If unspecified,
subtests inherit this value from their parent. The default value is Infinity.
--test-update-snapshots#
Regenerates the snapshot files used by the test runner for snapshot testing.
--throw-deprecation#
Throw errors for deprecations.
--title=title#
Set process.title on startup.
--tls-cipher-list=list#
Specify an alternative default TLS cipher list. Requires Node.js to be built with crypto support (default).
--tls-keylog=file#
Log TLS key material to a file. The key material is in NSS SSLKEYLOGFILE
format and can be used by software (such as Wireshark) to decrypt the TLS
traffic.
--tls-max-v1.2#
Set tls.DEFAULT_MAX_VERSION to 'TLSv1.2'. Use to disable support for
TLSv1.3.
--tls-max-v1.3#
Set default tls.DEFAULT_MAX_VERSION to 'TLSv1.3'. Use to enable support
for TLSv1.3.
--tls-min-v1.0#
Set default tls.DEFAULT_MIN_VERSION to 'TLSv1'. Use for compatibility with
old TLS clients or servers.
--tls-min-v1.1#
Set default tls.DEFAULT_MIN_VERSION to 'TLSv1.1'. Use for compatibility
with old TLS clients or servers.
--tls-min-v1.2#
Set default tls.DEFAULT_MIN_VERSION to '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 default tls.DEFAULT_MIN_VERSION to '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#
Print information 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 inf 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-env does, this prints the JavaScript stack trace of the access.
--trace-env-native-stack#
In addition to what --trace-env does, 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. invoking process.exit().
--trace-require-module=mode#
Prints information about usage of Loading ECMAScript modules using require().
When mode is all, all usage is printed. When mode is no-node-modules, usage
from the node_modules folder is excluded.
--trace-sigint#
Prints a stack trace on SIGINT.
--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 an Error is printed, whereas this makes Node.js also
print the stack trace associated with throwing the value (which does not need
to be an Error instance).
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#
Using this flag allows to change what should happen when an unhandled rejection occurs. One of the following modes can be chosen:
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 to 1.none: Silence all warnings.
If a rejection happens during the command line entry point's ES module static loading phase, it will always raise it as an uncaught exception.
--use-bundled-ca, --use-openssl-ca#
Use bundled Mozilla CA store as supplied by current Node.js version or use OpenSSL's default CA store. The default store is selectable at build-time.
The bundled CA store, as supplied by Node.js, is a snapshot of Mozilla CA store that is fixed at release time. It is identical on all supported platforms.
Using OpenSSL store allows for external modifications of the store. For most Linux and BSD distributions, this store is maintained by the distribution maintainers and system administrators. OpenSSL CA store location is dependent on configuration of the OpenSSL library but this can be altered at runtime using environment variables.
See SSL_CERT_DIR and SSL_CERT_FILE.
--use-env-proxy#
Stability: 1.1 - Active Development
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. 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 is equivalent to setting the NODE_USE_ENV_PROXY=1 environment variable.
When both are set, --use-env-proxy takes precedence.
--use-largepages=mode#
This option is no longer supported and a 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:
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-ca option and the NODE_EXTRA_CA_CERTS environment 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
- Trust:
- 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”.
- Trust:
On Windows, the following settings are respected:
- Local Machine (accessed via
certlm.msc)- Trust:
- 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
- Trust:
- Current User (accessed via
certmgr.msc)- Trust:
- Trusted Root Certification Authorities
- Enterprise Trust -> Group Policy -> Trusted Root Certification Authorities
- Trust:
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.
--v8-options#
Print V8 command-line options.
--v8-pool-size=num#
Set V8's thread pool size which will be used to allocate background jobs.
If set to 0 then 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.
-v, --version#
Print node's version.
--vfs-load=source#
source<string>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-path to specify what paths to watch.
This flag cannot be combined with
--check, --eval, --interactive, or the REPL.
Note: The --watch flag requires a file path as an argument and is incompatible
with --run or inline script input, as --run takes precedence and ignores watch
mode. If no file is provided, Node.js will exit with status code 9.
node --watch index.js
--watch-kill-signal#
Stability: 1.1 - Active Development
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-path implicitly enables --watch, which requires a file path
and is incompatible with --run, as --run takes 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#
Disable the clearing of the console when watch mode restarts the process.
node --watch --watch-preserve-output test.js
--zero-fill-buffers#
Automatically zero-fills all newly allocated Buffer instances.
Environment variables#
Stability: 2 - Stable
FORCE_COLOR=[1, 2, 3]#
The FORCE_COLOR environment 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_CACHE=dir#
Enable the module compile cache for the Node.js instance. See the documentation of module compile cache for details.
NODE_COMPILE_CACHE_PORTABLE=1#
When set to 1, 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_READONLY=1#
When set to 1, the module compile cache only reads existing entries from its directory: nothing is written to it and it is not created if missing.
NODE_DEBUG=module[,…]#
','-separated list of core modules that should print debug information.
NODE_DEBUG_NATIVE=module[,…]#
','-separated list of core C++ modules that should print debug information.
NODE_DISABLE_COLORS=1#
When set, colors will not be used in the REPL.
NODE_DISABLE_COMPILE_CACHE=1#
Stability: 1.1 - Active Development
Disable the module compile cache for the Node.js instance. See the documentation of module compile cache for details.
NODE_EXTRA_CA_CERTS=file#
When set, the well known "root" CAs (like VeriSign) will be extended with the
extra certificates in file. The 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.
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.
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.
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.
NODE_OPTIONS=options...#
A space-separated list of command-line options. 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[:…]#
':'-separated list of directories prefixed to the module search path.
On Windows, this is a ';'-separated list instead.
NODE_PENDING_DEPRECATION=1#
When set to 1, emit pending deprecation warnings.
Pending deprecations are generally identical to a runtime deprecation with the
notable exception that they are turned off by default and will not be emitted
unless either the --pending-deprecation command-line flag, or the
NODE_PENDING_DEPRECATION=1 environment variable, is set. Pending deprecations
are used to provide a kind of selective "early warning" mechanism that
developers may leverage to detect deprecated API usage.
NODE_PENDING_PIPE_INSTANCES=instances#
Set the number of pending pipe instance handles when the pipe server is waiting for connections. This setting applies to Windows only.
NODE_PRESERVE_SYMLINKS=1#
When set to 1, instructs the module loader to preserve symbolic links when
resolving and caching modules.
NODE_REDIRECT_WARNINGS=file#
When set, process warnings will be emitted to the given file instead of
printing to stderr. The file will be created if it does not exist, and will be
appended to if it does. If an error occurs while attempting to write the
warning to the file, the warning will be written 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 which will be loaded in place of the built-in REPL.
Overriding this value to an empty string ('') will use the built-in REPL.
NODE_REPL_HISTORY=file#
Path to the file used to store the persistent REPL history. The default path is
~/.node_repl_history, which is overridden by this variable. Setting the value
to an empty string ('' or ' ') disables persistent REPL history.
NODE_SKIP_PLATFORM_CHECK=value#
If value equals '1', the check for a supported platform is skipped during
Node.js startup. Node.js might not execute correctly. Any issues encountered
on unsupported platforms will not be fixed.
NODE_TEST_CONTEXT=value#
If value equals 'child', test reporter options will be overridden and test
output will be sent to stdout in the TAP format. If any other value is provided,
Node.js makes no guarantees about the reporter format used or its stability.
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.
NODE_USE_ENV_PROXY=1#
Stability: 1.1 - Active Development
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. 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.
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.
When both are set, --use-system-ca takes precedence.
NODE_V8_COVERAGE=dir#
When set, Node.js will begin outputting V8 JavaScript code coverage and
Source Map data to the directory provided as an argument (coverage
information is written as JSON to files with a coverage prefix).
NODE_V8_COVERAGE will automatically propagate to subprocesses, making it
easier to instrument applications that call the child_process.spawn() family
of functions. NODE_V8_COVERAGE can be set to an empty string, to prevent
propagation.
Coverage output#
Coverage is output as an array of ScriptCoverage objects on the top-level
key result:
{
"result": [
{
"scriptId": "67",
"url": "internal/tty.js",
"functions": []
}
]
}
Source map cache#
Stability: 1 - Experimental
If found, source map data is appended to the top-level key source-map-cache
on the JSON coverage object.
source-map-cache is an object with keys representing the files source maps
were extracted from, and values which include the raw source-map URL
(in the key url), the parsed Source Map v3 information (in the key data),
and the line lengths of the source file (in the key lineLengths).
{
"result": [
{
"scriptId": "68",
"url": "file:///absolute/path/to/source.js",
"functions": []
}
],
"source-map-cache": {
"file:///absolute/path/to/source.js": {
"url": "./path-to-map.json",
"data": {
"version": 3,
"sources": [
"file:///absolute/path/to/original.js"
],
"names": [
"Foo",
"console",
"info"
],
"mappings": "MAAMA,IACJC,YAAaC",
"sourceRoot": "./"
},
"lineLengths": [
13,
62,
38,
27
]
}
}
}
NO_COLOR=<any>#
NO_COLOR is an alias for NODE_DISABLE_COLORS. The value of the
environment variable is arbitrary.
OPENSSL_CONF=file#
Load 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. This 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.
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.
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.
TZ#
The TZ environment variable is used to specify the timezone configuration.
While Node.js does not support all of the various ways that TZ is handled in
other environments, 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.
$ TZ=Europe/Dublin node -pe "new Date().toString()"
Wed May 12 2021 20:30:48 GMT+0100 (Irish Standard Time)
UV_THREADPOOL_SIZE=size#
Set 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 do not exist, libuv's threadpool is used to create asynchronous node APIs based on synchronous system APIs. Node.js APIs that use the threadpool are:
- all
fsAPIs, other than the file watcher APIs and those that are explicitly synchronous - asynchronous crypto APIs such as
crypto.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. In order to
mitigate this issue, 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). However, setting this from inside
the process using process.env.UV_THREADPOOL_SIZE=size is not guaranteed to work
as the threadpool would have been created as part of the runtime initialisation
much before user code is run. For more information, see the libuv threadpool documentation.
Useful V8 options#
V8 has its own set of CLI options. Any V8 CLI option that is provided to node
will be passed on to V8 to handle. V8's options have no stability guarantee.
The V8 team themselves don't consider them to be part of their formal API,
and reserve the right to change them at any time. Likewise, they are not
covered by the Node.js stability guarantees. Many of the V8
options are of interest only to V8 developers. Despite this, there is a small
set of V8 options that are widely applicable to Node.js, and they are
documented here:
--abort-on-uncaught-exception#
--disallow-code-generation-from-strings#
--enable-etw-stack-walking#
--expose-gc#
--harmony-shadow-realm#
--heap-snapshot-on-oom#
--interpreted-frames-native-stack#
--jitless#
--max-heap-size#
Specifies the maximum heap size (in megabytes) for the process.
This option is typically used to limit the amount of memory the process can use for its JavaScript heap.
--max-old-space-size=SIZE (in MiB)#
Sets the max memory size of V8's old memory section. As memory consumption approaches the limit, V8 will spend more time on garbage collection in an effort to free unused memory.
On a machine with 2 GiB of memory, consider setting this to 1536 (1.5 GiB) to leave some memory for other uses and avoid swapping.
node --max-old-space-size=1536 index.js
--max-semi-space-size=SIZE (in MiB)#
Sets the maximum semi-space size for V8's scavenge garbage collector in MiB (mebibytes). Increasing the max size of a semi-space may improve throughput for Node.js at the cost of more memory consumption.
Since the young generation size of the V8 heap is three times (see
YoungGenerationSizeFromSemiSpaceSize in V8) the size of the semi-space,
an increase of 1 MiB to semi-space applies to each of the three individual
semi-spaces and causes the heap size to increase by 3 MiB. The throughput
improvement depends on your workload (see #42511).
The default value depends on the memory limit. For example, on 64-bit systems with a memory limit of 512 MiB, the max size of a semi-space defaults to 1 MiB. For memory limits up to and including 2GiB, the default max size of a semi-space will be less than 16 MiB on 64-bit systems.
To get the best configuration for your application, you should try different max-semi-space-size values when running benchmarks for your application.
For example, benchmark on a 64-bit systems:
for MiB in 16 32 64 128; do
node --max-semi-space-size=$MiB index.js
done
--perf-basic-prof#
--perf-basic-prof-only-functions#
--perf-prof#
--perf-prof-unwinding-info#
--prof#
--security-revert#
--stack-trace-limit=limit#
The maximum number of stack frames to collect in an error's stack trace. Setting it to 0 disables stack trace collection. The default value is 10.
node --stack-trace-limit=12 -p -e "Error.stackTraceLimit" # prints 12
Console#
Stability: 2 - Stable
The node:console module provides a simple debugging console that is similar to
the JavaScript console mechanism provided by web browsers.
The module exports two specific components:
- A
Consoleclass with methods such asconsole.log(),console.error(), andconsole.warn()that can be used to write to any Node.js stream. - A global
consoleinstance configured to write toprocess.stdoutandprocess.stderr. The globalconsolecan be used without callingrequire('node:console').
Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. Programs that desire to depend on the synchronous / asynchronous behavior of the console functions should first figure out the nature of console's backing stream. This is because the stream is dependent on the underlying platform and standard stream configuration of the current process. See the note on process I/O for more information.
Example using the global console:
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
Class: Console#
The Console class can be used to create a simple logger with configurable
output streams and can be accessed using either require('node:console').Console
or console.Console (or their destructured counterparts):
import { Console } from 'node:console';const { Console } = require('node:console');
const { Console } = console;
new Console(stdout[, stderr][, ignoreErrors])#
new Console(options)#
options<Object>stdout<stream.Writable>stderr<stream.Writable>ignoreErrors<boolean>Ignore errors when writing to the underlying streams. Default:true.colorMode<boolean>|<string>Set color support for thisConsoleinstance. Setting totrueenables coloring while inspecting values. Setting tofalsedisables coloring while inspecting values. Setting to'auto'makes color support depend on the value of theisTTYproperty and the value returned bygetColorDepth()on the respective stream. This option can not be used, ifinspectOptions.colorsis set as well. Default:'auto'.inspectOptions<Object>|<Map>Specifies options that are passed along toutil.inspect(). Can be an options object or, if different options for stdout and stderr are desired, aMapfrom stream objects to options.groupIndentation<number>Set group indentation. Default:2.
Creates a new Console with one or two writable stream instances. stdout is a
writable stream to print log or info output. stderr is used for warning or
error output. If stderr is not provided, stdout is used for stderr.
import { createWriteStream } from 'node:fs'; import { Console } from 'node:console'; // Alternatively // const { Console } = console; const output = createWriteStream('./stdout.log'); const errorOutput = createWriteStream('./stderr.log'); // Custom simple logger const logger = new Console({ stdout: output, stderr: errorOutput }); // use it like console const count = 5; logger.log('count: %d', count); // In stdout.log: count 5const fs = require('node:fs'); const { Console } = require('node:console'); // Alternatively // const { Console } = console; const output = fs.createWriteStream('./stdout.log'); const errorOutput = fs.createWriteStream('./stderr.log'); // Custom simple logger const logger = new Console({ stdout: output, stderr: errorOutput }); // use it like console const count = 5; logger.log('count: %d', count); // In stdout.log: count 5
The global console is a special Console whose output is sent to
process.stdout and process.stderr. It is equivalent to calling:
new Console({ stdout: process.stdout, stderr: process.stderr });
console.assert(value[, ...message])#
value<any>The value tested for being truthy....message<any>All arguments besidesvalueare used as error message.
console.assert() writes a message if value is falsy or omitted. It only
writes a message and does not otherwise affect execution. The output always
starts with "Assertion failed". If provided, message is formatted using
util.format().
If value is truthy, nothing happens.
console.assert(true, 'does nothing');
console.assert(false, 'Whoops %s work', 'didn\'t');
// Assertion failed: Whoops didn't work
console.assert();
// Assertion failed
console.clear()#
When stdout is a TTY, calling console.clear() will attempt to clear the
TTY. When stdout is not a TTY, this method does nothing.
The specific operation of console.clear() can vary across operating systems
and terminal types. For most Linux operating systems, console.clear()
operates similarly to the clear shell command. On Windows, console.clear()
will clear only the output in the current terminal viewport for the Node.js
binary.
console.count([label])#
label<string>The display label for the counter. Default:'default'.
Maintains an internal counter specific to label and outputs to stdout the
number of times console.count() has been called with the given label.
> console.count()
default: 1
undefined
> console.count('default')
default: 2
undefined
> console.count('abc')
abc: 1
undefined
> console.count('xyz')
xyz: 1
undefined
> console.count('abc')
abc: 2
undefined
> console.count()
default: 3
undefined
>
console.countReset([label])#
label<string>The display label for the counter. Default:'default'.
Resets the internal counter specific to label.
> console.count('abc');
abc: 1
undefined
> console.countReset('abc');
undefined
> console.count('abc');
abc: 1
undefined
>
console.debug(data[, ...args])#
The console.debug() function is an alias for console.log().
console.dir(obj[, options])#
obj<any>options<Object>showHidden<boolean>Iftruethen the object's non-enumerable and symbol properties will be shown too. Default:false.depth<number>Tellsutil.inspect()how many times to recurse while formatting the object. This is useful for inspecting large complicated objects. To make it recurse indefinitely, passnull. Default:2.colors<boolean>Iftrue, then the output will be styled with ANSI color codes. Colors are customizable; see customizingutil.inspect()colors. Default:false.
Uses util.inspect() on obj and prints the resulting string to stdout.
This function bypasses any custom inspect() function defined on obj.
console.dirxml(...data)#
...data<any>
This method calls console.log() passing it the arguments received.
This method does not produce any XML formatting.
console.error([data][, ...args])#
Prints to stderr with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3) (the arguments are all passed to util.format()).
const code = 5;
console.error('error #%d', code);
// Prints: error #5, to stderr
console.error('error', code);
// Prints: error 5, to stderr
If formatting elements (e.g. %d) are not found in the first string then
util.inspect() is called on each argument and the resulting string
values are concatenated. See util.format() for more information.
console.group([...label])#
...label<any>
Increases indentation of subsequent lines by spaces for groupIndentation
length.
If one or more labels are provided, those are printed first without the
additional indentation.
console.groupCollapsed()#
An alias for console.group().
console.groupEnd()#
Decreases indentation of subsequent lines by spaces for groupIndentation
length.
console.info([data][, ...args])#
The console.info() function is an alias for console.log().
console.log([data][, ...args])#
Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3) (the arguments are all passed to util.format()).
const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout
See util.format() for more information.
console.table(tabularData[, properties])#
Try to construct a table with the columns of the properties of tabularData
(or use properties) and rows of tabularData and log it. Falls back to just
logging the argument if it can't be parsed as tabular.
// These can't be parsed as tabular data
console.table(Symbol());
// Symbol()
console.table(undefined);
// undefined
console.table([{ a: 1, b: 'Y' }, { a: 'Z', b: 2 }]);
// ┌─────────┬─────┬─────┐
// │ (index) │ a │ b │
// ├─────────┼─────┼─────┤
// │ 0 │ 1 │ 'Y' │
// │ 1 │ 'Z' │ 2 │
// └─────────┴─────┴─────┘
console.table([{ a: 1, b: 'Y' }, { a: 'Z', b: 2 }], ['a']);
// ┌─────────┬─────┐
// │ (index) │ a │
// ├─────────┼─────┤
// │ 0 │ 1 │
// │ 1 │ 'Z' │
// └─────────┴─────┘
console.time([label])#
label<string>Default:'default'
Starts a timer that can be used to compute the duration of an operation. Timers
are identified by a unique label. Use the same label when calling
console.timeEnd() to stop the timer and output the elapsed time in
suitable time units to stdout. For example, if the elapsed
time is 3869ms, console.timeEnd() displays "3.869s".
console.timeEnd([label])#
label<string>Default:'default'
Stops a timer that was previously started by calling console.time() and
prints the result to stdout:
console.time('bunch-of-stuff');
// Do a bunch of stuff.
console.timeEnd('bunch-of-stuff');
// Prints: bunch-of-stuff: 225.438ms
console.timeLog([label][, ...data])#
For a timer that was previously started by calling console.time(), prints
the elapsed time and other data arguments to stdout:
console.time('process');
const value = expensiveProcess1(); // Returns 42
console.timeLog('process', value);
// Prints "process: 365.227ms 42".
doExpensiveProcess2(value);
console.timeEnd('process');
console.trace([message][, ...args])#
Prints to stderr the string 'Trace: ', followed by the util.format()
formatted message and stack trace to the current position in the code.
console.trace('Show me');
// Prints: (stack trace will vary based on where trace is called)
// Trace: Show me
// at repl:2:9
// at REPLServer.defaultEval (repl.js:248:27)
// at bound (domain.js:287:14)
// at REPLServer.runBound [as eval] (domain.js:300:12)
// at REPLServer.<anonymous> (repl.js:412:12)
// at emitOne (events.js:82:20)
// at REPLServer.emit (events.js:169:7)
// at REPLServer.Interface._onLine (readline.js:210:10)
// at REPLServer.Interface._line (readline.js:549:8)
// at REPLServer.Interface._ttyWrite (readline.js:826:14)
console.warn([data][, ...args])#
The console.warn() function is an alias for console.error().
Inspector only methods#
The following methods are exposed by the V8 engine in the general API but do
not display anything unless used in conjunction with the inspector
(--inspect flag).
console.profile([label])#
label<string>
This method does not display anything unless used in the inspector. The
console.profile() method starts a JavaScript CPU profile with an optional
label until console.profileEnd() is called. The profile is then added to
the Profile panel of the inspector.
console.profile('MyLabel');
// Some code
console.profileEnd('MyLabel');
// Adds the profile 'MyLabel' to the Profiles panel of the inspector.
console.profileEnd([label])#
label<string>
This method does not display anything unless used in the inspector. Stops the
current JavaScript CPU profiling session if one has been started and prints
the report to the Profiles panel of the inspector. See
console.profile() for an example.
If this method is called without a label, the most recently started profile is stopped.
console.timeStamp([label])#
label<string>
This method does not display anything unless used in the inspector. The
console.timeStamp() method adds an event with the label 'label' to the
Timeline panel of the inspector.
Crypto#
Stability: 2 - Stable
The node:crypto module provides cryptographic functionality that includes a
set of wrappers for OpenSSL's hash, message authentication code (MAC), cipher,
decipher, sign, verify, and key encapsulation mechanism (KEM) functions.
const { createHmac } = await import('node:crypto'); const secret = 'abcdefg'; const hash = createHmac('sha256', secret) .update('I love cupcakes') .digest('hex'); console.log(hash); // Prints: // c0fa1bc00531bd78ef38c628449c5102aeabd49b5dc3a2a516ea6ea959d6658econst { createHmac } = require('node:crypto'); const secret = 'abcdefg'; const hash = createHmac('sha256', secret) .update('I love cupcakes') .digest('hex'); console.log(hash); // Prints: // c0fa1bc00531bd78ef38c628449c5102aeabd49b5dc3a2a516ea6ea959d6658e
Determining if crypto support is unavailable#
It is possible for Node.js to be built without including support for the
node:crypto module. In such cases, attempting to import from crypto or
calling require('node:crypto') will result in an error being thrown.
When using CommonJS, the error thrown can be caught using try/catch:
let crypto;
try {
crypto = require('node:crypto');
} catch (err) {
console.error('crypto support is disabled!');
}
When using the lexical ESM import keyword, the error can only be
caught if a handler for process.on('uncaughtException') is registered
before any attempt to load the module is made (using, for instance,
a preload module).
When using ESM, if there is a chance that the code may be run on a build
of Node.js where crypto support is not enabled, consider using the
import() function instead of the lexical import keyword:
let crypto;
try {
crypto = await import('node:crypto');
} catch (err) {
console.error('crypto support is disabled!');
}
Asymmetric key types#
The following lists group the asymmetric key types recognized by the
KeyObject API by the complete set of formats supported for importing and
exporting each type.
Formats: 'pem', 'der'
'dh'(Diffie-Hellman) — OID1.2.840.113549.1.3.1'dsa'— OID1.2.840.10040.4.1'rsa-pss'— OID1.2.840.113549.1.1.10
Formats: 'pem', 'der', 'jwk'
'rsa'— OID1.2.840.113549.1.1.1
Formats: 'pem', 'der', 'jwk', 'raw-public', 'raw-private'
'ec'(Elliptic curve) — OID1.2.840.10045.2.1'ed25519'— OID1.3.101.112'ed448'— OID1.3.101.113'slh-dsa-sha2-128f'1 — OID2.16.840.1.101.3.4.3.21'slh-dsa-sha2-128s'1 — OID2.16.840.1.101.3.4.3.20'slh-dsa-sha2-192f'1 — OID2.16.840.1.101.3.4.3.23'slh-dsa-sha2-192s'1 — OID2.16.840.1.101.3.4.3.22'slh-dsa-sha2-256f'1 — OID2.16.840.1.101.3.4.3.25'slh-dsa-sha2-256s'1 — OID2.16.840.1.101.3.4.3.24'slh-dsa-shake-128f'1 — OID2.16.840.1.101.3.4.3.27'slh-dsa-shake-128s'1 — OID2.16.840.1.101.3.4.3.26'slh-dsa-shake-192f'1 — OID2.16.840.1.101.3.4.3.29'slh-dsa-shake-192s'1 — OID2.16.840.1.101.3.4.3.28'slh-dsa-shake-256f'1 — OID2.16.840.1.101.3.4.3.31'slh-dsa-shake-256s'1 — OID2.16.840.1.101.3.4.3.30'x25519'— OID1.3.101.110'x448'— OID1.3.101.111
Formats: 'pem', 'der', 'jwk', 'raw-public', 'raw-seed'
Key formats#
Asymmetric keys can be represented in several formats. The recommended
approach is to import key material into a KeyObject once and reuse it
for all subsequent operations, as this avoids repeated parsing and delivers
the best performance.
When a KeyObject is not practical - for example, when key material
arrives in a protocol message and is used only once - most cryptographic
functions also accept a PEM string or an object specifying the format
and key material directly. See crypto.createPublicKey(),
crypto.createPrivateKey(), and keyObject.export() for the full
options accepted by each format.
KeyObject#
A KeyObject is the in-memory representation of a parsed key. It is
created by crypto.createPublicKey(), crypto.createPrivateKey(),
crypto.createSecretKey(), or key generation functions such as
crypto.generateKeyPair(). The first cryptographic operation with a given
KeyObject may be slower than subsequent ones because OpenSSL lazily
initializes internal caches on first use.
PEM and DER#
PEM and DER are the traditional encoding formats for asymmetric keys based on ASN.1 structures.
- PEM is a text encoding that wraps Base64-encoded DER data between
header and footer lines (e.g.
-----BEGIN PUBLIC KEY-----). PEM strings can be passed directly to most cryptographic operations. - DER is the binary encoding of the same ASN.1 structures. When providing
DER input, the
type(typically'spki'or'pkcs8') must be specified explicitly.
JSON Web Key (JWK)#
JSON Web Key (JWK) is a JSON-based key representation defined in RFC 7517. JWK encodes each key component as an individual Base64url-encoded value inside a JSON object. For RSA keys, JWK avoids ASN.1 parsing overhead and is the fastest serialized import format.
Raw key formats#
Stability: 1.1 - Active development
The 'raw-public', 'raw-private', and 'raw-seed' key formats allow
importing and exporting raw key material without any encoding wrapper.
See keyObject.export(), crypto.createPublicKey(), and
crypto.createPrivateKey() for usage details.
'raw-public' is generally the fastest way to import a public key.
'raw-private' and 'raw-seed' are not always faster than other formats
because they only contain the private scalar or seed - importing them requires
deriving the public key component (e.g. elliptic curve point multiplication or
seed expansion), which can be expensive. Other formats include both private
and public components, avoiding that computation.
Choosing a key format#
Always prefer a KeyObject - create one from whatever format you
have and reuse it. The guidance below applies only when choosing between
serialization formats, either for importing into a KeyObject or for
passing key material inline when a KeyObject is not practical.
Importing keys#
When creating a KeyObject for repeated use, the import cost is paid once,
so choosing a faster format reduces startup latency.
The import cost breaks down into two parts: parsing overhead (decoding the serialization wrapper) and key computation (any mathematical work needed to reconstruct the full key, such as deriving a public key from a private scalar or expanding a seed). Which part dominates depends on the key type. For example:
- Public keys -
'raw-public'is the fastest serialized format because the raw format skips all ASN.1 and Base64 decoding. - EC private keys -
'raw-private'is faster than PEM or DER because it avoids ASN.1 parsing. However, for larger curves (e.g. P-384, P-521) the required derivation of the public point from the private scalar becomes expensive, reducing the advantage. - RSA keys -
'jwk'is the fastest serialized format. JWK represents RSA key components as individual Base64url-encoded integers, avoiding the overhead of ASN.1 parsing entirely.
Inline key material in operations#
When a KeyObject cannot be reused (e.g. the key arrives as raw bytes in
a protocol message and is used only once), most cryptographic functions also
accept a PEM string or an object specifying the format and key
material directly. In this case the total cost is the sum of key import and
the cryptographic computation itself.
For operations where the cryptographic computation dominates - such as
signing with RSA or ECDH key agreement with P-384 or P-521 - the
serialization format has negligible impact on overall throughput, so choose
whichever format is most convenient. For lightweight operations like Ed25519
signing or verification, the import cost is a larger fraction of the total,
so a faster format like 'raw-public' or 'raw-private' can meaningfully
improve throughput.
Even if the same key material is used only a few times, it is worth importing it
into a KeyObject rather than passing the raw or PEM representation
repeatedly.
Examples#
Example: Reusing a KeyObject across sign and verify operations:
import { promisify } from 'node:util';
const { generateKeyPair, sign, verify } = await import('node:crypto');
const { publicKey, privateKey } = await promisify(generateKeyPair)('ed25519');
// A KeyObject holds the parsed key in memory and can be reused
// across multiple operations without re-parsing.
const data = new TextEncoder().encode('message to sign');
const signature = sign(null, data, privateKey);
verify(null, data, publicKey, signature);
Example: Importing keys of various formats into KeyObjects:
import { promisify } from 'node:util';
const {
createPrivateKey, createPublicKey, generateKeyPair,
} = await import('node:crypto');
const generated = await promisify(generateKeyPair)('ed25519');
// PEM
const privatePem = generated.privateKey.export({ format: 'pem', type: 'pkcs8' });
const publicPem = generated.publicKey.export({ format: 'pem', type: 'spki' });
createPrivateKey(privatePem);
createPublicKey(publicPem);
// DER - requires explicit type
const privateDer = generated.privateKey.export({ format: 'der', type: 'pkcs8' });
const publicDer = generated.publicKey.export({ format: 'der', type: 'spki' });
createPrivateKey({ key: privateDer, format: 'der', type: 'pkcs8' });
createPublicKey({ key: publicDer, format: 'der', type: 'spki' });
// JWK
const privateJwk = generated.privateKey.export({ format: 'jwk' });
const publicJwk = generated.publicKey.export({ format: 'jwk' });
createPrivateKey({ key: privateJwk, format: 'jwk' });
createPublicKey({ key: publicJwk, format: 'jwk' });
// Raw
const rawPriv = generated.privateKey.export({ format: 'raw-private' });
const rawPub = generated.publicKey.export({ format: 'raw-public' });
createPrivateKey({ key: rawPriv, format: 'raw-private', asymmetricKeyType: 'ed25519' });
createPublicKey({ key: rawPub, format: 'raw-public', asymmetricKeyType: 'ed25519' });
Example: Passing key material directly to crypto.sign() and
crypto.verify() without creating a KeyObject first:
import { promisify } from 'node:util';
const { generateKeyPair, sign, verify } = await import('node:crypto');
const generated = await promisify(generateKeyPair)('ed25519');
const data = new TextEncoder().encode('message to sign');
// PEM strings
const privatePem = generated.privateKey.export({ format: 'pem', type: 'pkcs8' });
const publicPem = generated.publicKey.export({ format: 'pem', type: 'spki' });
const sig1 = sign(null, data, privatePem);
verify(null, data, publicPem, sig1);
// JWK objects
const privateJwk = generated.privateKey.export({ format: 'jwk' });
const publicJwk = generated.publicKey.export({ format: 'jwk' });
const sig2 = sign(null, data, { key: privateJwk, format: 'jwk' });
verify(null, data, { key: publicJwk, format: 'jwk' }, sig2);
// Raw key bytes
const rawPriv = generated.privateKey.export({ format: 'raw-private' });
const rawPub = generated.publicKey.export({ format: 'raw-public' });
const sig3 = sign(null, data, {
key: rawPriv, format: 'raw-private', asymmetricKeyType: 'ed25519',
});
verify(null, data, {
key: rawPub, format: 'raw-public', asymmetricKeyType: 'ed25519',
}, sig3);
Example: For EC keys, the namedCurve option is required when importing
raw keys:
import { promisify } from 'node:util';
const {
createPrivateKey, createPublicKey, generateKeyPair, sign, verify,
} = await import('node:crypto');
const generated = await promisify(generateKeyPair)('ec', {
namedCurve: 'P-256',
});
// Export the raw EC public key (uncompressed by default).
const rawPublicKey = generated.publicKey.export({ format: 'raw-public' });
// The following is equivalent.
const rawPublicKeyUncompressed = generated.publicKey.export({
format: 'raw-public',
type: 'uncompressed',
});
// Export compressed point format.
const rawPublicKeyCompressed = generated.publicKey.export({
format: 'raw-public',
type: 'compressed',
});
// Export the raw EC private key.
const rawPrivateKey = generated.privateKey.export({ format: 'raw-private' });
// Import the raw EC keys.
// Both compressed and uncompressed point formats are accepted.
const publicKey = createPublicKey({
key: rawPublicKey,
format: 'raw-public',
asymmetricKeyType: 'ec',
namedCurve: 'P-256',
});
const privateKey = createPrivateKey({
key: rawPrivateKey,
format: 'raw-private',
asymmetricKeyType: 'ec',
namedCurve: 'P-256',
});
const data = new TextEncoder().encode('message to sign');
const signature = sign('sha256', data, privateKey);
verify('sha256', data, publicKey, signature);
Example: Exporting raw seeds and importing them:
import { promisify } from 'node:util';
const {
createPrivateKey, decapsulate, encapsulate, generateKeyPair,
} = await import('node:crypto');
const generated = await promisify(generateKeyPair)('ml-kem-768');
// Export the raw seed (64 bytes for ML-KEM).
const seed = generated.privateKey.export({ format: 'raw-seed' });
// Import the raw seed.
const privateKey = createPrivateKey({
key: seed,
format: 'raw-seed',
asymmetricKeyType: 'ml-kem-768',
});
const { ciphertext } = encapsulate(generated.publicKey);
decapsulate(privateKey, ciphertext);
Class: Certificate#
SPKAC is a Certificate Signing Request mechanism originally implemented by
Netscape and was specified formally as part of HTML5's keygen element.
<keygen> is deprecated since HTML 5.2 and new projects
should not use this element anymore.
The node:crypto module provides the Certificate class for working with SPKAC
data. The most common usage is handling output generated by the HTML5
<keygen> element. Node.js uses OpenSSL's SPKAC implementation internally.
Static method: Certificate.exportChallenge(spkac[, encoding])#
spkac<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>encoding<string>The encoding of thespkacstring.- Returns:
<Buffer>The challenge component of thespkacdata structure, which includes a public key and a challenge.
const { Certificate } = await import('node:crypto'); const spkac = getSpkacSomehow(); const challenge = Certificate.exportChallenge(spkac); console.log(challenge.toString('utf8')); // Prints: the challenge as a UTF8 stringconst { Certificate } = require('node:crypto'); const spkac = getSpkacSomehow(); const challenge = Certificate.exportChallenge(spkac); console.log(challenge.toString('utf8')); // Prints: the challenge as a UTF8 string
Static method: Certificate.exportPublicKey(spkac[, encoding])#
spkac<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>encoding<string>The encoding of thespkacstring.- Returns:
<Buffer>The public key component of thespkacdata structure, which includes a public key and a challenge.
const { Certificate } = await import('node:crypto'); const spkac = getSpkacSomehow(); const publicKey = Certificate.exportPublicKey(spkac); console.log(publicKey); // Prints: the public key as <Buffer ...>const { Certificate } = require('node:crypto'); const spkac = getSpkacSomehow(); const publicKey = Certificate.exportPublicKey(spkac); console.log(publicKey); // Prints: the public key as <Buffer ...>
Static method: Certificate.verifySpkac(spkac[, encoding])#
spkac<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>encoding<string>The encoding of thespkacstring.- Returns:
<boolean>trueif the givenspkacdata structure is valid,falseotherwise.
import { Buffer } from 'node:buffer'; const { Certificate } = await import('node:crypto'); const spkac = getSpkacSomehow(); console.log(Certificate.verifySpkac(Buffer.from(spkac))); // Prints: true or falseconst { Buffer } = require('node:buffer'); const { Certificate } = require('node:crypto'); const spkac = getSpkacSomehow(); console.log(Certificate.verifySpkac(Buffer.from(spkac))); // Prints: true or false
Legacy API#
Stability: 0 - Deprecated
As a legacy interface, it is possible to create new instances of
the crypto.Certificate class as illustrated in the examples below.
new crypto.Certificate()#
Instances of the Certificate class can be created using the new keyword
or by calling crypto.Certificate() as a function:
const { Certificate } = await import('node:crypto'); const cert1 = new Certificate(); const cert2 = Certificate();const { Certificate } = require('node:crypto'); const cert1 = new Certificate(); const cert2 = Certificate();
certificate.exportChallenge(spkac[, encoding])#
spkac<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>encoding<string>The encoding of thespkacstring.- Returns:
<Buffer>The challenge component of thespkacdata structure, which includes a public key and a challenge.
const { Certificate } = await import('node:crypto'); const cert = Certificate(); const spkac = getSpkacSomehow(); const challenge = cert.exportChallenge(spkac); console.log(challenge.toString('utf8')); // Prints: the challenge as a UTF8 stringconst { Certificate } = require('node:crypto'); const cert = Certificate(); const spkac = getSpkacSomehow(); const challenge = cert.exportChallenge(spkac); console.log(challenge.toString('utf8')); // Prints: the challenge as a UTF8 string
certificate.exportPublicKey(spkac[, encoding])#
spkac<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>encoding<string>The encoding of thespkacstring.- Returns:
<Buffer>The public key component of thespkacdata structure, which includes a public key and a challenge.
const { Certificate } = await import('node:crypto'); const cert = Certificate(); const spkac = getSpkacSomehow(); const publicKey = cert.exportPublicKey(spkac); console.log(publicKey); // Prints: the public key as <Buffer ...>const { Certificate } = require('node:crypto'); const cert = Certificate(); const spkac = getSpkacSomehow(); const publicKey = cert.exportPublicKey(spkac); console.log(publicKey); // Prints: the public key as <Buffer ...>
certificate.verifySpkac(spkac[, encoding])#
spkac<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>encoding<string>The encoding of thespkacstring.- Returns:
<boolean>trueif the givenspkacdata structure is valid,falseotherwise.
import { Buffer } from 'node:buffer'; const { Certificate } = await import('node:crypto'); const cert = Certificate(); const spkac = getSpkacSomehow(); console.log(cert.verifySpkac(Buffer.from(spkac))); // Prints: true or falseconst { Buffer } = require('node:buffer'); const { Certificate } = require('node:crypto'); const cert = Certificate(); const spkac = getSpkacSomehow(); console.log(cert.verifySpkac(Buffer.from(spkac))); // Prints: true or false
Class: Cipheriv#
- Extends:
<stream.Transform>
Instances of the Cipheriv class are used to encrypt data. The class can be
used in one of two ways:
- As a stream that is both readable and writable, where plain unencrypted data is written to produce encrypted data on the readable side, or
- Using the
cipher.update()andcipher.final()methods to produce the encrypted data.
The crypto.createCipheriv() method is
used to create Cipheriv instances. Cipheriv objects are not to be created
directly using the new keyword.
The selected algorithm may impose additional restrictions on streaming and
calls to cipher.update(). See CCM mode, CBC-CTS mode, XTS mode,
AES key wrap modes, and SIV and GCM-SIV modes.
Example: Using Cipheriv objects as streams:
const { scrypt, randomFill, createCipheriv, } = await import('node:crypto'); const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; // First, we'll generate the key. The key length is dependent on the algorithm. // In this case for aes192, it is 24 bytes (192 bits). scrypt(password, 'salt', 24, (err, key) => { if (err) throw err; // Then, we'll generate a random initialization vector randomFill(new Uint8Array(16), (err, iv) => { if (err) throw err; // Once we have the key and iv, we can create and use the cipher... const cipher = createCipheriv(algorithm, key, iv); let encrypted = ''; cipher.setEncoding('hex'); cipher.on('data', (chunk) => encrypted += chunk); cipher.on('end', () => console.log(encrypted)); cipher.write('some clear text data'); cipher.end(); }); });const { scrypt, randomFill, createCipheriv, } = require('node:crypto'); const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; // First, we'll generate the key. The key length is dependent on the algorithm. // In this case for aes192, it is 24 bytes (192 bits). scrypt(password, 'salt', 24, (err, key) => { if (err) throw err; // Then, we'll generate a random initialization vector randomFill(new Uint8Array(16), (err, iv) => { if (err) throw err; // Once we have the key and iv, we can create and use the cipher... const cipher = createCipheriv(algorithm, key, iv); let encrypted = ''; cipher.setEncoding('hex'); cipher.on('data', (chunk) => encrypted += chunk); cipher.on('end', () => console.log(encrypted)); cipher.write('some clear text data'); cipher.end(); }); });
Example: Using Cipheriv and piped streams:
import { createReadStream, createWriteStream, } from 'node:fs'; import { pipeline, } from 'node:stream'; const { scrypt, randomFill, createCipheriv, } = await import('node:crypto'); const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; // First, we'll generate the key. The key length is dependent on the algorithm. // In this case for aes192, it is 24 bytes (192 bits). scrypt(password, 'salt', 24, (err, key) => { if (err) throw err; // Then, we'll generate a random initialization vector randomFill(new Uint8Array(16), (err, iv) => { if (err) throw err; const cipher = createCipheriv(algorithm, key, iv); const input = createReadStream('test.js'); const output = createWriteStream('test.enc'); pipeline(input, cipher, output, (err) => { if (err) throw err; }); }); });const { createReadStream, createWriteStream, } = require('node:fs'); const { pipeline, } = require('node:stream'); const { scrypt, randomFill, createCipheriv, } = require('node:crypto'); const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; // First, we'll generate the key. The key length is dependent on the algorithm. // In this case for aes192, it is 24 bytes (192 bits). scrypt(password, 'salt', 24, (err, key) => { if (err) throw err; // Then, we'll generate a random initialization vector randomFill(new Uint8Array(16), (err, iv) => { if (err) throw err; const cipher = createCipheriv(algorithm, key, iv); const input = createReadStream('test.js'); const output = createWriteStream('test.enc'); pipeline(input, cipher, output, (err) => { if (err) throw err; }); }); });
Example: Using the cipher.update() and cipher.final() methods:
const { scrypt, randomFill, createCipheriv, } = await import('node:crypto'); const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; // First, we'll generate the key. The key length is dependent on the algorithm. // In this case for aes192, it is 24 bytes (192 bits). scrypt(password, 'salt', 24, (err, key) => { if (err) throw err; // Then, we'll generate a random initialization vector randomFill(new Uint8Array(16), (err, iv) => { if (err) throw err; const cipher = createCipheriv(algorithm, key, iv); let encrypted = cipher.update('some clear text data', 'utf8', 'hex'); encrypted += cipher.final('hex'); console.log(encrypted); }); });const { scrypt, randomFill, createCipheriv, } = require('node:crypto'); const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; // First, we'll generate the key. The key length is dependent on the algorithm. // In this case for aes192, it is 24 bytes (192 bits). scrypt(password, 'salt', 24, (err, key) => { if (err) throw err; // Then, we'll generate a random initialization vector randomFill(new Uint8Array(16), (err, iv) => { if (err) throw err; const cipher = createCipheriv(algorithm, key, iv); let encrypted = cipher.update('some clear text data', 'utf8', 'hex'); encrypted += cipher.final('hex'); console.log(encrypted); }); });
cipher.final([outputEncoding])#
outputEncoding<string>The encoding of the return value.- Returns:
<Buffer>|<string>Any remaining enciphered contents. IfoutputEncodingis specified, a string is returned. If anoutputEncodingis not provided, aBufferis returned.
If an output encoding was specified in a previous call to
cipher.update(), outputEncoding must use the same encoding.
Once the cipher.final() method has been called, the Cipheriv object can no
longer be used to encrypt data. Attempts to call cipher.final() more than
once will result in an error being thrown.
cipher.getAuthTag()#
- Returns:
<Buffer>When using an authenticated encryption mode (GCM,CCM,OCB,SIV,GCM-SIV, andchacha20-poly1305are currently supported), thecipher.getAuthTag()method returns aBuffercontaining the authentication tag that has been computed from the given data.
The cipher.getAuthTag() method should only be called after encryption has
been completed using the cipher.final() method.
If the authTagLength option was set during the cipher instance's creation,
this function will return exactly authTagLength bytes.
cipher.setAAD(buffer[, options])#
buffer<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>options<Object>stream.transformoptions- Returns:
<Cipheriv>The sameCipherivinstance for method chaining.
When using an authenticated encryption mode (GCM, CCM, OCB, SIV,
GCM-SIV, and chacha20-poly1305 are currently supported), the
cipher.setAAD() method sets the value used for the additional authenticated
data (AAD) input parameter.
The plaintextLength option is optional for GCM, OCB, SIV, and
GCM-SIV. When using CCM, the plaintextLength option must be specified and
its value must match the length of the plaintext in bytes. See CCM mode.
The cipher.setAAD() method must be called before cipher.update().
cipher.setAutoPadding([autoPadding])#
autoPadding<boolean>Default:true- Returns:
<Cipheriv>The sameCipherivinstance for method chaining.
When using block ciphers that use standard block padding, the Cipheriv class
will automatically add padding to the input data to the appropriate block size.
To disable the default padding call cipher.setAutoPadding(false).
For block ciphers that use standard block padding, when autoPadding is
false, the length of the entire input data must be a multiple of the cipher's
block size or cipher.final() will throw an error. Disabling automatic
padding is useful for non-standard padding, for instance using 0x0 instead of
PKCS padding.
The cipher.setAutoPadding() method must be called before
cipher.final().
cipher.update(data[, inputEncoding][, outputEncoding])#
data<string>|<Buffer>|<TypedArray>|<DataView>inputEncoding<string>The encoding of the data.outputEncoding<string>The encoding of the return value.- Returns:
<Buffer>|<string>
Updates the cipher with data. If the inputEncoding argument is given,
the data
argument is a string using the specified encoding. If the inputEncoding
argument is not given, data must be a Buffer, TypedArray, or
DataView. If data is a Buffer, TypedArray, or DataView, then
inputEncoding is ignored.
The outputEncoding specifies the output format of the enciphered
data. If the outputEncoding
is specified, a string using the specified encoding is returned. If no
outputEncoding is provided, a Buffer is returned.
When outputEncoding is specified, it must use the same encoding as previous
calls to cipher.update().
For most algorithms, cipher.update() can be called multiple times with new
data until cipher.final() is called. Some algorithms restrict calls to
cipher.update(). For example, CCM mode, CBC-CTS mode, XTS mode,
AES key wrap modes, and SIV and GCM-SIV modes require the whole message
in a single call. Calling cipher.update() after cipher.final() will
result in an error being thrown.
Class: Decipheriv#
- Extends:
<stream.Transform>
Instances of the Decipheriv class are used to decrypt data. The class can be
used in one of two ways:
- As a stream that is both readable and writable, where plain encrypted data is written to produce unencrypted data on the readable side, or
- Using the
decipher.update()anddecipher.final()methods to produce the unencrypted data.
The crypto.createDecipheriv() method is
used to create Decipheriv instances. Decipheriv objects are not to be created
directly using the new keyword.
The selected algorithm may impose additional restrictions on streaming and
calls to decipher.update(). See CCM mode, CBC-CTS mode,
XTS mode, AES key wrap modes, and SIV and GCM-SIV modes.
Example: Using Decipheriv objects as streams:
import { Buffer } from 'node:buffer'; const { scryptSync, createDecipheriv, } = await import('node:crypto'); const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; // Key length is dependent on the algorithm. In this case for aes192, it is // 24 bytes (192 bits). // Use the async `crypto.scrypt()` instead. const key = scryptSync(password, 'salt', 24); // The IV is usually passed along with the ciphertext. const iv = Buffer.alloc(16, 0); // Initialization vector. const decipher = createDecipheriv(algorithm, key, iv); let decrypted = ''; decipher.on('readable', () => { let chunk; while (null !== (chunk = decipher.read())) { decrypted += chunk.toString('utf8'); } }); decipher.on('end', () => { console.log(decrypted); // Prints: some clear text data }); // Encrypted with same algorithm, key and iv. const encrypted = 'e5f79c5915c02171eec6b212d5520d44480993d7d622a7c4c2da32f6efda0ffa'; decipher.write(encrypted, 'hex'); decipher.end();const { scryptSync, createDecipheriv, } = require('node:crypto'); const { Buffer } = require('node:buffer'); const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; // Key length is dependent on the algorithm. In this case for aes192, it is // 24 bytes (192 bits). // Use the async `crypto.scrypt()` instead. const key = scryptSync(password, 'salt', 24); // The IV is usually passed along with the ciphertext. const iv = Buffer.alloc(16, 0); // Initialization vector. const decipher = createDecipheriv(algorithm, key, iv); let decrypted = ''; decipher.on('readable', () => { let chunk; while (null !== (chunk = decipher.read())) { decrypted += chunk.toString('utf8'); } }); decipher.on('end', () => { console.log(decrypted); // Prints: some clear text data }); // Encrypted with same algorithm, key and iv. const encrypted = 'e5f79c5915c02171eec6b212d5520d44480993d7d622a7c4c2da32f6efda0ffa'; decipher.write(encrypted, 'hex'); decipher.end();
Example: Using Decipheriv and piped streams:
import { createReadStream, createWriteStream, } from 'node:fs'; import { Buffer } from 'node:buffer'; const { scryptSync, createDecipheriv, } = await import('node:crypto'); const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; // Use the async `crypto.scrypt()` instead. const key = scryptSync(password, 'salt', 24); // The IV is usually passed along with the ciphertext. const iv = Buffer.alloc(16, 0); // Initialization vector. const decipher = createDecipheriv(algorithm, key, iv); const input = createReadStream('test.enc'); const output = createWriteStream('test.js'); input.pipe(decipher).pipe(output);const { createReadStream, createWriteStream, } = require('node:fs'); const { scryptSync, createDecipheriv, } = require('node:crypto'); const { Buffer } = require('node:buffer'); const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; // Use the async `crypto.scrypt()` instead. const key = scryptSync(password, 'salt', 24); // The IV is usually passed along with the ciphertext. const iv = Buffer.alloc(16, 0); // Initialization vector. const decipher = createDecipheriv(algorithm, key, iv); const input = createReadStream('test.enc'); const output = createWriteStream('test.js'); input.pipe(decipher).pipe(output);
Example: Using the decipher.update() and decipher.final() methods:
import { Buffer } from 'node:buffer'; const { scryptSync, createDecipheriv, } = await import('node:crypto'); const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; // Use the async `crypto.scrypt()` instead. const key = scryptSync(password, 'salt', 24); // The IV is usually passed along with the ciphertext. const iv = Buffer.alloc(16, 0); // Initialization vector. const decipher = createDecipheriv(algorithm, key, iv); // Encrypted using same algorithm, key and iv. const encrypted = 'e5f79c5915c02171eec6b212d5520d44480993d7d622a7c4c2da32f6efda0ffa'; let decrypted = decipher.update(encrypted, 'hex', 'utf8'); decrypted += decipher.final('utf8'); console.log(decrypted); // Prints: some clear text dataconst { scryptSync, createDecipheriv, } = require('node:crypto'); const { Buffer } = require('node:buffer'); const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; // Use the async `crypto.scrypt()` instead. const key = scryptSync(password, 'salt', 24); // The IV is usually passed along with the ciphertext. const iv = Buffer.alloc(16, 0); // Initialization vector. const decipher = createDecipheriv(algorithm, key, iv); // Encrypted using same algorithm, key and iv. const encrypted = 'e5f79c5915c02171eec6b212d5520d44480993d7d622a7c4c2da32f6efda0ffa'; let decrypted = decipher.update(encrypted, 'hex', 'utf8'); decrypted += decipher.final('utf8'); console.log(decrypted); // Prints: some clear text data
decipher.final([outputEncoding])#
outputEncoding<string>The encoding of the return value.- Returns:
<Buffer>|<string>Any remaining deciphered contents. IfoutputEncodingis specified, a string is returned. If anoutputEncodingis not provided, aBufferis returned.
If an output encoding was specified in a previous call to
decipher.update(), outputEncoding must use the same encoding.
Once the decipher.final() method has been called, the Decipheriv object can
no longer be used to decrypt data. Attempts to call decipher.final() more
than once will result in an error being thrown.
decipher.setAAD(buffer[, options])#
buffer<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>options<Object>stream.transformoptions- Returns:
<Decipheriv>The sameDecipherivinstance for method chaining.
When using an authenticated encryption mode (GCM, CCM, OCB, SIV,
GCM-SIV, and chacha20-poly1305 are currently supported), the
decipher.setAAD() method sets the value used for the additional
authenticated data (AAD) input parameter.
The options argument is optional for GCM, OCB, SIV, and GCM-SIV.
When using CCM, the plaintextLength option must be specified and its value
must match the length of the ciphertext in bytes. See CCM mode.
The decipher.setAAD() method must be called before decipher.update().
When passing a string as the buffer, please consider
caveats when using strings as inputs to cryptographic APIs.
decipher.setAuthTag(buffer[, encoding])#
buffer<string>|<Buffer>|<ArrayBuffer>|<TypedArray>|<DataView>encoding<string>String encoding to use whenbufferis a string.- Returns:
<Decipheriv>The sameDecipherivinstance for method chaining.
When using an authenticated encryption mode (GCM, CCM, OCB, SIV,
GCM-SIV, and chacha20-poly1305 are currently supported), the
decipher.setAuthTag() method is used to pass in the received
authentication tag. If no tag is provided, or if the cipher text has been
tampered with, decipher.final() will throw, indicating that the cipher
text should be discarded due to failed authentication. If the tag length is
invalid according to NIST SP 800-38D or does not match the value of the
authTagLength option, decipher.setAuthTag() will throw an error.
The decipher.setAuthTag() method must be called before decipher.update()
for CCM, SIV, and GCM-SIV modes or before decipher.final() for
GCM and OCB modes and chacha20-poly1305.
decipher.setAuthTag() can only be called once.
When passing a string as the authentication tag, please consider caveats when using strings as inputs to cryptographic APIs.
decipher.setAutoPadding([autoPadding])#
autoPadding<boolean>Default:true- Returns:
<Decipheriv>The sameDecipherivinstance for method chaining.
When data has been encrypted without standard block padding, calling
decipher.setAutoPadding(false) will disable automatic padding to prevent
decipher.final() from checking for and removing padding.
For block ciphers that use standard block padding, disabling it requires the input data's length to be a multiple of the cipher's block size.
The decipher.setAutoPadding() method must be called before
decipher.final().
decipher.update(data[, inputEncoding][, outputEncoding])#
data<string>|<Buffer>|<TypedArray>|<DataView>inputEncoding<string>The encoding of thedatastring.outputEncoding<string>The encoding of the return value.- Returns:
<Buffer>|<string>
Updates the decipher with data. If the inputEncoding argument is given,
the data
argument is a string using the specified encoding. If the inputEncoding
argument is not given, data must be a Buffer, TypedArray, or
DataView. If data is a Buffer, TypedArray, or DataView, then
inputEncoding is ignored.
The outputEncoding specifies the output format of the deciphered
data. If the outputEncoding
is specified, a string using the specified encoding is returned. If no
outputEncoding is provided, a Buffer is returned.
When outputEncoding is specified, it must use the same encoding as previous
calls to decipher.update().
For most algorithms, decipher.update() can be called multiple times with new
data until decipher.final() is called. Some algorithms restrict calls to
decipher.update(). For example, CCM mode, CBC-CTS mode, XTS mode,
AES key wrap modes, and SIV and GCM-SIV modes require the whole message
in a single call. Calling decipher.update() after decipher.final() will
result in an error being thrown.
Even if the underlying cipher implements authentication, the authenticity and
integrity of the plaintext returned from this function may be uncertain at this
time. For authenticated encryption algorithms, authenticity is generally only
established when the application calls decipher.final().
Class: DiffieHellman#
The DiffieHellman class is a utility for creating Diffie-Hellman key
exchanges.
Instances of the DiffieHellman class can be created using the
crypto.createDiffieHellman() function.
import assert from 'node:assert'; const { createDiffieHellman, } = await import('node:crypto'); // Generate Alice's keys... const alice = createDiffieHellman(2048); const aliceKey = alice.generateKeys(); // Generate Bob's keys... const bob = createDiffieHellman(alice.getPrime(), alice.getGenerator()); const bobKey = bob.generateKeys(); // Exchange and generate the secret... const aliceSecret = alice.computeSecret(bobKey); const bobSecret = bob.computeSecret(aliceKey); // OK assert.strictEqual(aliceSecret.toString('hex'), bobSecret.toString('hex'));const assert = require('node:assert'); const { createDiffieHellman, } = require('node:crypto'); // Generate Alice's keys... const alice = createDiffieHellman(2048); const aliceKey = alice.generateKeys(); // Generate Bob's keys... const bob = createDiffieHellman(alice.getPrime(), alice.getGenerator()); const bobKey = bob.generateKeys(); // Exchange and generate the secret... const aliceSecret = alice.computeSecret(bobKey); const bobSecret = bob.computeSecret(aliceKey); // OK assert.strictEqual(aliceSecret.toString('hex'), bobSecret.toString('hex'));
diffieHellman.computeSecret(otherPublicKey[, inputEncoding][, outputEncoding])#
otherPublicKey<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>inputEncoding<string>The encoding of anotherPublicKeystring.outputEncoding<string>The encoding of the return value.- Returns:
<Buffer>|<string>
Computes the shared secret using otherPublicKey as the other
party's public key and returns the computed shared secret. The supplied
key is interpreted using the specified inputEncoding, and secret is
encoded using specified outputEncoding.
If the inputEncoding is not
provided, otherPublicKey is expected to be a Buffer,
TypedArray, or DataView.
If outputEncoding is given a string is returned; otherwise, a
Buffer is returned.
diffieHellman.generateKeys([encoding])#
Generates private and public Diffie-Hellman key values unless they have been
generated or computed already, and returns
the public key in the specified encoding. This key should be
transferred to the other party.
If encoding is provided a string is returned; otherwise a
Buffer is returned.
This function is a thin wrapper around DH_generate_key(). In particular,
once a private key has been generated or set, calling this function only
recomputes the public key from the existing private key. Since the public key is
determined by the private key, the result will be the same unless the private key
has been changed via diffieHellman.setPrivateKey().
diffieHellman.getGenerator([encoding])#
Returns the Diffie-Hellman generator in the specified encoding.
If encoding is provided a string is
returned; otherwise a Buffer is returned.
diffieHellman.getPrime([encoding])#
Returns the Diffie-Hellman prime in the specified encoding.
If encoding is provided a string is
returned; otherwise a Buffer is returned.
diffieHellman.getPrivateKey([encoding])#
Returns the Diffie-Hellman private key in the specified encoding.
If encoding is provided a
string is returned; otherwise a Buffer is returned.
diffieHellman.getPublicKey([encoding])#
Returns the Diffie-Hellman public key in the specified encoding.
If encoding is provided a
string is returned; otherwise a Buffer is returned.
diffieHellman.setPrivateKey(privateKey[, encoding])#
privateKey<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>encoding<string>The encoding of theprivateKeystring.
Sets the Diffie-Hellman private key. If the encoding argument is provided,
privateKey is expected
to be a string. If no encoding is provided, privateKey is expected
to be a Buffer, TypedArray, or DataView.
This function does not automatically compute the associated public key. Either
diffieHellman.setPublicKey() or diffieHellman.generateKeys() can be
used to manually provide the public key or to automatically derive it.
diffieHellman.setPublicKey(publicKey[, encoding])#
publicKey<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>encoding<string>The encoding of thepublicKeystring.
Sets the Diffie-Hellman public key. If the encoding argument is provided,
publicKey is expected
to be a string. If no encoding is provided, publicKey is expected
to be a Buffer, TypedArray, or DataView.
diffieHellman.verifyError#
A bit field containing any warnings and/or errors resulting from a check
performed during initialization of the DiffieHellman object.
The following values are valid for this property (as defined in node:constants module):
DH_CHECK_P_NOT_SAFE_PRIMEDH_CHECK_P_NOT_PRIMEDH_UNABLE_TO_CHECK_GENERATORDH_NOT_SUITABLE_GENERATOR
Class: DiffieHellmanGroup#
The DiffieHellmanGroup class takes a well-known modp group as its argument.
It works the same as DiffieHellman, except that it does not allow changing
its keys after creation. In other words, it does not implement setPublicKey()
or setPrivateKey() methods.
const { createDiffieHellmanGroup } = await import('node:crypto'); const dh = createDiffieHellmanGroup('modp16');const { createDiffieHellmanGroup } = require('node:crypto'); const dh = createDiffieHellmanGroup('modp16');
The following groups are supported:
'modp14'(2048 bits, RFC 3526 Section 3)'modp15'(3072 bits, RFC 3526 Section 4)'modp16'(4096 bits, RFC 3526 Section 5)'modp17'(6144 bits, RFC 3526 Section 6)'modp18'(8192 bits, RFC 3526 Section 7)
The following groups are still supported but deprecated (see Caveats):
'modp1'(768 bits, RFC 2409 Section 6.1)'modp2'(1024 bits, RFC 2409 Section 6.2)'modp5'(1536 bits, RFC 3526 Section 2)
These deprecated groups might be removed in future versions of Node.js.
Class: ECDH#
The ECDH class is a utility for creating Elliptic Curve Diffie-Hellman (ECDH)
key exchanges.
Instances of the ECDH class can be created using the
crypto.createECDH() function.
import assert from 'node:assert'; const { createECDH, } = await import('node:crypto'); // Generate Alice's keys... const alice = createECDH('secp521r1'); const aliceKey = alice.generateKeys(); // Generate Bob's keys... const bob = createECDH('secp521r1'); const bobKey = bob.generateKeys(); // Exchange and generate the secret... const aliceSecret = alice.computeSecret(bobKey); const bobSecret = bob.computeSecret(aliceKey); assert.strictEqual(aliceSecret.toString('hex'), bobSecret.toString('hex')); // OKconst assert = require('node:assert'); const { createECDH, } = require('node:crypto'); // Generate Alice's keys... const alice = createECDH('secp521r1'); const aliceKey = alice.generateKeys(); // Generate Bob's keys... const bob = createECDH('secp521r1'); const bobKey = bob.generateKeys(); // Exchange and generate the secret... const aliceSecret = alice.computeSecret(bobKey); const bobSecret = bob.computeSecret(aliceKey); assert.strictEqual(aliceSecret.toString('hex'), bobSecret.toString('hex')); // OK
Static method: ECDH.convertKey(key, curve[, inputEncoding[, outputEncoding[, format]]])#
key<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>curve<string>inputEncoding<string>The encoding of thekeystring.outputEncoding<string>The encoding of the return value.format<string>Default:'uncompressed'- Returns:
<Buffer>|<string>
Converts the EC Diffie-Hellman public key specified by key and curve to the
format specified by format. The format argument specifies point encoding
and can be 'compressed', 'uncompressed' or 'hybrid'. The supplied key is
interpreted using the specified inputEncoding, and the returned key is encoded
using the specified outputEncoding.
Use crypto.getCurves() to obtain a list of available curve names.
On recent OpenSSL releases, openssl ecparam -list_curves will also display
the name and description of each available elliptic curve.
If format is not specified the point will be returned in 'uncompressed'
format.
If the inputEncoding is not provided, key is expected to be a Buffer,
TypedArray, or DataView.
Example (uncompressing a key):
const { createECDH, ECDH, } = await import('node:crypto'); const ecdh = createECDH('secp256k1'); ecdh.generateKeys(); const compressedKey = ecdh.getPublicKey('hex', 'compressed'); const uncompressedKey = ECDH.convertKey(compressedKey, 'secp256k1', 'hex', 'hex', 'uncompressed'); // The converted key and the uncompressed public key should be the same console.log(uncompressedKey === ecdh.getPublicKey('hex'));const { createECDH, ECDH, } = require('node:crypto'); const ecdh = createECDH('secp256k1'); ecdh.generateKeys(); const compressedKey = ecdh.getPublicKey('hex', 'compressed'); const uncompressedKey = ECDH.convertKey(compressedKey, 'secp256k1', 'hex', 'hex', 'uncompressed'); // The converted key and the uncompressed public key should be the same console.log(uncompressedKey === ecdh.getPublicKey('hex'));
ecdh.computeSecret(otherPublicKey[, inputEncoding][, outputEncoding])#
otherPublicKey<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>inputEncoding<string>The encoding of theotherPublicKeystring.outputEncoding<string>The encoding of the return value.- Returns:
<Buffer>|<string>
Computes the shared secret using otherPublicKey as the other
party's public key and returns the computed shared secret. The supplied
key is interpreted using specified inputEncoding, and the returned secret
is encoded using the specified outputEncoding.
If the inputEncoding is not
provided, otherPublicKey is expected to be a Buffer, TypedArray, or
DataView.
If outputEncoding is given a string will be returned; otherwise a
Buffer is returned.
ecdh.computeSecret will throw an
ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY error when otherPublicKey
lies outside of the elliptic curve. Since otherPublicKey is
usually supplied from a remote user over an insecure network,
be sure to handle this exception accordingly.
ecdh.generateKeys([encoding[, format]])#
encoding<string>The encoding of the return value.format<string>Default:'uncompressed'- Returns:
<Buffer>|<string>
Generates private and public EC Diffie-Hellman key values, and returns
the public key in the specified format and encoding. This key should be
transferred to the other party.
The format argument specifies point encoding and can be 'compressed' or
'uncompressed'. If format is not specified, the point will be returned in
'uncompressed' format.
If encoding is provided a string is returned; otherwise a Buffer
is returned.
ecdh.getPrivateKey([encoding])#
encoding<string>The encoding of the return value.- Returns:
<Buffer>|<string>The EC Diffie-Hellman in the specifiedencoding.
If encoding is specified, a string is returned; otherwise a Buffer is
returned.
ecdh.getPublicKey([encoding][, format])#
encoding<string>The encoding of the return value.format<string>Default:'uncompressed'- Returns:
<Buffer>|<string>The EC Diffie-Hellman public key in the specifiedencodingandformat.
The format argument specifies point encoding and can be 'compressed' or
'uncompressed'. If format is not specified the point will be returned in
'uncompressed' format.
If encoding is specified, a string is returned; otherwise a Buffer is
returned.
ecdh.setPrivateKey(privateKey[, encoding])#
privateKey<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>encoding<string>The encoding of theprivateKeystring.
Sets the EC Diffie-Hellman private key.
If encoding is provided, privateKey is expected
to be a string; otherwise privateKey is expected to be a Buffer,
TypedArray, or DataView.
If privateKey is not valid for the curve specified when the ECDH object was
created, an error is thrown. Upon setting the private key, the associated
public point (key) is also generated and set in the ECDH object.
ecdh.setPublicKey(publicKey[, encoding])#
Stability: 0 - Deprecated
publicKey<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>encoding<string>The encoding of thepublicKeystring.
Sets the EC Diffie-Hellman public key.
If encoding is provided publicKey is expected to
be a string; otherwise a Buffer, TypedArray, or DataView is expected.
There is not normally a reason to call this method because ECDH
only requires a private key and the other party's public key to compute the
shared secret. Typically either ecdh.generateKeys() or
ecdh.setPrivateKey() will be called. The ecdh.setPrivateKey() method
attempts to generate the public point/key associated with the private key being
set.
Example (obtaining a shared secret):
const { createECDH, createHash, } = await import('node:crypto'); const alice = createECDH('secp256k1'); const bob = createECDH('secp256k1'); // This is a shortcut way of specifying one of Alice's previous private // keys. It would be unwise to use such a predictable private key in a real // application. alice.setPrivateKey( createHash('sha256').update('alice', 'utf8').digest(), ); // Bob uses a newly generated cryptographically strong // pseudorandom key pair bob.generateKeys(); const aliceSecret = alice.computeSecret(bob.getPublicKey(), null, 'hex'); const bobSecret = bob.computeSecret(alice.getPublicKey(), null, 'hex'); // aliceSecret and bobSecret should be the same shared secret value console.log(aliceSecret === bobSecret);const { createECDH, createHash, } = require('node:crypto'); const alice = createECDH('secp256k1'); const bob = createECDH('secp256k1'); // This is a shortcut way of specifying one of Alice's previous private // keys. It would be unwise to use such a predictable private key in a real // application. alice.setPrivateKey( createHash('sha256').update('alice', 'utf8').digest(), ); // Bob uses a newly generated cryptographically strong // pseudorandom key pair bob.generateKeys(); const aliceSecret = alice.computeSecret(bob.getPublicKey(), null, 'hex'); const bobSecret = bob.computeSecret(alice.getPublicKey(), null, 'hex'); // aliceSecret and bobSecret should be the same shared secret value console.log(aliceSecret === bobSecret);
Class: Hash#
- Extends:
<stream.Transform>
The Hash class is a utility for creating hash digests of data. It can be
used in one of two ways:
- As a stream that is both readable and writable, where data is written to produce a computed hash digest on the readable side, or
- Using the
hash.update()andhash.digest()methods to produce the computed hash.
The crypto.createHash() method is used to create Hash instances. Hash
objects are not to be created directly using the new keyword.
Example: Using Hash objects as streams:
const { createHash, } = await import('node:crypto'); const hash = createHash('sha256'); hash.on('readable', () => { // Only one element is going to be produced by the // hash stream. const data = hash.read(); if (data) { console.log(data.toString('hex')); // Prints: // 6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50 } }); hash.write('some data to hash'); hash.end();const { createHash, } = require('node:crypto'); const hash = createHash('sha256'); hash.on('readable', () => { // Only one element is going to be produced by the // hash stream. const data = hash.read(); if (data) { console.log(data.toString('hex')); // Prints: // 6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50 } }); hash.write('some data to hash'); hash.end();
Example: Using Hash and piped streams:
import { createReadStream } from 'node:fs'; import { stdout } from 'node:process'; const { createHash } = await import('node:crypto'); const hash = createHash('sha256'); const input = createReadStream('test.js'); input.pipe(hash).setEncoding('hex').pipe(stdout);const { createReadStream } = require('node:fs'); const { createHash } = require('node:crypto'); const { stdout } = require('node:process'); const hash = createHash('sha256'); const input = createReadStream('test.js'); input.pipe(hash).setEncoding('hex').pipe(stdout);
Example: Using the hash.update() and hash.digest() methods:
const { createHash, } = await import('node:crypto'); const hash = createHash('sha256'); hash.update('some data to hash'); console.log(hash.digest('hex')); // Prints: // 6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50const { createHash, } = require('node:crypto'); const hash = createHash('sha256'); hash.update('some data to hash'); console.log(hash.digest('hex')); // Prints: // 6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50
hash.copy([options])#
options<Object>stream.transformoptions- Returns:
<Hash>
Creates a new Hash object that contains a deep copy of the internal state
of the current Hash object.
The optional options argument controls stream behavior. For XOF hash
functions such as 'shake256', the outputLength option can be used to
specify the desired output length in bytes.
An error is thrown when an attempt is made to copy the Hash object after
its hash.digest() method has been called.
// Calculate a rolling hash. const { createHash, } = await import('node:crypto'); const hash = createHash('sha256'); hash.update('one'); console.log(hash.copy().digest('hex')); hash.update('two'); console.log(hash.copy().digest('hex')); hash.update('three'); console.log(hash.copy().digest('hex')); // Etc.// Calculate a rolling hash. const { createHash, } = require('node:crypto'); const hash = createHash('sha256'); hash.update('one'); console.log(hash.copy().digest('hex')); hash.update('two'); console.log(hash.copy().digest('hex')); hash.update('three'); console.log(hash.copy().digest('hex')); // Etc.
hash.digest([encoding])#
Calculates the digest of all of the data passed to be hashed (using the
hash.update() method).
If encoding is provided a string will be returned; otherwise
a Buffer is returned.
The Hash object can not be used again after hash.digest() method has been
called. Multiple calls will cause an error to be thrown.
hash.update(data[, inputEncoding])#
data<string>|<Buffer>|<TypedArray>|<DataView>inputEncoding<string>The encoding of thedatastring.
Updates the hash content with the given data, the encoding of which
is given in inputEncoding.
If encoding is not provided, and the data is a string, an
encoding of 'utf8' is enforced. If data is a Buffer, TypedArray, or
DataView, then inputEncoding is ignored.
This can be called many times with new data as it is streamed.
Class: Hmac#
- Extends:
<stream.Transform>
The Hmac class is a utility for creating cryptographic HMAC digests. It can
be used in one of two ways:
- As a stream that is both readable and writable, where data is written to produce a computed HMAC digest on the readable side, or
- Using the
hmac.update()andhmac.digest()methods to produce the computed HMAC digest.
The crypto.createHmac() method is used to create Hmac instances. Hmac
objects are not to be created directly using the new keyword.
Example: Using Hmac objects as streams:
const { createHmac, } = await import('node:crypto'); const hmac = createHmac('sha256', 'a secret'); hmac.on('readable', () => { // Only one element is going to be produced by the // hash stream. const data = hmac.read(); if (data) { console.log(data.toString('hex')); // Prints: // 7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e } }); hmac.write('some data to hash'); hmac.end();const { createHmac, } = require('node:crypto'); const hmac = createHmac('sha256', 'a secret'); hmac.on('readable', () => { // Only one element is going to be produced by the // hash stream. const data = hmac.read(); if (data) { console.log(data.toString('hex')); // Prints: // 7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e } }); hmac.write('some data to hash'); hmac.end();
Example: Using Hmac and piped streams:
import { createReadStream } from 'node:fs'; import { stdout } from 'node:process'; const { createHmac, } = await import('node:crypto'); const hmac = createHmac('sha256', 'a secret'); const input = createReadStream('test.js'); input.pipe(hmac).pipe(stdout);const { createReadStream, } = require('node:fs'); const { createHmac, } = require('node:crypto'); const { stdout } = require('node:process'); const hmac = createHmac('sha256', 'a secret'); const input = createReadStream('test.js'); input.pipe(hmac).pipe(stdout);
Example: Using the hmac.update() and hmac.digest() methods:
const { createHmac, } = await import('node:crypto'); const hmac = createHmac('sha256', 'a secret'); hmac.update('some data to hash'); console.log(hmac.digest('hex')); // Prints: // 7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77econst { createHmac, } = require('node:crypto'); const hmac = createHmac('sha256', 'a secret'); hmac.update('some data to hash'); console.log(hmac.digest('hex')); // Prints: // 7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e
hmac.digest([encoding])#
Calculates the HMAC digest of all of the data passed using hmac.update().
If encoding is
provided a string is returned; otherwise a Buffer is returned;
The Hmac object can not be used again after hmac.digest() has been
called. Multiple calls to hmac.digest() will result in an error being thrown.
hmac.update(data[, inputEncoding])#
data<string>|<Buffer>|<TypedArray>|<DataView>inputEncoding<string>The encoding of thedatastring.
Updates the Hmac content with the given data, the encoding of which
is given in inputEncoding.
If encoding is not provided, and the data is a string, an
encoding of 'utf8' is enforced. If data is a Buffer, TypedArray, or
DataView, then inputEncoding is ignored.
This can be called many times with new data as it is streamed.
Class: KeyObject#
Node.js uses a KeyObject class to represent a symmetric or asymmetric key,
and each kind of key exposes different functions. The
crypto.createSecretKey(), crypto.createPublicKey() and
crypto.createPrivateKey() methods are used to create KeyObject
instances. KeyObject objects are not to be created directly using the new
keyword.
Most applications should consider using the new KeyObject API instead of
passing keys as strings or Buffers due to improved security features.
KeyObject instances can be passed to other threads via postMessage().
The receiver obtains a cloned KeyObject, and the KeyObject does not need to
be listed in the transferList argument.
Static method: KeyObject.from(key)#
key<CryptoKey>- Returns:
<KeyObject>
Returns the underlying <KeyObject> of a <CryptoKey>. The returned <KeyObject>
does not retain any of the restrictions imposed by the Web Crypto API on the
original <CryptoKey>, such as the allowed key usages, the algorithm or hash
algorithm bindings, and the extractability flag. In particular, the underlying
key material of the returned <KeyObject> can always be exported.
const { KeyObject } = await import('node:crypto'); const { subtle } = globalThis.crypto; const key = await subtle.generateKey({ name: 'HMAC', hash: 'SHA-256', length: 256, }, true, ['sign', 'verify']); const keyObject = KeyObject.from(key); console.log(keyObject.symmetricKeySize); // Prints: 32 (symmetric key size in bytes)const { KeyObject } = require('node:crypto'); const { subtle } = globalThis.crypto; (async function() { const key = await subtle.generateKey({ name: 'HMAC', hash: 'SHA-256', length: 256, }, true, ['sign', 'verify']); const keyObject = KeyObject.from(key); console.log(keyObject.symmetricKeySize); // Prints: 32 (symmetric key size in bytes) })();
keyObject.asymmetricKeyDetails#
- Type:
<Object>modulusLength<number>Key size in bits (RSA, DSA).publicExponent<bigint>Public exponent (RSA).hashAlgorithm<string>Name of the message digest (RSA-PSS).mgf1HashAlgorithm<string>Name of the message digest used by MGF1 (RSA-PSS).saltLength<number>Minimal salt length in bytes (RSA-PSS).divisorLength<number>Size ofqin bits (DSA).namedCurve<string>Name of the curve (EC).
This property exists only on asymmetric keys. Depending on the type of the key, this object contains information about the key. None of the information obtained through this property can be used to uniquely identify a key or to compromise the security of the key.
For RSA-PSS keys, if the key material contains a RSASSA-PSS-params sequence,
the hashAlgorithm, mgf1HashAlgorithm, and saltLength properties will be
set.
Other key details might be exposed via this API using additional attributes.
keyObject.asymmetricKeyType#
- Type:
<string>
For asymmetric keys, this property represents the type of the key. See the supported asymmetric key types.
This property is undefined for unrecognized KeyObject types and symmetric
keys.
keyObject.equals(otherKeyObject)#
otherKeyObject<KeyObject>AKeyObjectwith which to comparekeyObject.- Returns:
<boolean>
Returns true or false depending on whether the keys have exactly the same
type, value, and parameters. This method is not
constant time.
keyObject.export([options])#
For symmetric keys, the following encoding options can be used:
format<string>Must be'buffer'(default) or'jwk'.
For public keys, the following encoding options can be used:
format<string>Must be'pem','der','jwk', or'raw-public'. See asymmetric key types for format support.type<string>Whenformatis'pem'or'der', must be'pkcs1'(RSA only) or'spki'. For EC keys with'raw-public'format, may be'uncompressed'(default) or'compressed'. Ignored whenformatis'jwk'.
For private keys, the following encoding options can be used:
format<string>Must be'pem','der','jwk','raw-private', or'raw-seed'. See asymmetric key types for format support.type<string>Whenformatis'pem'or'der', must be'pkcs1'(RSA only),'pkcs8', or'sec1'(EC only). Ignored whenformatis'jwk','raw-private', or'raw-seed'.cipher<string>If specified, the private key will be encrypted with the givencipherandpassphraseusing PKCS#5 v2.0 password based encryption. Ignored whenformatis'jwk','raw-private', or'raw-seed'.passphrase<string>|<Buffer>The passphrase to use for encryption. Required whencipheris specified.
The result type depends on the selected encoding format, when PEM the
result is a string, when DER it will be a buffer containing the data
encoded as DER, when JWK it will be an object. Raw formats return a
<Buffer> containing the raw key material.
Private keys can be encrypted by specifying a cipher and passphrase.
The PKCS#8 type supports encryption with both PEM and DER format for any
key algorithm. PKCS#1 and SEC1 can only be encrypted when the PEM format is
used. For maximum compatibility, use PKCS#8 for encrypted private keys. Since
PKCS#8 defines its own encryption mechanism, PEM-level encryption is not
supported when encrypting a PKCS#8 key. See RFC 5208 for PKCS#8 encryption
and RFC 1421 for PKCS#1 and SEC1 encryption.
keyObject.symmetricKeySize#
- Type:
<number>
For secret keys, this property represents the size of the key in bytes. This
property is undefined for asymmetric keys.
keyObject.toCryptoKey(algorithm, extractable, keyUsages)#
algorithm<string>|<Algorithm>|<RsaHashedImportParams>|<EcKeyImportParams>|<HmacImportParams>
extractable<boolean>keyUsages<string>[] See Key usages.- Returns:
<CryptoKey>
Converts a KeyObject instance to a CryptoKey.
keyObject.type#
- Type:
<string>
Depending on the type of this KeyObject, this property is either
'secret' for secret (symmetric) keys, 'public' for public (asymmetric) keys
or 'private' for private (asymmetric) keys.
Class: Mac#
- Extends:
<stream.Transform>
The Mac class computes message authentication codes using MAC
implementations supplied by OpenSSL providers. It can be used in one of two
ways:
- As a stream that is both readable and writable, where data is written and one authentication tag is produced on the readable side when the writable side ends; or
- By calling
mac.update()one or more times followed bymac.final().
Instances of Mac are created using crypto.createMac(). The Mac class
is not exported directly by the node:crypto module.
Calling mac.end() without first writing data computes the authentication tag
for an empty message. If the selected MAC produces a zero-byte tag, such as
when a provider accepts outputLength: 0, the readable side ends without
emitting a data chunk because Node.js streams do not emit zero-length chunks.
When using mac.final() instead, it returns a zero-length Buffer or an
empty encoded string.
mac.end() and mac.final() are alternative terminal operations and must not
both be called on the same object. A Mac object cannot be used again after
either operation attempts finalization or after an underlying MAC update fails.
Example: Using mac.update() and mac.final():
const { createMac, randomBytes } = await import('node:crypto');
const key = randomBytes(16);
const mac = createMac('CMAC', key, {
cipher: 'AES-128-CBC',
});
mac.update('some data to authenticate');
console.log(mac.final('hex'));
mac.final([outputEncoding])#
Completes the MAC computation and returns the authentication tag. If
outputEncoding is omitted or is 'buffer', a Buffer is returned.
Otherwise, a string is returned.
To verify an authentication tag, compare equal-length Buffer values using
crypto.timingSafeEqual().
The Mac object cannot be used again after finalization is attempted,
including when finalization fails. Later calls to mac.update() or
mac.final() throw ERR_CRYPTO_MAC_FINALIZED.
mac.update(data[, inputEncoding])#
data<string>|<Buffer>|<TypedArray>|<DataView>inputEncoding<string>The encoding of thedatastring.- Returns: {Mac}
Updates the MAC with data and returns the Mac object so that calls can be
chained. When data is a string, inputEncoding defaults to 'utf8'. When
data is a Buffer, TypedArray, or DataView, inputEncoding is
ignored.
This method can be called multiple times before finalization. If an underlying
MAC update fails, the Mac object cannot be used again. Calling this method
after a previous underlying MAC update failure or after finalization throws
ERR_CRYPTO_MAC_FINALIZED.
Class: Sign#
- Extends:
<stream.Writable>
The Sign class is a utility for generating signatures. It can be used in one
of two ways:
- As a writable stream, where data to be signed is written and the
sign.sign()method is used to generate and return the signature, or - Using the
sign.update()andsign.sign()methods to produce the signature.
The crypto.createSign() method is used to create Sign instances. The
argument is the string name of the hash function to use. Sign objects are not
to be created directly using the new keyword.
Example: Using Sign and Verify objects as streams:
const { generateKeyPairSync, createSign, createVerify, } = await import('node:crypto'); const { privateKey, publicKey } = generateKeyPairSync('ec', { namedCurve: 'sect239k1', }); const sign = createSign('SHA256'); sign.write('some data to sign'); sign.end(); const signature = sign.sign(privateKey, 'hex'); const verify = createVerify('SHA256'); verify.write('some data to sign'); verify.end(); console.log(verify.verify(publicKey, signature, 'hex')); // Prints: trueconst { generateKeyPairSync, createSign, createVerify, } = require('node:crypto'); const { privateKey, publicKey } = generateKeyPairSync('ec', { namedCurve: 'sect239k1', }); const sign = createSign('SHA256'); sign.write('some data to sign'); sign.end(); const signature = sign.sign(privateKey, 'hex'); const verify = createVerify('SHA256'); verify.write('some data to sign'); verify.end(); console.log(verify.verify(publicKey, signature, 'hex')); // Prints: true
Example: Using the sign.update() and verify.update() methods:
const { generateKeyPairSync, createSign, createVerify, } = await import('node:crypto'); const { privateKey, publicKey } = generateKeyPairSync('rsa', { modulusLength: 2048, }); const sign = createSign('SHA256'); sign.update('some data to sign'); sign.end(); const signature = sign.sign(privateKey); const verify = createVerify('SHA256'); verify.update('some data to sign'); verify.end(); console.log(verify.verify(publicKey, signature)); // Prints: trueconst { generateKeyPairSync, createSign, createVerify, } = require('node:crypto'); const { privateKey, publicKey } = generateKeyPairSync('rsa', { modulusLength: 2048, }); const sign = createSign('SHA256'); sign.update('some data to sign'); sign.end(); const signature = sign.sign(privateKey); const verify = createVerify('SHA256'); verify.update('some data to sign'); verify.end(); console.log(verify.verify(publicKey, signature)); // Prints: true
sign.sign(privateKey[, outputEncoding])#
privateKey<Object>|<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<KeyObject>|<CryptoKey>|<URL>outputEncoding<string>The encoding of the return value.- Returns:
<Buffer>|<string>
Calculates the signature on all the data passed through using either
sign.update() or sign.write().
If privateKey is not a KeyObject, this function behaves as if
privateKey had been passed to crypto.createPrivateKey(). When
privateKey is a string, ArrayBuffer, Buffer, TypedArray, or
DataView, it must contain PEM-encoded key material. If it is an object, the
following additional properties can be passed:
-
dsaEncoding<string>For DSA and ECDSA, this option specifies the format of the generated signature. It can be one of the following:'der'(default): DER-encoded ASN.1 signature structure encoding(r, s).'ieee-p1363': Signature formatr || sas proposed in IEEE-P1363.
-
padding<integer>Optional padding value for RSA, one of the following:crypto.constants.RSA_PKCS1_PADDING(default)crypto.constants.RSA_PKCS1_PSS_PADDING
RSA_PKCS1_PSS_PADDINGwill use MGF1 with the same hash function used to sign the message as specified in section 3.1 of RFC 4055, unless an MGF1 hash function has been specified as part of the key in compliance with section 3.3 of RFC 4055. -
saltLength<integer>Salt length for when padding isRSA_PKCS1_PSS_PADDING. The special valuecrypto.constants.RSA_PSS_SALTLEN_DIGESTsets the salt length to the digest size,crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN(default) sets it to the maximum permissible value.
If outputEncoding is provided a string is returned; otherwise a Buffer
is returned.
The Sign object can not be again used after sign.sign() method has been
called. Multiple calls to sign.sign() will result in an error being thrown.
sign.update(data[, inputEncoding])#
data<string>|<Buffer>|<TypedArray>|<DataView>inputEncoding<string>The encoding of thedatastring.
Updates the Sign content with the given data, the encoding of which
is given in inputEncoding.
If encoding is not provided, and the data is a string, an
encoding of 'utf8' is enforced. If data is a Buffer, TypedArray, or
DataView, then inputEncoding is ignored.
This can be called many times with new data as it is streamed.
Class: Verify#
- Extends:
<stream.Writable>
The Verify class is a utility for verifying signatures. It can be used in one
of two ways:
- As a writable stream where written data is used to validate against the supplied signature, or
- Using the
verify.update()andverify.verify()methods to verify the signature.
The crypto.createVerify() method is used to create Verify instances.
Verify objects are not to be created directly using the new keyword.
See Sign for examples.
verify.update(data[, inputEncoding])#
data<string>|<Buffer>|<TypedArray>|<DataView>inputEncoding<string>The encoding of thedatastring.
Updates the Verify content with the given data, the encoding of which
is given in inputEncoding.
If inputEncoding is not provided, and the data is a string, an
encoding of 'utf8' is enforced. If data is a Buffer, TypedArray, or
DataView, then inputEncoding is ignored.
This can be called many times with new data as it is streamed.
verify.verify(key, signature[, signatureEncoding])#
key<Object>|<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<KeyObject>|<CryptoKey>signature<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>signatureEncoding<string>The encoding of thesignaturestring.- Returns:
<boolean>trueorfalsedepending on the validity of the signature for the data and public key.
Verifies the provided data using the given key and signature.
If key is not a KeyObject, this function behaves as if
key had been passed to crypto.createPublicKey(). When key is a string,
ArrayBuffer, Buffer, TypedArray, or DataView, it must contain
PEM-encoded key material. If it is an object, the following additional
properties can be passed:
-
dsaEncoding<string>For DSA and ECDSA, this option specifies the format of the signature. It can be one of the following:'der'(default): DER-encoded ASN.1 signature structure encoding(r, s).'ieee-p1363': Signature formatr || sas proposed in IEEE-P1363.
-
padding<integer>Optional padding value for RSA, one of the following:crypto.constants.RSA_PKCS1_PADDING(default)crypto.constants.RSA_PKCS1_PSS_PADDING
RSA_PKCS1_PSS_PADDINGwill use MGF1 with the same hash function used to verify the message as specified in section 3.1 of RFC 4055, unless an MGF1 hash function has been specified as part of the key in compliance with section 3.3 of RFC 4055. -
saltLength<integer>Salt length for when padding isRSA_PKCS1_PSS_PADDING. The special valuecrypto.constants.RSA_PSS_SALTLEN_DIGESTsets the salt length to the digest size,crypto.constants.RSA_PSS_SALTLEN_AUTO(default) causes it to be determined automatically.
The signature argument is the previously calculated signature for the data, in
the signatureEncoding.
If a signatureEncoding is specified, the signature is expected to be a
string; otherwise signature is expected to be a Buffer,
TypedArray, or DataView.
The verify object can not be used again after verify.verify() has been
called. Multiple calls to verify.verify() will result in an error being
thrown.
Because public keys can be derived from private keys, a private key may be passed instead of a public key.
Class: X509Certificate#
Encapsulates an X509 certificate and provides read-only access to its information.
const { X509Certificate } = await import('node:crypto'); const x509 = new X509Certificate('{... pem encoded cert ...}'); console.log(x509.subject);const { X509Certificate } = require('node:crypto'); const x509 = new X509Certificate('{... pem encoded cert ...}'); console.log(x509.subject);
new X509Certificate(buffer)#
buffer<string>|<TypedArray>|<Buffer>|<DataView>A PEM or DER encoded X509 Certificate.
x509.ca#
- Type:
<boolean>Will betrueif this is a Certificate Authority (CA) certificate.
x509.checkEmail(email[, options])#
email<string>options<Object>subject<string>'default','always', or'never'. Default:'default'.
- Returns:
<string>|<undefined>Returnsemailif the certificate matches,undefinedif it does not.
Checks whether the certificate matches the given email address.
If the 'subject' option is undefined or set to 'default', the certificate
subject is considered according to OpenSSL's default behavior.
If the 'subject' option is set to 'always' and if the subject alternative
name extension either does not exist or does not contain a matching email
address, the certificate subject is considered.
If the 'subject' option is set to 'never', the certificate subject is never
considered, even if the certificate contains no subject alternative names.
x509.checkHost(name[, options])#
name<string>options<Object>- Returns:
<string>|<undefined>Returns a subject name that matchesname, orundefinedif no subject name matchesname.
Checks whether the certificate matches the given host name.
If the certificate matches the given host name, the matching subject name is
returned. The returned name might be an exact match (e.g., foo.example.com)
or it might contain wildcards (e.g., *.example.com). Because host name
comparisons are case-insensitive, the returned subject name might also differ
from the given name in capitalization.
If the 'subject' option is undefined or set to 'default', the certificate
subject is considered according to OpenSSL's default behavior.
If the 'subject' option is set to 'always' and if the subject alternative
name extension either does not exist or does not contain a matching DNS name,
the certificate subject is considered.
If the 'subject' option is set to 'never', the certificate subject is never
considered, even if the certificate contains no subject alternative names.
x509.checkIP(ip)#
ip<string>- Returns:
<string>|<undefined>Returnsipif the certificate matches,undefinedif it does not.
Checks whether the certificate matches the given IP address (IPv4 or IPv6).
Only RFC 5280 iPAddress subject alternative names are considered, and they
must match the given ip address exactly. Other subject alternative names as
well as the subject field of the certificate are ignored.
x509.checkIssued(otherCert)#
otherCert<X509Certificate>- Returns:
<boolean>
Checks whether this certificate was potentially issued by the given otherCert
by comparing the certificate metadata.
This is useful for pruning a list of possible issuer certificates which have been selected using a more rudimentary filtering routine, i.e. just based on subject and issuer names.
Finally, to verify that this certificate's signature was produced by a private key
corresponding to otherCert's public key use x509.verify(publicKey)
with otherCert's public key represented as a KeyObject
like so
if (!x509.verify(otherCert.publicKey)) {
throw new Error('otherCert did not issue x509');
}
x509.checkPrivateKey(privateKey)#
privateKey<KeyObject>A private key.- Returns:
<boolean>
Checks whether the public key for this certificate is consistent with the given private key.
x509.fingerprint#
- Type:
<string>
The SHA-1 fingerprint of this certificate.
Because SHA-1 is cryptographically broken and because the security of SHA-1 is
significantly worse than that of algorithms that are commonly used to sign
certificates, consider using x509.fingerprint256 instead.
x509.fingerprint256#
- Type:
<string>
The SHA-256 fingerprint of this certificate.
x509.fingerprint512#
- Type:
<string>
The SHA-512 fingerprint of this certificate.
Because computing the SHA-256 fingerprint is usually faster and because it is
only half the size of the SHA-512 fingerprint, x509.fingerprint256 may be
a better choice. While SHA-512 presumably provides a higher level of security in
general, the security of SHA-256 matches that of most algorithms that are
commonly used to sign certificates.
x509.infoAccess#
- Type:
<string>
A textual representation of the certificate's authority information access extension.
This is a line feed separated list of access descriptions. Each line begins with the access method and the kind of the access location, followed by a colon and the value associated with the access location.
After the prefix denoting the access method and the kind of the access location, the remainder of each line might be enclosed in quotes to indicate that the value is a JSON string literal. For backward compatibility, Node.js only uses JSON string literals within this property when necessary to avoid ambiguity. Third-party code should be prepared to handle both possible entry formats.
x509.issuer#
- Type:
<string>
The issuer identification included in this certificate.
x509.issuerCertificate#
- Type:
<X509Certificate>
The issuer certificate or undefined if the issuer certificate is not
available.
x509.keyUsage#
- Type:
<string>[]
An array detailing the key extended usages for this certificate.
x509.publicKey#
- Type:
<KeyObject>
The public key <KeyObject> for this certificate.
x509.raw#
- Type:
<Buffer>
A Buffer containing the DER encoding of this certificate.
x509.serialNumber#
- Type:
<string>
The serial number of this certificate.
Serial numbers are assigned by certificate authorities and do not uniquely
identify certificates. Consider using x509.fingerprint256 as a unique
identifier instead.
x509.subject#
- Type:
<string>
The complete subject of this certificate.
x509.subjectAltName#
- Type:
<string>
The subject alternative name specified for this certificate.
This is a comma-separated list of subject alternative names. Each entry begins with a string identifying the kind of the subject alternative name followed by a colon and the value associated with the entry.
Earlier versions of Node.js incorrectly assumed that it is safe to split this
property at the two-character sequence ', ' (see CVE-2021-44532). However,
both malicious and legitimate certificates can contain subject alternative names
that include this sequence when represented as a string.
After the prefix denoting the type of the entry, the remainder of each entry might be enclosed in quotes to indicate that the value is a JSON string literal. For backward compatibility, Node.js only uses JSON string literals within this property when necessary to avoid ambiguity. Third-party code should be prepared to handle both possible entry formats.
x509.toJSON()#
- Type:
<string>
There is no standard JSON encoding for X509 certificates. The
toJSON() method returns a string containing the PEM encoded
certificate.
x509.toLegacyObject()#
- Type:
<Object>
Returns information about this certificate using the legacy certificate object encoding.
x509.toString()#
- Type:
<string>
Returns the PEM-encoded certificate.
x509.validFrom#
- Type:
<string>
The date/time from which this certificate is valid.
x509.validFromDate#
- Type:
<Date>
The date/time from which this certificate is valid, encapsulated in a Date object.
x509.validTo#
- Type:
<string>
The date/time until which this certificate is valid.
x509.validToDate#
- Type:
<Date>
The date/time until which this certificate is valid, encapsulated in a Date object.
x509.signatureAlgorithm#
- Type:
<string>|<undefined>
The algorithm used to sign the certificate or undefined if the signature algorithm is unknown by OpenSSL.
x509.signatureAlgorithmOid#
- Type:
<string>
The OID of the algorithm used to sign the certificate.
x509.verify(publicKey)#
publicKey<KeyObject>A public key.- Returns:
<boolean>
Verifies that this certificate was signed by the given public key. Does not perform any other validation checks on the certificate.
node:crypto module methods and properties#
crypto.argon2(algorithm, parameters, callback)#
algorithm<string>Variant of Argon2, one of"argon2d","argon2i"or"argon2id".parameters<Object>message<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>REQUIRED, this is the password for password hashing applications of Argon2.nonce<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>REQUIRED, must be at least 8 bytes long. This is the salt for password hashing applications of Argon2.parallelism<number>REQUIRED, degree of parallelism determines how many computational chains (lanes) can be run. Must be at least1and at most2**24-1.tagLength<number>REQUIRED, the length of the key to generate. Must be at least4and at most2**32-1.memory<number>REQUIRED, memory cost in 1KiB blocks. Must be at least8 * parallelismand at most2**32-1. The actual number of blocks is rounded down to the nearest multiple of4 * parallelism.passes<number>REQUIRED, number of passes (iterations). Must be at least1and at most2**32-1.secret<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<undefined>OPTIONAL, Random additional input, similar to the salt, that should NOT be stored with the derived key. This is known as pepper in password hashing applications. If used, must have a length not greater than2**32-1bytes.associatedData<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<undefined>OPTIONAL, Additional data to be added to the hash, functionally equivalent to salt or secret, but meant for non-random data. If used, must have a length not greater than2**32-1bytes.
callback<Function>
Provides an asynchronous Argon2 implementation. Argon2 is a password-based key derivation function that is designed to be expensive computationally and memory-wise in order to make brute-force attacks unrewarding.
The nonce should be as unique as possible. It is recommended that a nonce is
random and at least 16 bytes long. See NIST SP 800-132 for details.
When passing strings for message, nonce, secret or associatedData, please
consider caveats when using strings as inputs to cryptographic APIs.
The callback function is called with two arguments: err and derivedKey.
err is an exception object when key derivation fails, otherwise err is
null. derivedKey is passed to the callback as a Buffer.
An exception is thrown when any of the input arguments specify invalid values or types.
const { argon2, randomBytes } = await import('node:crypto'); const parameters = { message: 'password', nonce: randomBytes(16), parallelism: 4, tagLength: 64, memory: 65536, passes: 3, }; argon2('argon2id', parameters, (err, derivedKey) => { if (err) throw err; console.log(derivedKey.toString('hex')); // 'af91dad...9520f15' });const { argon2, randomBytes } = require('node:crypto'); const parameters = { message: 'password', nonce: randomBytes(16), parallelism: 4, tagLength: 64, memory: 65536, passes: 3, }; argon2('argon2id', parameters, (err, derivedKey) => { if (err) throw err; console.log(derivedKey.toString('hex')); // 'af91dad...9520f15' });
crypto.argon2Sync(algorithm, parameters)#
algorithm<string>Variant of Argon2, one of"argon2d","argon2i"or"argon2id".parameters<Object>message<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>REQUIRED, this is the password for password hashing applications of Argon2.nonce<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>REQUIRED, must be at least 8 bytes long. This is the salt for password hashing applications of Argon2.parallelism<number>REQUIRED, degree of parallelism determines how many computational chains (lanes) can be run. Must be at least 1 and at most2**24-1.tagLength<number>REQUIRED, the length of the key to generate. Must be at least4and at most2**32-1.memory<number>REQUIRED, memory cost in 1KiB blocks. Must be at least8 * parallelismand at most2**32-1. The actual number of blocks is rounded down to the nearest multiple of4 * parallelism.passes<number>REQUIRED, number of passes (iterations). Must be at least1and at most2**32-1.secret<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<undefined>OPTIONAL, Random additional input, similar to the salt, that should NOT be stored with the derived key. This is known as pepper in password hashing applications. If used, must have a length not greater than2**32-1bytes.associatedData<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<undefined>OPTIONAL, Additional data to be added to the hash, functionally equivalent to salt or secret, but meant for non-random data. If used, must have a length not greater than2**32-1bytes.
- Returns:
<Buffer>
Provides a synchronous Argon2 implementation. Argon2 is a password-based key derivation function that is designed to be expensive computationally and memory-wise in order to make brute-force attacks unrewarding.
The nonce should be as unique as possible. It is recommended that a nonce is
random and at least 16 bytes long. See NIST SP 800-132 for details.
When passing strings for message, nonce, secret or associatedData, please
consider caveats when using strings as inputs to cryptographic APIs.
An exception is thrown when key derivation fails, otherwise the derived key is
returned as a Buffer.
An exception is thrown when any of the input arguments specify invalid values or types.
const { argon2Sync, randomBytes } = await import('node:crypto'); const parameters = { message: 'password', nonce: randomBytes(16), parallelism: 4, tagLength: 64, memory: 65536, passes: 3, }; const derivedKey = argon2Sync('argon2id', parameters); console.log(derivedKey.toString('hex')); // 'af91dad...9520f15'const { argon2Sync, randomBytes } = require('node:crypto'); const parameters = { message: 'password', nonce: randomBytes(16), parallelism: 4, tagLength: 64, memory: 65536, passes: 3, }; const derivedKey = argon2Sync('argon2id', parameters); console.log(derivedKey.toString('hex')); // 'af91dad...9520f15'
crypto.checkPrime(candidate[, options], callback)#
candidate<ArrayBuffer>|<SharedArrayBuffer>|<TypedArray>|<Buffer>|<DataView>|<bigint>A possible prime encoded as a sequence of big endian octets of arbitrary length.options<Object>checks<number>The number of Miller-Rabin probabilistic primality iterations to perform. When the value is0(zero), a number of checks is used that yields a false positive rate of at most 2-64 for random input. Care must be used when selecting a number of checks. Refer to the OpenSSL documentation for theBN_is_prime_exfunctionnchecksoptions for more details. Default:0
callback<Function>
Checks the primality of the candidate.
crypto.checkPrimeSync(candidate[, options])#
candidate<ArrayBuffer>|<SharedArrayBuffer>|<TypedArray>|<Buffer>|<DataView>|<bigint>A possible prime encoded as a sequence of big endian octets of arbitrary length.options<Object>checks<number>The number of Miller-Rabin probabilistic primality iterations to perform. When the value is0(zero), a number of checks is used that yields a false positive rate of at most 2-64 for random input. Care must be used when selecting a number of checks. Refer to the OpenSSL documentation for theBN_is_prime_exfunctionnchecksoptions for more details. Default:0
- Returns:
<boolean>trueif the candidate is a prime with an error probability less than0.25 ** options.checks.
Checks the primality of the candidate.
crypto.constants#
- Type:
<Object>
An object containing commonly used constants for crypto and security related operations. The specific constants currently defined are described in Crypto constants.
crypto.createCipheriv(algorithm, key, iv[, options])#
algorithm<string>key<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<KeyObject>|<CryptoKey>iv<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<null>options<Object>stream.transformoptions with these additional properties:authTagLength<number>The authentication tag length in bytes. Its requirements and default depend on the authenticated cipher, as described below.ctsMode<string>The CBC-CTS mode variant. One of'CS1','CS2', or'CS3'. The values are case-sensitive. Default:'CS1'.encoding<string>The encoding to use whenkeyis a string. This option does not affect a stringiv, which is always interpreted as UTF-8. Default:'utf8'.xtsStandard<string>The standard used bysm4-xts. One of'GB'or'IEEE'. The values are case-sensitive. Default:'GB'.
- Returns:
<Cipheriv>
Creates and returns a Cipheriv object, with the given algorithm, key and
initialization vector (iv).
The options argument controls cipher-specific settings and stream behavior.
It is optional except when a cipher in CCM or OCB mode (e.g. 'aes-128-ccm')
is used. In that case, the authTagLength option is required and specifies the
length of the authentication tag in bytes, see CCM mode. In GCM mode, the
authTagLength option is not required but can be used to set the length of the
authentication tag that will be returned by getAuthTag() and defaults to 16
bytes.
For SIV, GCM-SIV, and chacha20-poly1305, the authTagLength option
defaults to 16 bytes. SIV and GCM-SIV only support 16-byte authentication
tags.
The ctsMode and xtsStandard options configure parameters exposed by OpenSSL
providers. They are available only with OpenSSL 3.0 or later and a provider
that supports the corresponding parameter. ctsMode applies only to CBC-CTS
ciphers, and xtsStandard applies only to sm4-xts. Supplying either option
for an available cipher implementation that does not support it throws an
ERR_CRYPTO_UNSUPPORTED_OPERATION error. See CBC-CTS mode and XTS mode
for details.
The available algorithms depend on OpenSSL. crypto.getCiphers() lists the
algorithms exposed by Node.js. On recent OpenSSL releases,
openssl list -cipher-algorithms displays the algorithms available to OpenSSL,
which can include algorithms that Node.js does not expose.
The key is the raw key used by the algorithm and iv is an
initialization vector. Each may be a string, ArrayBuffer, Buffer,
TypedArray, or DataView. A string key is decoded using options.encoding,
which defaults to 'utf8'; a string iv is always decoded as UTF-8. The key
may optionally be a KeyObject of type secret. If the cipher does not
need an initialization vector, iv may be null.
When passing strings for key or iv, please consider
caveats when using strings as inputs to cryptographic APIs.
Initialization vector requirements depend on the algorithm. For some algorithms, an IV must be unpredictable and unique; for others, uniqueness alone is sufficient, a fixed value is required, or no IV is used. Follow the requirements for the selected algorithm. IVs typically do not have to be secret and can be transmitted with the ciphertext.
crypto.createDecipheriv(algorithm, key, iv[, options])#
algorithm<string>key<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<KeyObject>|<CryptoKey>iv<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<null>options<Object>stream.transformoptions with these additional properties:authTagLength<number>The authentication tag length in bytes. Its requirements and default depend on the authenticated cipher, as described below.ctsMode<string>The CBC-CTS mode variant. One of'CS1','CS2', or'CS3'. The values are case-sensitive. Default:'CS1'.encoding<string>The encoding to use whenkeyis a string. This option does not affect a stringiv, which is always interpreted as UTF-8. Default:'utf8'.xtsStandard<string>The standard used bysm4-xts. One of'GB'or'IEEE'. The values are case-sensitive. Default:'GB'.
- Returns:
<Decipheriv>
Creates and returns a Decipheriv object that uses the given algorithm, key
and initialization vector (iv).
The options argument controls cipher-specific settings and stream behavior.
It is optional except when a cipher in CCM or OCB mode (e.g. 'aes-128-ccm')
is used. In that case, the authTagLength option is required and specifies the
length of the authentication tag in bytes, see CCM mode. For GCM and
chacha20-poly1305, the authTagLength option defaults to 16 bytes and must be
set if a different length is used. For SIV and GCM-SIV, the authTagLength
option defaults to 16 bytes and only 16-byte authentication tags are supported.
The ctsMode and xtsStandard options configure parameters exposed by OpenSSL
providers. They are available only with OpenSSL 3.0 or later and a provider
that supports the corresponding parameter. ctsMode applies only to CBC-CTS
ciphers, and xtsStandard applies only to sm4-xts. Supplying either option
for an available cipher implementation that does not support it throws an
ERR_CRYPTO_UNSUPPORTED_OPERATION error. See CBC-CTS mode and XTS mode
for details.
The available algorithms depend on OpenSSL. crypto.getCiphers() lists the
algorithms exposed by Node.js. On recent OpenSSL releases,
openssl list -cipher-algorithms displays the algorithms available to OpenSSL,
which can include algorithms that Node.js does not expose.
The key is the raw key used by the algorithm and iv is an
initialization vector. Each may be a string, ArrayBuffer, Buffer,
TypedArray, or DataView. A string key is decoded using options.encoding,
which defaults to 'utf8'; a string iv is always decoded as UTF-8. The key
may optionally be a KeyObject of type secret. If the cipher does not
need an initialization vector, iv may be null.
When passing strings for key or iv, please consider
caveats when using strings as inputs to cryptographic APIs.
Initialization vector requirements depend on the algorithm. For some algorithms, an IV must be unpredictable and unique; for others, uniqueness alone is sufficient, a fixed value is required, or no IV is used. Follow the requirements for the selected algorithm. IVs typically do not have to be secret and can be transmitted with the ciphertext.
crypto.createDiffieHellman(prime[, primeEncoding][, generator][, generatorEncoding])#
prime<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>primeEncoding<string>The encoding of theprimestring.generator<number>|<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>Default:2generatorEncoding<string>The encoding of thegeneratorstring.- Returns:
<DiffieHellman>
Creates a DiffieHellman key exchange object using the supplied prime and an
optional specific generator.
The generator argument can be a number, string, or Buffer. If
generator is not specified, the value 2 is used.
If primeEncoding is specified, prime is expected to be a string; otherwise
a Buffer, TypedArray, or DataView is expected.
If generatorEncoding is specified, generator is expected to be a string;
otherwise a number, Buffer, TypedArray, or DataView is expected.
crypto.createDiffieHellman(primeLength[, generator])#
primeLength<number>generator<number>Default:2- Returns:
<DiffieHellman>
Creates a DiffieHellman key exchange object and generates a prime of
primeLength bits using an optional specific numeric generator.
If generator is not specified, the value 2 is used.
crypto.createDiffieHellmanGroup(name)#
name<string>- Returns:
<DiffieHellmanGroup>
An alias for crypto.getDiffieHellman()
crypto.createECDH(curveName)#
Creates an Elliptic Curve Diffie-Hellman (ECDH) key exchange object using a
predefined curve specified by the curveName string. Use
crypto.getCurves() to obtain a list of available curve names. On recent
OpenSSL releases, openssl ecparam -list_curves will also display the name
and description of each available elliptic curve.
crypto.createHash(algorithm[, options])#
algorithm<string>options<Object>stream.transformoptionscustomization<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>For cSHAKE hash functions, specifies the customization byte string. Default: an empty byte string.functionName<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>For cSHAKE hash functions, specifies the NIST function-name byte string. Default: an empty byte string.outputLength<number>For XOF hash functions, specifies the desired output length in bytes.
- Returns:
<Hash>
Creates and returns a Hash object that can be used to generate hash digests
using the given algorithm. Optional options argument controls stream
behavior. For XOF hash functions such as 'shake256', the outputLength option
can be used to specify the desired output length in bytes.
The functionName and customization options apply only to cSHAKE-128 and
cSHAKE-256. They are supported only when Node.js is built with OpenSSL 4.0 or
later and the selected provider supports the corresponding digest parameters.
Strings are encoded as UTF-8, and neither strings nor byte values may contain
NUL bytes. Both options default to an empty byte string. For OpenSSL's built-in
providers, functionName is case-sensitive and must be '', 'TupleHash',
'ParallelHash', or 'KMAC'. Other providers can impose different
restrictions. With both options empty, cSHAKE produces the same output as the
corresponding SHAKE function for the same output length. cshake-128 and
cshake-256 default to output lengths of 32 and 64 bytes, respectively.
When the data is small (< 5MB) and readily available, crypto.hash() is usually faster.
The available algorithms depend on the version and configuration of OpenSSL on
the platform. Examples are 'sha256' and 'sha512'. Use
crypto.getHashes() to obtain the list of hash algorithms available to the
Node.js process.
Example: generating the sha256 sum of a file
import { createReadStream, } from 'node:fs'; import { argv } from 'node:process'; const { createHash, } = await import('node:crypto'); const filename = argv[2]; const hash = createHash('sha256'); const input = createReadStream(filename); input.on('readable', () => { // Only one element is going to be produced by the // hash stream. const data = input.read(); if (data) hash.update(data); else { console.log(`${hash.digest('hex')} ${filename}`); } });const { createReadStream, } = require('node:fs'); const { createHash, } = require('node:crypto'); const { argv } = require('node:process'); const filename = argv[2]; const hash = createHash('sha256'); const input = createReadStream(filename); input.on('readable', () => { // Only one element is going to be produced by the // hash stream. const data = input.read(); if (data) hash.update(data); else { console.log(`${hash.digest('hex')} ${filename}`); } });
crypto.createHmac(algorithm, key[, options])#
algorithm<string>key<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<KeyObject>|<CryptoKey>options<Object>stream.transformoptionsencoding<string>The string encoding to use whenkeyis a string.
- Returns:
<Hmac>
Creates and returns an Hmac object that uses the given algorithm and key.
Optional options argument controls stream behavior.
The available algorithms depend on the version and configuration of OpenSSL on
the platform. Examples are 'sha256' and 'sha512'.
crypto.getHashes() lists algorithms available to the hashing APIs, but
HMAC imposes additional restrictions, so not every listed algorithm is
suitable.
The key is the HMAC key used to generate the cryptographic HMAC hash. If it is
a KeyObject, its type must be secret. If it is a string, please consider
caveats when using strings as inputs to cryptographic APIs. If it was
obtained from a cryptographically secure source of entropy, such as
crypto.randomBytes() or crypto.generateKey(), its length should not
exceed the block size of algorithm (e.g., 512 bits for SHA-256).
Example: generating the sha256 HMAC of a file
import { createReadStream, } from 'node:fs'; import { argv } from 'node:process'; const { createHmac, } = await import('node:crypto'); const filename = argv[2]; const hmac = createHmac('sha256', 'a secret'); const input = createReadStream(filename); input.on('readable', () => { // Only one element is going to be produced by the // hash stream. const data = input.read(); if (data) hmac.update(data); else { console.log(`${hmac.digest('hex')} ${filename}`); } });const { createReadStream, } = require('node:fs'); const { createHmac, } = require('node:crypto'); const { argv } = require('node:process'); const filename = argv[2]; const hmac = createHmac('sha256', 'a secret'); const input = createReadStream(filename); input.on('readable', () => { // Only one element is going to be produced by the // hash stream. const data = input.read(); if (data) hmac.update(data); else { console.log(`${hmac.digest('hex')} ${filename}`); } });
crypto.createMac(algorithm, key[, options])#
Stability: 1.2 - Release candidate
algorithm<string>The name of the MAC algorithm.key<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<KeyObject>options<Object>stream.transformoptionsdigest<string>The digest used by a MAC such as HMAC.cipher<string>The cipher used by a MAC such as CMAC or GMAC.iv<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>The initialization vector for a MAC such as GMAC.customization<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>A customization byte string for MACs that support it, such as KMAC.salt<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>A salt byte string for MACs that support it, such as BLAKE2 MACs.outputLength<number>The requested provider output size in bytes. Must be an unsigned 32-bit integer. Provider-specific restrictions also apply.
- Returns: {Mac}
algorithm must be a non-empty provider MAC name. The MAC-specific properties
listed above are extensions to the standard stream.transform options and
are passed only when the selected provider implementation advertises the
corresponding parameter with the expected type. A supplied MAC-specific option
that the selected implementation does not support causes an error.
The following table summarizes the MAC-specific options accepted by MAC
implementations in OpenSSL's built-in providers. The key argument is required
for every MAC. The table lists only MAC-specific options; standard
stream.transform options remain available for every family.
| MAC family | Required options | Optional options | Notes |
|---|---|---|---|
| HMAC | digest |
None | |
| CMAC | cipher using CBC mode |
None | |
| GMAC | cipher using GCM mode, non-empty iv |
None | Requires a unique IV for every message authenticated with a given key. |
| KMAC | None | customization, outputLength |
|
| BLAKE2 MAC | None | customization, salt, outputLength |
|
| Poly1305 | None | None | Each key must be used for only one message. |
| SipHash | None | outputLength |
outputLength configures the output size of the provider MAC. It is never
implemented by computing a longer tag and truncating it. A value of 0 is
passed to the provider and is accepted only when that provider can initialize
and finalize the MAC with a zero-byte output. When outputLength is omitted,
the provider's default output size is used and must be nonzero.
The key must contain bytes or be a KeyObject of type secret. Key
length and other key requirements are determined by the selected provider
implementation.
Available algorithms and their accepted parameters depend on the OpenSSL
version, loaded providers, and active default property query. Use
crypto.getMacs() to list fetchable MAC names. A listed name can still
require options or a key with provider-specific properties.
crypto.createPrivateKey(key)#
key<Object>|<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<URL>key<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<Object>|<URL>The key material, either in PEM, DER, JWK, or raw format, or a<URL>referencing an object for an OpenSSL STORE loader.format<string>Must be'pem','der','jwk','raw-private', or'raw-seed'. Default:'pem'.type<string>Must be'pkcs1','pkcs8'or'sec1'. This option is required only if theformatis'der'and ignored otherwise.passphrase<string>|<Buffer>The passphrase to use for decryption. Whenkeyis a<URL>, this is the optional PIN/passphrase forwarded to the STORE loader.properties<string>The optional OpenSSL property query used when fetching the STORE loader for a<URL>key.encoding<string>The string encoding to use whenkeyis a string.asymmetricKeyType<string>Required whenformatis'raw-private'or'raw-seed'and ignored otherwise. Must be a supported key type.namedCurve<string>Name of the curve to use. Required whenasymmetricKeyTypeis'ec'and ignored otherwise.
- Returns:
<KeyObject>
Creates and returns a new key object containing a private key. If key is a
string or Buffer, format is assumed to be 'pem'; otherwise, key
must be an object with the properties described above.
If the private key is encrypted, a passphrase must be specified. The length
of the passphrase is limited to 1024 bytes.
Private keys from OpenSSL STORE loaders#
Stability: 1.1 - Active development
If key is a <URL> (or an object whose key is a <URL>), the private key is
loaded through an OpenSSL STORE loader. The URL is passed to OpenSSL as a URI,
for example a file: URI or a provider-backed scheme such as pkcs11:. When
the Permission Model is enabled, --allow-openssl-store is required.
Warning: A URI scheme does not pin an OpenSSL STORE loader or prove where the returned key came from. Node.js forwards the URI to OpenSSL, which chooses loaders according to its version and configuration. For example, OpenSSL may offer an opaque URI such as
pkcs11:object=...(one without//after the scheme) to itsfileloader before trying thepkcs11loader. If the complete URI is a valid local path and that file exists, it may be loaded instead. Node.js does not verify which loader supplied the key. Do not rely on a provider-specific URI scheme as proof that a key came from that provider or from a hardware device.
Configured OpenSSL STORE loaders have broad authority and may access files,
devices, tokens, or the network. Access performed by a loader is not constrained
by the fs.read, fs.write, or net permission scopes.
When a <URL> is used, format, type, asymmetricKeyType, and namedCurve
are ignored even when those options would otherwise depend on each other, such
as type with format: 'der' or namedCurve with
asymmetricKeyType: 'ec'. The input is passed to the STORE loader as a URI,
not handled as PEM, DER, JWK, or raw key material. passphrase is still used as
the optional PIN/passphrase passed to the loader, and encoding applies if that
passphrase is a string.
Use passphrase instead of embedding credentials in the URI passed to the
STORE loader. Node.js redacts the URI from its own permission-denial resource
and diagnostics. Errors reported by OpenSSL or a provider after loading begins
may include the URI.
When properties is specified with a <URL> key, it is passed to OpenSSL as the
property query for selecting the STORE loader. It is not appended to the URL and
is distinct from provider-specific URI parameters.
crypto.createPublicKey(key)#
key<Object>|<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>key<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<Object>The key material, either in PEM, DER, JWK, or raw format.format<string>Must be'pem','der','jwk', or'raw-public'. Default:'pem'.type<string>Must be'pkcs1'or'spki'. This option is required only if theformatis'der'and ignored otherwise.encoding<string>The string encoding to use whenkeyis a string.asymmetricKeyType<string>Required whenformatis'raw-public'and ignored otherwise. Must be a supported key type.namedCurve<string>Name of the curve to use. Required whenasymmetricKeyTypeis'ec'and ignored otherwise.
- Returns:
<KeyObject>
Creates and returns a new key object containing a public key. If key is a
string or Buffer, format is assumed to be 'pem'; if key is a KeyObject
with type 'private', the public key is derived from the given private key;
otherwise, key must be an object with the properties described above.
If the format is 'pem', the 'key' may also be an X.509 certificate.
Because public keys can be derived from private keys, a private key may be
passed instead of a public key. In that case, this function behaves as if
crypto.createPrivateKey() had been called, except that the type of the
returned KeyObject will be 'public' and that the private key cannot be
extracted from the returned KeyObject. Similarly, if a KeyObject with type
'private' is given, a new KeyObject with type 'public' will be returned
and it will be impossible to extract the private key from the returned object.
A store-backed private key can be used as a public key by first loading it with
crypto.createPrivateKey(); a <URL> cannot be passed to crypto.createPublicKey() directly.
crypto.createSecretKey(key[, encoding])#
key<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>encoding<string>The string encoding whenkeyis a string.- Returns:
<KeyObject>
Creates and returns a new key object containing a secret key for symmetric
encryption or Hmac.
crypto.createSign(algorithm[, options])#
algorithm<string>options<Object>stream.Writableoptions- Returns:
<Sign>
Creates and returns a Sign object that uses the given algorithm. Use
crypto.getHashes() to obtain the names available to the hashing APIs. The
key type and signature scheme can impose additional restrictions on which
digests can be used. Optional options argument controls the
stream.Writable behavior.
In some cases, a Sign instance can be created using the name of a signature
algorithm, such as 'RSA-SHA256', instead of a digest algorithm. This will use
the corresponding digest algorithm. This does not work for all signature
algorithms, such as 'ecdsa-with-SHA256', so it is best to always use digest
algorithm names.
crypto.createVerify(algorithm[, options])#
algorithm<string>options<Object>stream.Writableoptions- Returns:
<Verify>
Creates and returns a Verify object that uses the given algorithm.
Use crypto.getHashes() to obtain the names available to the hashing APIs.
The key type and signature scheme can impose additional restrictions on which
digests can be used. Optional options argument controls the
stream.Writable behavior.
In some cases, a Verify instance can be created using the name of a signature
algorithm, such as 'RSA-SHA256', instead of a digest algorithm. This will use
the corresponding digest algorithm. This does not work for all signature
algorithms, such as 'ecdsa-with-SHA256', so it is best to always use digest
algorithm names.
crypto.decapsulate(key, ciphertext[, callback])#
key<Object>|<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<KeyObject>|<URL>Private Keyciphertext<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>callback<Function>- Returns:
<Buffer>if thecallbackfunction is not provided.
Key decapsulation using a KEM algorithm with a private key.
Supported key types and their KEM algorithms are:
'rsa'2 RSA Secret Value Encapsulation'ec'3 DHKEM(P-256, HKDF-SHA256), DHKEM(P-384, HKDF-SHA256), DHKEM(P-521, HKDF-SHA256)'x25519'3 DHKEM(X25519, HKDF-SHA256)'x448'3 DHKEM(X448, HKDF-SHA512)'ml-kem-512'1 ML-KEM'ml-kem-768'1 ML-KEM'ml-kem-1024'1 ML-KEM
If key is not a KeyObject, this function behaves as if key had been
passed to crypto.createPrivateKey().
If the callback function is provided this function uses libuv's threadpool.
crypto.diffieHellman(options[, callback])#
options<Object>privateKey<Object>|<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<KeyObject>|<URL>publicKey<Object>|<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<KeyObject>
callback<Function>- Returns:
<Buffer>if thecallbackfunction is not provided.
Computes the Diffie-Hellman shared secret based on a privateKey and a publicKey.
Both keys must represent the same asymmetric key type and must support either the DH or
ECDH operation.
If options.privateKey is not a KeyObject, this function behaves as if
options.privateKey had been passed to crypto.createPrivateKey().
If options.publicKey is not a KeyObject, this function behaves as if
options.publicKey had been passed to crypto.createPublicKey().
If the callback function is provided this function uses libuv's threadpool.
crypto.encapsulate(key[, callback])#
key<Object>|<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<KeyObject>Public Keycallback<Function>- Returns:
<Object>if thecallbackfunction is not provided.
Key encapsulation using a KEM algorithm with a public key.
Supported key types and their KEM algorithms are:
'rsa'2 RSA Secret Value Encapsulation'ec'3 DHKEM(P-256, HKDF-SHA256), DHKEM(P-384, HKDF-SHA256), DHKEM(P-521, HKDF-SHA256)'x25519'3 DHKEM(X25519, HKDF-SHA256)'x448'3 DHKEM(X448, HKDF-SHA512)'ml-kem-512'1 ML-KEM'ml-kem-768'1 ML-KEM'ml-kem-1024'1 ML-KEM
If key is not a KeyObject, this function behaves as if key had been
passed to crypto.createPublicKey().
If the callback function is provided this function uses libuv's threadpool.
crypto.fips#
Stability: 0 - Deprecated
Deprecated property for checking and controlling FIPS mode. Use
crypto.getFips() and crypto.setFips() instead.
crypto.generateKey(type, options, callback)#
type<string>The intended use of the generated secret key. Currently accepted values are'hmac'and'aes'.options<Object>length<number>The bit length of the key to generate. This must be a value greater than 0.- If
typeis'hmac', the minimum is 8, and the maximum length is 231-1. If the value is not a multiple of 8, the generated key will be truncated toMath.floor(length / 8). - If
typeis'aes', the length must be one of128,192, or256.
- If
callback<Function>err<Error>key<KeyObject>
Asynchronously generates a new random secret key of the given length. The
type will determine which validations will be performed on the length.
const { generateKey, } = await import('node:crypto'); generateKey('hmac', { length: 512 }, (err, key) => { if (err) throw err; console.log(key.export().toString('hex')); // 46e..........620 });const { generateKey, } = require('node:crypto'); generateKey('hmac', { length: 512 }, (err, key) => { if (err) throw err; console.log(key.export().toString('hex')); // 46e..........620 });
The size of a generated HMAC key should not exceed the block size of the
underlying hash function. See crypto.createHmac() for more information.
crypto.generateKeyPair(type, options, callback)#
type<string>The asymmetric key type to generate. See the supported asymmetric key types.options<Object>modulusLength<number>Key size in bits (RSA, DSA).publicExponent<number>Public exponent (RSA). Default:0x10001.hashAlgorithm<string>Name of the message digest (RSA-PSS).mgf1HashAlgorithm<string>Name of the message digest used by MGF1 (RSA-PSS).saltLength<number>Minimal salt length in bytes (RSA-PSS).divisorLength<number>Size ofqin bits (DSA).namedCurve<string>Name of the curve to use (EC).prime<Buffer>The prime parameter (DH).primeLength<number>Prime length in bits (DH).generator<number>Custom generator (DH). Default:2.groupName<string>Diffie-Hellman group name (DH). Seecrypto.getDiffieHellman().paramEncoding<string>Must be'named'or'explicit'(EC). Default:'named'.publicKeyEncoding<Object>SeekeyObject.export().privateKeyEncoding<Object>SeekeyObject.export().
callback<Function>err<Error>publicKey<string>|<Buffer>|<KeyObject>privateKey<string>|<Buffer>|<KeyObject>
Generates a new asymmetric key pair of the given type. See the
supported asymmetric key types.
For RSA-PSS keys, crypto.getHashes() lists algorithms available to the
hashing APIs, but not every listed digest can be encoded in RSA-PSS parameters
or is supported by the active RSA implementation.
If a publicKeyEncoding or privateKeyEncoding was specified, this function
behaves as if keyObject.export() had been called on its result. Otherwise,
the respective part of the key is returned as a KeyObject.
It is recommended to encode public keys as 'spki' and private keys as
'pkcs8' with encryption for long-term storage:
const { generateKeyPair, } = await import('node:crypto'); generateKeyPair('rsa', { modulusLength: 4096, publicKeyEncoding: { type: 'spki', format: 'pem', }, privateKeyEncoding: { type: 'pkcs8', format: 'pem', cipher: 'aes-256-cbc', passphrase: 'top secret', }, }, (err, publicKey, privateKey) => { // Handle errors and use the generated key pair. });const { generateKeyPair, } = require('node:crypto'); generateKeyPair('rsa', { modulusLength: 4096, publicKeyEncoding: { type: 'spki', format: 'pem', }, privateKeyEncoding: { type: 'pkcs8', format: 'pem', cipher: 'aes-256-cbc', passphrase: 'top secret', }, }, (err, publicKey, privateKey) => { // Handle errors and use the generated key pair. });
On completion, callback will be called with err set to undefined and
publicKey / privateKey representing the generated key pair.
If this method is invoked as its util.promisify()ed version, it returns
a Promise for an Object with publicKey and privateKey properties.
crypto.generateKeyPairSync(type, options)#
type<string>The asymmetric key type to generate. See the supported asymmetric key types.options<Object>modulusLength<number>Key size in bits (RSA, DSA).publicExponent<number>Public exponent (RSA). Default:0x10001.hashAlgorithm<string>Name of the message digest (RSA-PSS).mgf1HashAlgorithm<string>Name of the message digest used by MGF1 (RSA-PSS).saltLength<number>Minimal salt length in bytes (RSA-PSS).divisorLength<number>Size ofqin bits (DSA).namedCurve<string>Name of the curve to use (EC).prime<Buffer>The prime parameter (DH).primeLength<number>Prime length in bits (DH).generator<number>Custom generator (DH). Default:2.groupName<string>Diffie-Hellman group name (DH). Seecrypto.getDiffieHellman().paramEncoding<string>Must be'named'or'explicit'(EC). Default:'named'.publicKeyEncoding<Object>SeekeyObject.export().privateKeyEncoding<Object>SeekeyObject.export().
- Returns:
<Object>publicKey<string>|<Buffer>|<KeyObject>privateKey<string>|<Buffer>|<KeyObject>
Generates a new asymmetric key pair of the given type. See the
supported asymmetric key types.
For RSA-PSS keys, crypto.getHashes() lists algorithms available to the
hashing APIs, but not every listed digest can be encoded in RSA-PSS parameters
or is supported by the active RSA implementation.
If a publicKeyEncoding or privateKeyEncoding was specified, this function
behaves as if keyObject.export() had been called on its result. Otherwise,
the respective part of the key is returned as a KeyObject.
When encoding public keys, it is recommended to use 'spki'. When encoding
private keys, it is recommended to use 'pkcs8' with a strong passphrase,
and to keep the passphrase confidential.
const { generateKeyPairSync, } = await import('node:crypto'); const { publicKey, privateKey, } = generateKeyPairSync('rsa', { modulusLength: 4096, publicKeyEncoding: { type: 'spki', format: 'pem', }, privateKeyEncoding: { type: 'pkcs8', format: 'pem', cipher: 'aes-256-cbc', passphrase: 'top secret', }, });const { generateKeyPairSync, } = require('node:crypto'); const { publicKey, privateKey, } = generateKeyPairSync('rsa', { modulusLength: 4096, publicKeyEncoding: { type: 'spki', format: 'pem', }, privateKeyEncoding: { type: 'pkcs8', format: 'pem', cipher: 'aes-256-cbc', passphrase: 'top secret', }, });
The return value { publicKey, privateKey } represents the generated key pair.
When PEM encoding was selected, the respective key will be a string, otherwise
it will be a buffer containing the data encoded as DER.
crypto.generateKeySync(type, options)#
type<string>The intended use of the generated secret key. Currently accepted values are'hmac'and'aes'.options<Object>length<number>The bit length of the key to generate.- If
typeis'hmac', the minimum is 8, and the maximum length is 231-1. If the value is not a multiple of 8, the generated key will be truncated toMath.floor(length / 8). - If
typeis'aes', the length must be one of128,192, or256.
- If
- Returns:
<KeyObject>
Synchronously generates a new random secret key of the given length. The
type will determine which validations will be performed on the length.
const { generateKeySync, } = await import('node:crypto'); const key = generateKeySync('hmac', { length: 512 }); console.log(key.export().toString('hex')); // e89..........41econst { generateKeySync, } = require('node:crypto'); const key = generateKeySync('hmac', { length: 512 }); console.log(key.export().toString('hex')); // e89..........41e
The size of a generated HMAC key should not exceed the block size of the
underlying hash function. See crypto.createHmac() for more information.
crypto.generatePrime(size[, options], callback)#
size<number>The size (in bits) of the prime to generate.options<Object>add<ArrayBuffer>|<SharedArrayBuffer>|<TypedArray>|<Buffer>|<DataView>|<bigint>rem<ArrayBuffer>|<SharedArrayBuffer>|<TypedArray>|<Buffer>|<DataView>|<bigint>safe<boolean>Default:false.bigint<boolean>Whentrue, the generated prime is returned as abigint.
callback<Function>err<Error>prime<ArrayBuffer>|<bigint>
Generates a pseudorandom prime of size bits.
If options.safe is true, the prime will be a safe prime -- that is,
(prime - 1) / 2 will also be a prime.
The options.add and options.rem parameters can be used to enforce additional
requirements, e.g., for Diffie-Hellman:
- If
options.addandoptions.remare both set, the prime will satisfy the condition thatprime % add = rem. - If only
options.addis set andoptions.safeis nottrue, the prime will satisfy the condition thatprime % add = 1. - If only
options.addis set andoptions.safeis set totrue, the prime will instead satisfy the condition thatprime % add = 3. This is necessary becauseprime % add = 1foroptions.add > 2would contradict the condition enforced byoptions.safe. options.remis ignored ifoptions.addis not given.
Both options.add and options.rem must be encoded as big-endian sequences
if given as an ArrayBuffer, SharedArrayBuffer, TypedArray, Buffer, or
DataView.
By default, the prime is encoded as a big-endian sequence of octets
in an <ArrayBuffer>. If the bigint option is true, then a <bigint>
is provided.
The size of the prime will have a direct impact on how long it takes to
generate the prime. The larger the size, the longer it will take. Because
we use OpenSSL's BN_generate_prime_ex function, which provides only
minimal control over our ability to interrupt the generation process,
it is not recommended to generate overly large primes, as doing so may make
the process unresponsive.
crypto.generatePrimeSync(size[, options])#
size<number>The size (in bits) of the prime to generate.options<Object>add<ArrayBuffer>|<SharedArrayBuffer>|<TypedArray>|<Buffer>|<DataView>|<bigint>rem<ArrayBuffer>|<SharedArrayBuffer>|<TypedArray>|<Buffer>|<DataView>|<bigint>safe<boolean>Default:false.bigint<boolean>Whentrue, the generated prime is returned as abigint.
- Returns:
<ArrayBuffer>|<bigint>
Generates a pseudorandom prime of size bits.
If options.safe is true, the prime will be a safe prime -- that is,
(prime - 1) / 2 will also be a prime.
The options.add and options.rem parameters can be used to enforce additional
requirements, e.g., for Diffie-Hellman:
- If
options.addandoptions.remare both set, the prime will satisfy the condition thatprime % add = rem. - If only
options.addis set andoptions.safeis nottrue, the prime will satisfy the condition thatprime % add = 1. - If only
options.addis set andoptions.safeis set totrue, the prime will instead satisfy the condition thatprime % add = 3. This is necessary becauseprime % add = 1foroptions.add > 2would contradict the condition enforced byoptions.safe. options.remis ignored ifoptions.addis not given.
Both options.add and options.rem must be encoded as big-endian sequences
if given as an ArrayBuffer, SharedArrayBuffer, TypedArray, Buffer, or
DataView.
By default, the prime is encoded as a big-endian sequence of octets
in an <ArrayBuffer>. If the bigint option is true, then a <bigint>
is provided.
The size of the prime will have a direct impact on how long it takes to
generate the prime. The larger the size, the longer it will take. Because
we use OpenSSL's BN_generate_prime_ex function, which provides only
minimal control over our ability to interrupt the generation process,
it is not recommended to generate overly large primes, as doing so may make
the process unresponsive.
crypto.getCipherInfo(nameOrNid[, options])#
nameOrNid<string>|<number>The name or nid of the cipher to query.options<Object>- Returns:
<Object>name<string>The name of the ciphernid<number>|<undefined>The nid of the cipher. This property isundefinedif the cipher has no OpenSSL nid.blockSize<number>|<undefined>The block size of the cipher in bytes. This property isundefinedwhenmodeis'stream'.ivLength<number>|<undefined>The expected or default initialization vector length in bytes. This property isundefinedif the cipher does not use an initialization vector.keyLength<number>The expected or default key length in bytes.mode<string>The cipher mode. One of'cbc','ccm','cfb','ctr','ecb','gcm','gcm-siv','ocb','ofb','siv','stream','wrap','xts'.
Returns information about a given cipher.
Some ciphers accept variable length keys and initialization vectors. By default,
the crypto.getCipherInfo() method will return the default values for these
ciphers. To test if a given key length or iv length is acceptable for given
cipher, use the keyLength and ivLength options. If the given values are
unacceptable, undefined will be returned.
crypto.getCiphers()#
- Returns:
<string>[] An array with the names of the supported cipher algorithms.
const { getCiphers, } = await import('node:crypto'); console.log(getCiphers()); // ['aes-128-cbc', 'aes-128-ccm', ...]const { getCiphers, } = require('node:crypto'); console.log(getCiphers()); // ['aes-128-cbc', 'aes-128-ccm', ...]
crypto.getCurves()#
- Returns:
<string>[] An array with the names of the supported elliptic curves.
const { getCurves, } = await import('node:crypto'); console.log(getCurves()); // ['Oakley-EC2N-3', 'Oakley-EC2N-4', ...]const { getCurves, } = require('node:crypto'); console.log(getCurves()); // ['Oakley-EC2N-3', 'Oakley-EC2N-4', ...]
crypto.getDiffieHellman(groupName)#
groupName<string>- Returns:
<DiffieHellmanGroup>
Creates a predefined DiffieHellmanGroup key exchange object. The
supported groups are listed in the documentation for DiffieHellmanGroup.
The returned object mimics the interface of objects created by
crypto.createDiffieHellman(), but will not allow changing
the keys (with diffieHellman.setPublicKey(), for example). The
advantage of using this method is that the parties do not have to
generate nor exchange a group modulus beforehand, saving both processor
and communication time.
Example (obtaining a shared secret):
const { getDiffieHellman, } = await import('node:crypto'); const alice = getDiffieHellman('modp14'); const bob = getDiffieHellman('modp14'); alice.generateKeys(); bob.generateKeys(); const aliceSecret = alice.computeSecret(bob.getPublicKey(), null, 'hex'); const bobSecret = bob.computeSecret(alice.getPublicKey(), null, 'hex'); /* aliceSecret and bobSecret should be the same */ console.log(aliceSecret === bobSecret);const { getDiffieHellman, } = require('node:crypto'); const alice = getDiffieHellman('modp14'); const bob = getDiffieHellman('modp14'); alice.generateKeys(); bob.generateKeys(); const aliceSecret = alice.computeSecret(bob.getPublicKey(), null, 'hex'); const bobSecret = bob.computeSecret(alice.getPublicKey(), null, 'hex'); /* aliceSecret and bobSecret should be the same */ console.log(aliceSecret === bobSecret);
crypto.getFips()#
- Returns:
<number>1if FIPS mode is enabled,0otherwise. A future semver-major release may change the return type of this API to a<boolean>.
With OpenSSL 3, this reports whether the default property query includes
fips=yes. It does not establish that a FIPS provider is loaded or validated.
It can return 1 even when a requested cryptographic implementation cannot be
fetched because no loaded provider supplies a match for fips=yes. See FIPS
mode.
crypto.getHashes()#
- Returns:
<string>[] An array of the names of the supported hash algorithms, such as'RSA-SHA256'. Hash algorithms are also called "digest" algorithms.
This is the authoritative Node.js list of hash algorithms available to
crypto.createHash() and crypto.hash() in the current process. With
OpenSSL 3 or later, the list depends on the loaded providers and the default
property query in effect when the list is first generated. Some listed
algorithms can require API-specific options, such as outputLength for XOF
hash functions.
A listed hash algorithm is not necessarily supported by APIs that combine a digest with another cryptographic operation, such as HMAC, key derivation, or signing. Those operations can apply additional restrictions.
const { getHashes, } = await import('node:crypto'); console.log(getHashes()); // ['DSA', 'DSA-SHA', 'DSA-SHA1', ...]const { getHashes, } = require('node:crypto'); console.log(getHashes()); // ['DSA', 'DSA-SHA', 'DSA-SHA1', ...]
crypto.getMacs()#
Stability: 1.2 - Release candidate
- Returns:
<string>[] A fresh array containing the sorted, lowercase names and aliases of fetchable MAC implementations.
Returns MAC names exposed by loaded OpenSSL providers that match the active
default property query. Duplicate names and numeric OID aliases are omitted.
On builds without OpenSSL EVP_MAC support, this function returns an empty
array.
The returned names describe implementations that OpenSSL can fetch. They do not
guarantee that crypto.createMac() can initialize the MAC without
additional options. A provider can require additional parameters or a key with
algorithm-specific properties, and it can expose parameters that this API does
not support.
After a successful FIPS mode change made with crypto.setFips(), subsequent
calls reflect the new mode, and newly created Mac objects use it. Existing
Mac objects continue using the provider implementation selected when they
were created.
const { getMacs } = await import('node:crypto');
console.log(getMacs());
// ['blake2bmac', 'blake2smac', 'cmac', 'gmac', 'hmac', ...]
crypto.getRandomValues(typedArray)#
typedArray<Buffer>|<TypedArray>|<DataView>|<ArrayBuffer>- Returns:
<Buffer>|<TypedArray>|<DataView>|<ArrayBuffer>ReturnstypedArray.
A convenient alias for crypto.webcrypto.getRandomValues(). This
implementation is not compliant with the Web Crypto spec, to write
web-compatible code use crypto.webcrypto.getRandomValues() instead.
crypto.hash(algorithm, data[, options])#
algorithm<string>|<undefined>data<string>|<Buffer>|<TypedArray>|<DataView>Whendatais a string, it will be encoded as UTF-8 before being hashed. If a different input encoding is desired for a string input, user could encode the string into aTypedArrayusing eitherTextEncoderorBuffer.from()and passing the encodedTypedArrayinto this API instead.options<Object>|<string>customization<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>For cSHAKE hash functions, specifies the customization byte string. Default: an empty byte string.functionName<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>For cSHAKE hash functions, specifies the NIST function-name byte string. Default: an empty byte string.outputEncoding<string>Encoding used to encode the returned digest. Default:'hex'.outputLength<number>For XOF hash functions such as 'shake256', the outputLength option can be used to specify the desired output length in bytes.
- Returns:
<string>|<Buffer>
A utility for creating one-shot hash digests of data. It can be faster than
the object-based crypto.createHash() when hashing a smaller amount of data
(<= 5MB) that's readily available. If the data can be big or if it is streamed,
it's still recommended to use crypto.createHash() instead.
The available algorithms depend on the version and configuration of OpenSSL on
the platform. Examples are 'sha256' and 'sha512'. Use
crypto.getHashes() to obtain the list of hash algorithms available to the
Node.js process.
The functionName and customization options apply only to cSHAKE-128 and
cSHAKE-256. They are supported only when Node.js is built with OpenSSL 4.0 or
later and the selected provider supports the corresponding digest parameters.
Strings are encoded as UTF-8, and neither strings nor byte values may contain
NUL bytes. Both options default to an empty byte string. For OpenSSL's built-in
providers, functionName is case-sensitive and must be '', 'TupleHash',
'ParallelHash', or 'KMAC'. Other providers can impose different
restrictions. With both options empty, cSHAKE produces the same output as the
corresponding SHAKE function for the same output length. cshake-128 and
cshake-256 default to output lengths of 32 and 64 bytes, respectively.
If options is a string, then it specifies the outputEncoding.
Example:
const crypto = require('node:crypto'); const { Buffer } = require('node:buffer'); // Hashing a string and return the result as a hex-encoded string. const string = 'Node.js'; // 10b3493287f831e81a438811a1ffba01f8cec4b7 console.log(crypto.hash('sha1', string)); // Encode a base64-encoded string into a Buffer, hash it and return // the result as a buffer. const base64 = 'Tm9kZS5qcw=='; // <Buffer 10 b3 49 32 87 f8 31 e8 1a 43 88 11 a1 ff ba 01 f8 ce c4 b7> console.log(crypto.hash('sha1', Buffer.from(base64, 'base64'), 'buffer'));import crypto from 'node:crypto'; import { Buffer } from 'node:buffer'; // Hashing a string and return the result as a hex-encoded string. const string = 'Node.js'; // 10b3493287f831e81a438811a1ffba01f8cec4b7 console.log(crypto.hash('sha1', string)); // Encode a base64-encoded string into a Buffer, hash it and return // the result as a buffer. const base64 = 'Tm9kZS5qcw=='; // <Buffer 10 b3 49 32 87 f8 31 e8 1a 43 88 11 a1 ff ba 01 f8 ce c4 b7> console.log(crypto.hash('sha1', Buffer.from(base64, 'base64'), 'buffer'));
crypto.hkdf(digest, ikm, salt, info, keylen, callback)#
digest<string>The digest algorithm to use.ikm<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<KeyObject>The input keying material. Must be provided but can be zero-length.salt<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>The salt value. Must be provided but can be zero-length.info<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>Additional info value. Must be provided but can be zero-length, and cannot be more than 1024 bytes.keylen<number>The length of the key to generate. Must be greater than 0. The maximum allowable value is255times the number of bytes produced by the selected digest function (e.g.sha512generates 64-byte hashes, making the maximum HKDF output 16320 bytes).callback<Function>err<Error>derivedKey<ArrayBuffer>
HKDF is a simple key derivation function defined in RFC 5869. The given ikm,
salt and info are used with the digest to derive a key of keylen bytes.
The available digest algorithms depend on the version and configuration of
OpenSSL. HKDF uses HMAC internally. crypto.getHashes() lists algorithms
available to the hashing APIs, but not every listed algorithm is necessarily
suitable for HMAC or HKDF.
The supplied callback function is called with two arguments: err and
derivedKey. If an error occurs while deriving the key, err will be set;
otherwise err will be null. The successfully generated derivedKey will
be passed to the callback as an <ArrayBuffer>. An error will be thrown if any
of the input arguments specify invalid values or types.
import { Buffer } from 'node:buffer'; const { hkdf, } = await import('node:crypto'); hkdf('sha512', 'key', 'salt', 'info', 64, (err, derivedKey) => { if (err) throw err; console.log(Buffer.from(derivedKey).toString('hex')); // '24156e2...5391653' });const { hkdf, } = require('node:crypto'); const { Buffer } = require('node:buffer'); hkdf('sha512', 'key', 'salt', 'info', 64, (err, derivedKey) => { if (err) throw err; console.log(Buffer.from(derivedKey).toString('hex')); // '24156e2...5391653' });
crypto.hkdfSync(digest, ikm, salt, info, keylen)#
digest<string>The digest algorithm to use.ikm<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<KeyObject>The input keying material. Must be provided but can be zero-length.salt<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>The salt value. Must be provided but can be zero-length.info<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>Additional info value. Must be provided but can be zero-length, and cannot be more than 1024 bytes.keylen<number>The length of the key to generate. Must be greater than 0. The maximum allowable value is255times the number of bytes produced by the selected digest function (e.g.sha512generates 64-byte hashes, making the maximum HKDF output 16320 bytes).- Returns:
<ArrayBuffer>
Provides a synchronous HKDF key derivation function as defined in RFC 5869. The
given ikm, salt and info are used with the digest to derive a key of
keylen bytes.
The available digest algorithms depend on the version and configuration of
OpenSSL. HKDF uses HMAC internally. crypto.getHashes() lists algorithms
available to the hashing APIs, but not every listed algorithm is necessarily
suitable for HMAC or HKDF.
The successfully generated derivedKey will be returned as an <ArrayBuffer>.
An error will be thrown if any of the input arguments specify invalid values or types, or if the derived key cannot be generated.
import { Buffer } from 'node:buffer'; const { hkdfSync, } = await import('node:crypto'); const derivedKey = hkdfSync('sha512', 'key', 'salt', 'info', 64); console.log(Buffer.from(derivedKey).toString('hex')); // '24156e2...5391653'const { hkdfSync, } = require('node:crypto'); const { Buffer } = require('node:buffer'); const derivedKey = hkdfSync('sha512', 'key', 'salt', 'info', 64); console.log(Buffer.from(derivedKey).toString('hex')); // '24156e2...5391653'
crypto.parsePKCS12(bundle[, options])#
bundle<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>A DER-encoded PKCS#12 (.p12or.pfx) bundle.options<Object>passphrase<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>The passphrase protecting the bundle. Omitting this option is equivalent to passing''.
- Returns:
<Object>privateKey<KeyObject>|<null>The first private key in the bundle, ornullif none is present.certificate<X509Certificate>|<null>The certificate matchingprivateKey, ornullif no matching certificate is present.additionalCertificates<X509Certificate>[] All other certificates in the bundle. If there is no private key, this contains all certificates. May be empty.
Parses a PKCS#12 bundle, commonly stored with a .p12 or .pfx extension,
and returns its private key and certificates.
import { parsePKCS12 } from 'node:crypto';
import { readFileSync } from 'node:fs';
const { privateKey, certificate, additionalCertificates } = parsePKCS12(
readFileSync('bundle.p12'),
{ passphrase: 'secret' },
);
crypto.pbkdf2(password, salt, iterations, keylen, digest, callback)#
password<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>salt<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>iterations<number>keylen<number>digest<string>callback<Function>
Provides an asynchronous Password-Based Key Derivation Function 2 (PBKDF2)
implementation. A selected HMAC digest algorithm specified by digest is
applied to derive a key of the requested byte length (keylen) from the
password, salt and iterations.
The supplied callback function is called with two arguments: err and
derivedKey. If an error occurs while deriving the key, err will be set;
otherwise err will be null. By default, the successfully generated
derivedKey will be passed to the callback as a Buffer. An error will be
thrown if any of the input arguments specify invalid values or types.
The iterations argument must be a number set as high as possible. The
higher the number of iterations, the more secure the derived key will be,
but will take a longer amount of time to complete.
The salt should be as unique as possible. It is recommended that a salt is
random and at least 16 bytes long. See NIST SP 800-132 for details.
When passing strings for password or salt, please consider
caveats when using strings as inputs to cryptographic APIs.
const { pbkdf2, } = await import('node:crypto'); pbkdf2('secret', 'salt', 100000, 64, 'sha512', (err, derivedKey) => { if (err) throw err; console.log(derivedKey.toString('hex')); // '3745e48...08d59ae' });const { pbkdf2, } = require('node:crypto'); pbkdf2('secret', 'salt', 100000, 64, 'sha512', (err, derivedKey) => { if (err) throw err; console.log(derivedKey.toString('hex')); // '3745e48...08d59ae' });
The available digest algorithms depend on the version and configuration of
OpenSSL. PBKDF2 uses HMAC internally. crypto.getHashes() lists algorithms
available to the hashing APIs, but not every listed algorithm is necessarily
suitable for HMAC or PBKDF2.
This API uses libuv's threadpool, which can have surprising and
negative performance implications for some applications; see the
UV_THREADPOOL_SIZE documentation for more information.
crypto.pbkdf2Sync(password, salt, iterations, keylen, digest)#
password<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>salt<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>iterations<number>keylen<number>digest<string>- Returns:
<Buffer>
Provides a synchronous Password-Based Key Derivation Function 2 (PBKDF2)
implementation. A selected HMAC digest algorithm specified by digest is
applied to derive a key of the requested byte length (keylen) from the
password, salt and iterations.
If an error occurs an Error will be thrown, otherwise the derived key will be
returned as a Buffer.
The iterations argument must be a number set as high as possible. The
higher the number of iterations, the more secure the derived key will be,
but will take a longer amount of time to complete.
The salt should be as unique as possible. It is recommended that a salt is
random and at least 16 bytes long. See NIST SP 800-132 for details.
When passing strings for password or salt, please consider
caveats when using strings as inputs to cryptographic APIs.
const { pbkdf2Sync, } = await import('node:crypto'); const key = pbkdf2Sync('secret', 'salt', 100000, 64, 'sha512'); console.log(key.toString('hex')); // '3745e48...08d59ae'const { pbkdf2Sync, } = require('node:crypto'); const key = pbkdf2Sync('secret', 'salt', 100000, 64, 'sha512'); console.log(key.toString('hex')); // '3745e48...08d59ae'
The available digest algorithms depend on the version and configuration of
OpenSSL. PBKDF2 uses HMAC internally. crypto.getHashes() lists algorithms
available to the hashing APIs, but not every listed algorithm is necessarily
suitable for HMAC or PBKDF2.
crypto.privateDecrypt(privateKey, buffer)#
privateKey<Object>|<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<KeyObject>|<CryptoKey>|<URL>oaepHash<string>The hash function to use for OAEP padding and, unlessmgf1Hashis set, MGF1. Default:'sha1'mgf1Hash<string>The hash function to use for the MGF1 mask generation function of OAEP padding. If not specified, the value ofoaepHashis used. This allows the OAEP digest and the MGF1 digest to differ.oaepLabel<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>The label to use for OAEP padding. If not specified, no label is used.padding<crypto.constants>An optional padding value defined incrypto.constants, which may be:crypto.constants.RSA_NO_PADDING,crypto.constants.RSA_PKCS1_PADDING, orcrypto.constants.RSA_PKCS1_OAEP_PADDING.
buffer<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>- Returns:
<Buffer>A newBufferwith the decrypted content.
Decrypts buffer with privateKey. buffer was previously encrypted using
the corresponding public key, for example using crypto.publicEncrypt().
crypto.getHashes() lists algorithms available to the hashing APIs, but
the active RSA implementation can impose additional restrictions on digests
used for OAEP or MGF1.
If privateKey is not a KeyObject, this function behaves as if
privateKey had been passed to crypto.createPrivateKey(). If it is an
object, the padding property can be passed. Otherwise, this function uses
RSA_PKCS1_OAEP_PADDING.
Using crypto.constants.RSA_PKCS1_PADDING in crypto.privateDecrypt()
requires OpenSSL to support implicit rejection (rsa_pkcs1_implicit_rejection).
If the version of OpenSSL used by Node.js does not support this feature,
attempting to use RSA_PKCS1_PADDING will fail.
crypto.privateEncrypt(privateKey, buffer)#
privateKey<Object>|<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<KeyObject>|<CryptoKey>|<URL>key<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<KeyObject>|<CryptoKey>|<URL>The private key material, a<KeyObject>, or a<URL>referencing an object for an OpenSSL STORE loader.passphrase<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>An optional passphrase for the private key.padding<crypto.constants>An optional padding value defined incrypto.constants, which may be:crypto.constants.RSA_NO_PADDINGorcrypto.constants.RSA_PKCS1_PADDING.encoding<string>The string encoding to use whenbuffer,key, orpassphraseare strings.
buffer<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>- Returns:
<Buffer>A newBufferwith the encrypted content.
Encrypts buffer with privateKey. The returned data can be decrypted using
the corresponding public key, for example using crypto.publicDecrypt().
If privateKey is not a KeyObject, this function behaves as if
privateKey had been passed to crypto.createPrivateKey(). If it is an
object, the padding property can be passed. Otherwise, this function uses
RSA_PKCS1_PADDING.
crypto.publicDecrypt(key, buffer)#
key<Object>|<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<KeyObject>|<CryptoKey>passphrase<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>An optional passphrase for the private key.padding<crypto.constants>An optional padding value defined incrypto.constants, which may be:crypto.constants.RSA_NO_PADDINGorcrypto.constants.RSA_PKCS1_PADDING.encoding<string>The string encoding to use whenbuffer,key, orpassphraseare strings.
buffer<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>- Returns:
<Buffer>A newBufferwith the decrypted content.
Decrypts buffer with key. buffer was previously encrypted using
the corresponding private key, for example using crypto.privateEncrypt().
If key is not a KeyObject, this function behaves as if
key had been passed to crypto.createPublicKey(). If it is an
object, the padding property can be passed. Otherwise, this function uses
RSA_PKCS1_PADDING.
Because RSA public keys can be derived from private keys, a private key may be passed instead of a public key.
crypto.publicEncrypt(key, buffer)#
key<Object>|<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<KeyObject>|<CryptoKey>key<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<KeyObject>|<CryptoKey>A PEM encoded public or private key,<KeyObject>, or<CryptoKey>.oaepHash<string>The hash function to use for OAEP padding and, unlessmgf1Hashis set, MGF1. Default:'sha1'mgf1Hash<string>The hash function to use for the MGF1 mask generation function of OAEP padding. If not specified, the value ofoaepHashis used. This allows the OAEP digest and the MGF1 digest to differ.oaepLabel<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>The label to use for OAEP padding. If not specified, no label is used.passphrase<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>An optional passphrase for the private key.padding<crypto.constants>An optional padding value defined incrypto.constants, which may be:crypto.constants.RSA_NO_PADDING,crypto.constants.RSA_PKCS1_PADDING, orcrypto.constants.RSA_PKCS1_OAEP_PADDING.encoding<string>The string encoding to use whenbuffer,key,oaepLabel, orpassphraseare strings.
buffer<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>- Returns:
<Buffer>A newBufferwith the encrypted content.
Encrypts the content of buffer with key and returns a new
Buffer with encrypted content. The returned data can be decrypted using
the corresponding private key, for example using crypto.privateDecrypt().
crypto.getHashes() lists algorithms available to the hashing APIs, but
the active RSA implementation can impose additional restrictions on digests
used for OAEP or MGF1.
If key is not a KeyObject, this function behaves as if
key had been passed to crypto.createPublicKey(). If it is an
object, the padding property can be passed. Otherwise, this function uses
RSA_PKCS1_OAEP_PADDING.
Because RSA public keys can be derived from private keys, a private key may be passed instead of a public key.
crypto.randomBytes(size[, callback])#
size<number>The number of bytes to generate. Thesizemust not be larger than2**31 - 1.callback<Function>- Returns:
<Buffer>if thecallbackfunction is not provided.
Generates cryptographically strong pseudorandom data. The size argument
is a number indicating the number of bytes to generate.
If a callback function is provided, the bytes are generated asynchronously
and the callback function is invoked with two arguments: err and buf.
If an error occurs, err will be an Error object; otherwise it is null. The
buf argument is a Buffer containing the generated bytes.
// Asynchronous const { randomBytes, } = await import('node:crypto'); randomBytes(256, (err, buf) => { if (err) throw err; console.log(`${buf.length} bytes of random data: ${buf.toString('hex')}`); });// Asynchronous const { randomBytes, } = require('node:crypto'); randomBytes(256, (err, buf) => { if (err) throw err; console.log(`${buf.length} bytes of random data: ${buf.toString('hex')}`); });
If the callback function is not provided, the random bytes are generated
synchronously and returned as a Buffer. An error will be thrown if
there is a problem generating the bytes.
// Synchronous const { randomBytes, } = await import('node:crypto'); const buf = randomBytes(256); console.log( `${buf.length} bytes of random data: ${buf.toString('hex')}`);// Synchronous const { randomBytes, } = require('node:crypto'); const buf = randomBytes(256); console.log( `${buf.length} bytes of random data: ${buf.toString('hex')}`);
The crypto.randomBytes() method will not complete until there is
sufficient entropy available.
This should normally never take longer than a few milliseconds. The only time
when generating the random bytes may conceivably block for a longer period of
time is right after boot, when the whole system is still low on entropy.
This API uses libuv's threadpool, which can have surprising and
negative performance implications for some applications; see the
UV_THREADPOOL_SIZE documentation for more information.
The asynchronous version of crypto.randomBytes() is carried out in a single
threadpool request. To minimize threadpool task length variation, partition
large randomBytes requests when doing so as part of fulfilling a client
request.
crypto.randomFill(buffer[, offset][, size], callback)#
buffer<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>Must be supplied. The size of the providedbuffermust not be larger than2**31 - 1.offset<number>The start position, in elements for aTypedArrayand in bytes for anArrayBufferorDataView. Default:0size<number>The amount to fill, in the same units asoffset. Default:buffer.length - offsetfor aTypedArray, orbuffer.byteLength - offsetfor anArrayBufferorDataView. Thesizemust not be larger than2**31 - 1.callback<Function>function(err, buf) {}.
This function is similar to crypto.randomBytes() but requires the first
argument to be a Buffer that will be filled. It also
requires that a callback is passed in.
If the callback function is not provided, an error will be thrown.
import { Buffer } from 'node:buffer'; const { randomFill } = await import('node:crypto'); const buf = Buffer.alloc(10); randomFill(buf, (err, buf) => { if (err) throw err; console.log(buf.toString('hex')); }); randomFill(buf, 5, (err, buf) => { if (err) throw err; console.log(buf.toString('hex')); }); // The above is equivalent to the following: randomFill(buf, 5, 5, (err, buf) => { if (err) throw err; console.log(buf.toString('hex')); });const { randomFill } = require('node:crypto'); const { Buffer } = require('node:buffer'); const buf = Buffer.alloc(10); randomFill(buf, (err, buf) => { if (err) throw err; console.log(buf.toString('hex')); }); randomFill(buf, 5, (err, buf) => { if (err) throw err; console.log(buf.toString('hex')); }); // The above is equivalent to the following: randomFill(buf, 5, 5, (err, buf) => { if (err) throw err; console.log(buf.toString('hex')); });
Any ArrayBuffer, TypedArray, or DataView instance may be passed as
buffer.
While this includes instances of Float32Array and Float64Array, this
function should not be used to generate random floating-point numbers. The
result may contain +Infinity, -Infinity, and NaN, and even if the array
contains finite numbers only, they are not drawn from a uniform random
distribution and have no meaningful lower or upper bounds.
import { Buffer } from 'node:buffer'; const { randomFill } = await import('node:crypto'); const a = new Uint32Array(10); randomFill(a, (err, buf) => { if (err) throw err; console.log(Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength) .toString('hex')); }); const b = new DataView(new ArrayBuffer(10)); randomFill(b, (err, buf) => { if (err) throw err; console.log(Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength) .toString('hex')); }); const c = new ArrayBuffer(10); randomFill(c, (err, buf) => { if (err) throw err; console.log(Buffer.from(buf).toString('hex')); });const { randomFill } = require('node:crypto'); const { Buffer } = require('node:buffer'); const a = new Uint32Array(10); randomFill(a, (err, buf) => { if (err) throw err; console.log(Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength) .toString('hex')); }); const b = new DataView(new ArrayBuffer(10)); randomFill(b, (err, buf) => { if (err) throw err; console.log(Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength) .toString('hex')); }); const c = new ArrayBuffer(10); randomFill(c, (err, buf) => { if (err) throw err; console.log(Buffer.from(buf).toString('hex')); });
This API uses libuv's threadpool, which can have surprising and
negative performance implications for some applications; see the
UV_THREADPOOL_SIZE documentation for more information.
The asynchronous version of crypto.randomFill() is carried out in a single
threadpool request. To minimize threadpool task length variation, partition
large randomFill requests when doing so as part of fulfilling a client
request.
crypto.randomFillSync(buffer[, offset][, size])#
buffer<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>Must be supplied. The size of the providedbuffermust not be larger than2**31 - 1.offset<number>The start position, in elements for aTypedArrayand in bytes for anArrayBufferorDataView. Default:0size<number>The amount to fill, in the same units asoffset. Default:buffer.length - offsetfor aTypedArray, orbuffer.byteLength - offsetfor anArrayBufferorDataView. Thesizemust not be larger than2**31 - 1.- Returns:
<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>The object passed asbufferargument.
Synchronous version of crypto.randomFill().
import { Buffer } from 'node:buffer'; const { randomFillSync } = await import('node:crypto'); const buf = Buffer.alloc(10); console.log(randomFillSync(buf).toString('hex')); randomFillSync(buf, 5); console.log(buf.toString('hex')); // The above is equivalent to the following: randomFillSync(buf, 5, 5); console.log(buf.toString('hex'));const { randomFillSync } = require('node:crypto'); const { Buffer } = require('node:buffer'); const buf = Buffer.alloc(10); console.log(randomFillSync(buf).toString('hex')); randomFillSync(buf, 5); console.log(buf.toString('hex')); // The above is equivalent to the following: randomFillSync(buf, 5, 5); console.log(buf.toString('hex'));
Any ArrayBuffer, TypedArray or DataView instance may be passed as
buffer.
import { Buffer } from 'node:buffer'; const { randomFillSync } = await import('node:crypto'); const a = new Uint32Array(10); console.log(Buffer.from(randomFillSync(a).buffer, a.byteOffset, a.byteLength).toString('hex')); const b = new DataView(new ArrayBuffer(10)); console.log(Buffer.from(randomFillSync(b).buffer, b.byteOffset, b.byteLength).toString('hex')); const c = new ArrayBuffer(10); console.log(Buffer.from(randomFillSync(c)).toString('hex'));const { randomFillSync } = require('node:crypto'); const { Buffer } = require('node:buffer'); const a = new Uint32Array(10); console.log(Buffer.from(randomFillSync(a).buffer, a.byteOffset, a.byteLength).toString('hex')); const b = new DataView(new ArrayBuffer(10)); console.log(Buffer.from(randomFillSync(b).buffer, b.byteOffset, b.byteLength).toString('hex')); const c = new ArrayBuffer(10); console.log(Buffer.from(randomFillSync(c)).toString('hex'));
crypto.randomInt([min, ]max[, callback])#
min<integer>Start of random range (inclusive). Default:0.max<integer>End of random range (exclusive).callback<Function>function(err, n) {}.
Return a random integer n such that min <= n < max. This
implementation avoids modulo bias.
The range (max - min) must be less than 248. min and max must
be safe integers.
If the callback function is not provided, the random integer is
generated synchronously.
// Asynchronous const { randomInt, } = await import('node:crypto'); randomInt(3, (err, n) => { if (err) throw err; console.log(`Random number chosen from (0, 1, 2): ${n}`); });// Asynchronous const { randomInt, } = require('node:crypto'); randomInt(3, (err, n) => { if (err) throw err; console.log(`Random number chosen from (0, 1, 2): ${n}`); });
// Synchronous const { randomInt, } = await import('node:crypto'); const n = randomInt(3); console.log(`Random number chosen from (0, 1, 2): ${n}`);// Synchronous const { randomInt, } = require('node:crypto'); const n = randomInt(3); console.log(`Random number chosen from (0, 1, 2): ${n}`);
// With `min` argument const { randomInt, } = await import('node:crypto'); const n = randomInt(1, 7); console.log(`The dice rolled: ${n}`);// With `min` argument const { randomInt, } = require('node:crypto'); const n = randomInt(1, 7); console.log(`The dice rolled: ${n}`);
crypto.randomUUID([options])#
options<Object>disableEntropyCache<boolean>By default, to improve performance, Node.js generates and caches enough random data to generate up to 128 random UUIDs. To generate a UUID without using the cache, setdisableEntropyCachetotrue. Default:false.
- Returns:
<string>
Generates a random RFC 4122 version 4 UUID. The UUID is generated using a cryptographic pseudorandom number generator.
crypto.randomUUIDv7([options])#
options<Object>disableEntropyCache<boolean>By default, to improve performance, Node.js generates and caches enough random data to generate up to 128 random UUIDs. To generate a UUID without using the cache, setdisableEntropyCachetotrue. Default:false.
- Returns:
<string>
Generates a random RFC 9562 version 7 UUID. The UUID contains a millisecond precision Unix timestamp in the most significant 48 bits, followed by cryptographically secure random bits for the remaining fields, making it suitable for use as a database key with time-based sorting. The embedded timestamp relies on a non-monotonic clock and is not guaranteed to be strictly increasing.
crypto.scrypt(password, salt, keylen[, options], callback)#
password<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>salt<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>keylen<number>options<Object>cost<number>CPU/memory cost parameter. Must be a power of two greater than one. Default:16384.blockSize<number>Block size parameter. Default:8.parallelization<number>Parallelization parameter. Default:1.N<number>Alias forcost. Only one of both may be specified.r<number>Alias forblockSize. Only one of both may be specified.p<number>Alias forparallelization. Only one of both may be specified.maxmem<number>Memory upper bound. It is an error when (approximately)128 * N * r > maxmem. Default:32 * 1024 * 1024.
callback<Function>
Provides an asynchronous scrypt implementation. Scrypt is a password-based key derivation function that is designed to be expensive computationally and memory-wise in order to make brute-force attacks unrewarding.
The salt should be as unique as possible. It is recommended that a salt is
random and at least 16 bytes long. See NIST SP 800-132 for details.
When passing strings for password or salt, please consider
caveats when using strings as inputs to cryptographic APIs.
The callback function is called with two arguments: err and derivedKey.
err is an exception object when key derivation fails, otherwise err is
null. derivedKey is passed to the callback as a Buffer.
An exception is thrown when any of the input arguments specify invalid values or types.
const { scrypt, } = await import('node:crypto'); // Using the factory defaults. scrypt('password', 'salt', 64, (err, derivedKey) => { if (err) throw err; console.log(derivedKey.toString('hex')); // '3745e48...08d59ae' }); // Using a custom N parameter. Must be a power of two. scrypt('password', 'salt', 64, { N: 1024 }, (err, derivedKey) => { if (err) throw err; console.log(derivedKey.toString('hex')); // '3745e48...aa39b34' });const { scrypt, } = require('node:crypto'); // Using the factory defaults. scrypt('password', 'salt', 64, (err, derivedKey) => { if (err) throw err; console.log(derivedKey.toString('hex')); // '3745e48...08d59ae' }); // Using a custom N parameter. Must be a power of two. scrypt('password', 'salt', 64, { N: 1024 }, (err, derivedKey) => { if (err) throw err; console.log(derivedKey.toString('hex')); // '3745e48...aa39b34' });
crypto.scryptSync(password, salt, keylen[, options])#
password<string>|<Buffer>|<TypedArray>|<DataView>salt<string>|<Buffer>|<TypedArray>|<DataView>keylen<number>options<Object>cost<number>CPU/memory cost parameter. Must be a power of two greater than one. Default:16384.blockSize<number>Block size parameter. Default:8.parallelization<number>Parallelization parameter. Default:1.N<number>Alias forcost. Only one of both may be specified.r<number>Alias forblockSize. Only one of both may be specified.p<number>Alias forparallelization. Only one of both may be specified.maxmem<number>Memory upper bound. It is an error when (approximately)128 * N * r > maxmem. Default:32 * 1024 * 1024.
- Returns:
<Buffer>
Provides a synchronous scrypt implementation. Scrypt is a password-based key derivation function that is designed to be expensive computationally and memory-wise in order to make brute-force attacks unrewarding.
The salt should be as unique as possible. It is recommended that a salt is
random and at least 16 bytes long. See NIST SP 800-132 for details.
When passing strings for password or salt, please consider
caveats when using strings as inputs to cryptographic APIs.
An exception is thrown when key derivation fails, otherwise the derived key is
returned as a Buffer.
An exception is thrown when any of the input arguments specify invalid values or types.
const { scryptSync, } = await import('node:crypto'); // Using the factory defaults. const key1 = scryptSync('password', 'salt', 64); console.log(key1.toString('hex')); // '3745e48...08d59ae' // Using a custom N parameter. Must be a power of two. const key2 = scryptSync('password', 'salt', 64, { N: 1024 }); console.log(key2.toString('hex')); // '3745e48...aa39b34'const { scryptSync, } = require('node:crypto'); // Using the factory defaults. const key1 = scryptSync('password', 'salt', 64); console.log(key1.toString('hex')); // '3745e48...08d59ae' // Using a custom N parameter. Must be a power of two. const key2 = scryptSync('password', 'salt', 64, { N: 1024 }); console.log(key2.toString('hex')); // '3745e48...aa39b34'
crypto.secureHeapUsed()#
- Returns:
<Object>total<number>The total allocated secure heap size as specified using the--secure-heap=ncommand-line flag.min<number>The minimum allocation from the secure heap as specified using the--secure-heap-mincommand-line flag.used<number>The total number of bytes currently allocated from the secure heap.utilization<number>The calculated ratio ofusedtototalallocated bytes.
crypto.setEngine(engine[, flags])#
Stability: 0 - Deprecated
engine<string>flags<crypto.constants>Default:crypto.constants.ENGINE_METHOD_ALL
Load and set the engine for some or all OpenSSL functions (selected by flags).
Use of this API is deprecated because custom engine support has been deprecated
since OpenSSL 3.
engine could be either an id or a path to the engine's shared library.
The optional flags argument uses ENGINE_METHOD_ALL by default. The flags
is a bit field taking one of or a mix of the following flags (defined in
crypto.constants):
crypto.constants.ENGINE_METHOD_RSAcrypto.constants.ENGINE_METHOD_DSAcrypto.constants.ENGINE_METHOD_DHcrypto.constants.ENGINE_METHOD_RANDcrypto.constants.ENGINE_METHOD_ECcrypto.constants.ENGINE_METHOD_CIPHERScrypto.constants.ENGINE_METHOD_DIGESTScrypto.constants.ENGINE_METHOD_PKEY_METHScrypto.constants.ENGINE_METHOD_PKEY_ASN1_METHScrypto.constants.ENGINE_METHOD_ALLcrypto.constants.ENGINE_METHOD_NONE
crypto.setFips(bool)#
bool<boolean>trueto enable FIPS mode,falseto disable it.
Changes FIPS mode. With OpenSSL 3, this only adds or removes fips=yes in
the default property query. It does not install, load, initialize, or validate
a FIPS provider. For a usable FIPS configuration, install the provider and
configure OpenSSL to load it when Node.js starts, as described in FIPS
mode.
If no loaded provider supplies a requested cryptographic implementation
matching fips=yes, the call can still succeed and crypto.getFips() can still
return 1, but fetching that implementation fails. Affected node:crypto
operations typically fail with ERR_OSSL_EVP_UNSUPPORTED. Operations that do
not require a new fetch, including those using previously fetched
implementations or initialized operation contexts, may still succeed. Call this
method during application initialization, before application code uses other
OpenSSL-backed APIs.
This method only affects subsequent algorithm fetches. Node.js initializes some
OpenSSL state before application code runs. When the property query must be
active from process startup, set default_properties = fips=yes in the OpenSSL
configuration or use --enable-fips or --force-fips. The command-line
flags additionally require a configured provider named fips to initialize and
pass its self-test; Node.js fails to start otherwise.
Throws an error if OpenSSL cannot change the state. FIPS mode cannot be
disabled when Node.js was started with --force-fips. With OpenSSL 1.1.1,
enabling FIPS mode requires a FIPS-capable OpenSSL build.
crypto.sign(algorithm, data, key[, callback])#
algorithm<string>|<null>|<undefined>data<ArrayBuffer>|<Buffer>|<SharedArrayBuffer>|<TypedArray>|<DataView>|<string>key<Object>|<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<KeyObject>|<CryptoKey>|<URL>callback<Function>- Returns:
<Buffer>if thecallbackfunction is not provided.
Calculates and returns the signature for data using the given private key and
algorithm. If algorithm is null or undefined, then the algorithm is
dependent upon the key type.
algorithm is required to be null or undefined for Ed25519, Ed448, and
ML-DSA.
crypto.getHashes() lists algorithms available to the hashing APIs, but
the key type and signature scheme determine whether a listed digest can be
used for signing.
If key is not a KeyObject, this function behaves as if key had been
passed to crypto.createPrivateKey(). When key is a string, ArrayBuffer,
Buffer, TypedArray, or DataView, it must contain PEM-encoded key
material. If it is an object, the following additional properties can be
passed:
-
dsaEncoding<string>For DSA and ECDSA, this option specifies the format of the generated signature. It can be one of the following:'der'(default): DER-encoded ASN.1 signature structure encoding(r, s).'ieee-p1363': Signature formatr || sas proposed in IEEE-P1363.
-
padding<integer>Optional padding value for RSA, one of the following:crypto.constants.RSA_PKCS1_PADDING(default)crypto.constants.RSA_PKCS1_PSS_PADDING
RSA_PKCS1_PSS_PADDINGwill use MGF1 with the same hash function used to sign the message as specified in section 3.1 of RFC 4055. -
saltLength<integer>Salt length for when padding isRSA_PKCS1_PSS_PADDING. The special valuecrypto.constants.RSA_PSS_SALTLEN_DIGESTsets the salt length to the digest size,crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN(default) sets it to the maximum permissible value. -
context<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>For Ed255193 (using Ed25519ctx from RFC 8032), Ed448, ML-DSA, and SLH-DSA, this option specifies the optional context to differentiate signatures generated for different purposes with the same key.
If the callback function is provided this function uses libuv's threadpool.
crypto.subtle#
- Type:
<SubtleCrypto>
A convenient alias for crypto.webcrypto.subtle.
crypto.timingSafeEqual(a, b)#
a<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>b<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>- Returns:
<boolean>
This function compares the underlying bytes that represent the given
ArrayBuffer, TypedArray, or DataView instances using a constant-time
algorithm.
This function does not leak timing information that would allow an attacker to guess one of the values. This is suitable for comparing HMAC digests or secret values like authentication cookies or capability urls.
a and b must both be Buffers, TypedArrays, or DataViews, and they
must have the same byte length. An error is thrown if a and b have
different byte lengths.
If at least one of a and b is a TypedArray with more than one byte per
entry, such as Uint16Array, the result will be computed using the platform
byte order.
When both of the inputs are Float32Arrays or
Float64Arrays, this function might return unexpected results due to IEEE 754
encoding of floating-point numbers. In particular, neither x === y nor
Object.is(x, y) implies that the byte representations of two floating-point
numbers x and y are equal.
Use of crypto.timingSafeEqual does not guarantee that the surrounding code
is timing-safe. Care should be taken to ensure that the surrounding code does
not introduce timing vulnerabilities.
crypto.verify(algorithm, data, key, signature[, callback])#
algorithm<string>|<null>|<undefined>data<ArrayBuffer>|<Buffer>|<SharedArrayBuffer>|<TypedArray>|<DataView>|<string>key<Object>|<string>|<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>|<KeyObject>|<CryptoKey>signature<ArrayBuffer>|<Buffer>|<SharedArrayBuffer>|<TypedArray>|<DataView>callback<Function>- Returns:
<boolean>trueorfalsedepending on the validity of the signature for the data and public key if thecallbackfunction is not provided.
Verifies the given signature for data using the given key and algorithm. If
algorithm is null or undefined, then the algorithm is dependent upon the
key type.
algorithm is required to be null or undefined for Ed25519, Ed448, and
ML-DSA.
crypto.getHashes() lists algorithms available to the hashing APIs, but
the key type and signature scheme determine whether a listed digest can be
used for verification.
If key is not a KeyObject, this function behaves as if key had been
passed to crypto.createPublicKey(). When key is a string, ArrayBuffer,
Buffer, TypedArray, or DataView, it must contain PEM-encoded key
material. If it is an object, the following additional properties can be
passed:
-
dsaEncoding<string>For DSA and ECDSA, this option specifies the format of the signature. It can be one of the following:'der'(default): DER-encoded ASN.1 signature structure encoding(r, s).'ieee-p1363': Signature formatr || sas proposed in IEEE-P1363.
-
padding<integer>Optional padding value for RSA, one of the following:crypto.constants.RSA_PKCS1_PADDING(default)crypto.constants.RSA_PKCS1_PSS_PADDING
RSA_PKCS1_PSS_PADDINGwill use MGF1 with the same hash function used to sign the message as specified in section 3.1 of RFC 4055. -
saltLength<integer>Salt length for when padding isRSA_PKCS1_PSS_PADDING. The special valuecrypto.constants.RSA_PSS_SALTLEN_DIGESTsets the salt length to the digest size,crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN(default) sets it to the maximum permissible value. -
context<ArrayBuffer>|<Buffer>|<TypedArray>|<DataView>For Ed255193 (using Ed25519ctx from RFC 8032), Ed448, ML-DSA, and SLH-DSA, this option specifies the optional context to differentiate signatures generated for different purposes with the same key.
The signature argument is the previously calculated signature for the data.
Because public keys can be derived from private keys, a private key or a public
key may be passed for key.
If the callback function is provided this function uses libuv's threadpool.
crypto.webcrypto#
Type: <Crypto> An implementation of the Web Crypto API standard.
See the Web Crypto API documentation for details.
Notes#
Using strings as inputs to cryptographic APIs#
For historical reasons, many cryptographic APIs provided by Node.js accept strings as inputs where the underlying cryptographic algorithm works on byte sequences. These instances include plaintexts, ciphertexts, symmetric keys, initialization vectors, passphrases, salts, authentication tags, and additional authenticated data.
When passing strings to cryptographic APIs, consider the following factors.
-
Not all byte sequences are valid UTF-8 strings. Therefore, when a byte sequence of length
nis derived from a string, its entropy is generally lower than the entropy of a random or pseudorandomnbyte sequence. For example, no UTF-8 string will result in the byte sequencec0 af. Secret keys should almost exclusively be random or pseudorandom byte sequences. -
Similarly, when converting random or pseudorandom byte sequences to UTF-8 strings, subsequences that do not represent valid code points may be replaced by the Unicode replacement character (
U+FFFD). The byte representation of the resulting Unicode string may, therefore, not be equal to the byte sequence that the string was created from.const original = [0xc0, 0xaf]; const bytesAsString = Buffer.from(original).toString('utf8'); const stringAsBytes = Buffer.from(bytesAsString, 'utf8'); console.log(stringAsBytes); // Prints '<Buffer ef bf bd ef bf bd>'.The outputs of ciphers, hash functions, signature algorithms, and key derivation functions are pseudorandom byte sequences and should not be used as Unicode strings.
-
When strings are obtained from user input, some Unicode characters can be represented in multiple equivalent ways that result in different byte sequences. For example, when passing a user passphrase to a key derivation function, such as PBKDF2 or scrypt, the result of the key derivation function depends on whether the string uses composed or decomposed characters. Node.js does not normalize character representations. Developers should consider using
String.prototype.normalize()on user inputs before passing them to cryptographic APIs.
Legacy streams API (prior to Node.js 0.10)#
The Crypto module was added to Node.js before there was the concept of a
unified Stream API, and before there were Buffer objects for handling
binary data. As such, many crypto classes have methods not
typically found on other Node.js classes that implement the streams
API (e.g. update(), final(), or digest()). Also, many methods accepted
and returned 'latin1' encoded strings by default rather than Buffers. This
default was changed in Node.js 0.9.3 to use Buffer objects by default
instead.
Support for weak or compromised algorithms#
The node:crypto module still supports some algorithms which are already
compromised and are not recommended for use. The API also allows
the use of ciphers and hashes with a small key size that are too weak for safe
use.
Users should take full responsibility for selecting the crypto algorithm and key size according to their security requirements.
Based on the recommendations of NIST SP 800-131A:
- MD5 and SHA-1 are no longer acceptable where collision resistance is required such as digital signatures.
- The key used with RSA, DSA, and DH algorithms is recommended to have at least 2048 bits and that of the curve of ECDSA and ECDH at least 224 bits, to be safe to use for several years.
- The DH groups of
modp1,modp2andmodp5have a key size smaller than 2048 bits and are not recommended.
See the reference for other recommendations and details.
Some algorithms that have known weaknesses and are of little relevance in practice are only available through the legacy provider, which is not enabled by default.
CCM mode#
CCM is one of the supported AEAD algorithms. Applications which use this mode must adhere to certain restrictions when using the cipher API:
- The authentication tag length must be specified during cipher creation by
setting the
authTagLengthoption and must be one of 4, 6, 8, 10, 12, 14 or 16 bytes. - The length of the initialization vector (nonce)
Nmust be between 7 and 13 bytes (7 ≤ N ≤ 13). - The length of the plaintext is limited to
2 ** (8 * (15 - N))bytes. - When decrypting, the authentication tag must be set via
setAuthTag()before callingupdate(). Otherwise, decryption will fail andfinal()will throw an error in compliance with section 2.6 of RFC 3610. - Using stream methods such as
write(data),end(data)orpipe()in CCM mode might fail as CCM cannot handle more than one chunk of data per instance. - When passing additional authenticated data (AAD), the length of the actual
message in bytes must be passed to
setAAD()via theplaintextLengthoption. Many crypto libraries include the authentication tag in the ciphertext, which means that they produce ciphertexts of the lengthplaintextLength + authTagLength. Node.js does not include the authentication tag, so the ciphertext length is alwaysplaintextLength. This is not necessary if no AAD is used. - As CCM processes the whole message at once,
update()must be called exactly once. - Even though calling
update()is sufficient to encrypt/decrypt the message, applications must callfinal()to compute or verify the authentication tag.
import { Buffer } from 'node:buffer'; const { createCipheriv, createDecipheriv, randomBytes, } = await import('node:crypto'); const key = 'keykeykeykeykeykeykeykey'; const nonce = randomBytes(12); const aad = Buffer.from('0123456789', 'hex'); const cipher = createCipheriv('aes-192-ccm', key, nonce, { authTagLength: 16, }); const plaintext = 'Hello world'; cipher.setAAD(aad, { plaintextLength: Buffer.byteLength(plaintext), }); const ciphertext = cipher.update(plaintext, 'utf8'); cipher.final(); const tag = cipher.getAuthTag(); // Now transmit { ciphertext, nonce, tag }. const decipher = createDecipheriv('aes-192-ccm', key, nonce, { authTagLength: 16, }); decipher.setAuthTag(tag); decipher.setAAD(aad, { plaintextLength: ciphertext.length, }); const receivedPlaintext = decipher.update(ciphertext, null, 'utf8'); try { decipher.final(); } catch (err) { throw new Error('Authentication failed!', { cause: err }); } console.log(receivedPlaintext);const { Buffer } = require('node:buffer'); const { createCipheriv, createDecipheriv, randomBytes, } = require('node:crypto'); const key = 'keykeykeykeykeykeykeykey'; const nonce = randomBytes(12); const aad = Buffer.from('0123456789', 'hex'); const cipher = createCipheriv('aes-192-ccm', key, nonce, { authTagLength: 16, }); const plaintext = 'Hello world'; cipher.setAAD(aad, { plaintextLength: Buffer.byteLength(plaintext), }); const ciphertext = cipher.update(plaintext, 'utf8'); cipher.final(); const tag = cipher.getAuthTag(); // Now transmit { ciphertext, nonce, tag }. const decipher = createDecipheriv('aes-192-ccm', key, nonce, { authTagLength: 16, }); decipher.setAuthTag(tag); decipher.setAAD(aad, { plaintextLength: ciphertext.length, }); const receivedPlaintext = decipher.update(ciphertext, null, 'utf8'); try { decipher.final(); } catch (err) { throw new Error('Authentication failed!', { cause: err }); } console.log(receivedPlaintext);
CBC-CTS mode#
For CBC ciphertext stealing (CBC-CTS) ciphers, the ctsMode option to
crypto.createCipheriv() or crypto.createDecipheriv() selects the
variant:
'CS1'is the default. For block-aligned input, its output is the same as CBC mode.'CS2'is also the same as CBC for block-aligned input. For input with a partial final block, it swaps the final full and partial ciphertext blocks relative to CS1.'CS3'is the Kerberos 5 variant. It uses the CS2 ordering for a partial final block and swaps the final two ciphertext blocks even for block-aligned input.
Encryption and decryption must use the same variant. The option is available only with CBC-CTS provider ciphers on OpenSSL 3.0 or later.
Applications which use this mode must adhere to these restrictions:
- The plaintext or ciphertext must be at least one block long.
- The ciphertext has the same length as the plaintext.
cipher.update()ordecipher.update()must be called exactly once with all input data. Stream methods such aswrite(data),end(data), orpipe()may fail because CBC-CTS does not accept multiple data updates.cipher.final()ordecipher.final()must still be called to complete the operation.crypto.getCipherInfo()reports the base mode as'cbc'.
XTS mode#
XTS ciphers operate on independently tweakable data units. A Cipheriv or
Decipheriv instance represents one complete data unit, and its iv argument
provides the 16-byte tweak. Use a new instance with the appropriate positional
tweak for each different logical data unit.
Applications which use XTS mode must adhere to these restrictions:
- The plaintext or ciphertext must be at least one 16-byte block. Its length does not have to be a multiple of 16 bytes because XTS uses ciphertext stealing for a final partial block.
- The ciphertext has the same length as the plaintext.
cipher.update()ordecipher.update()must be called exactly once with all input data. Stream methods such aswrite(data),end(data), orpipe()may fail because XTS does not accept multiple data updates.cipher.final()ordecipher.final()must still be called to complete the operation.
For sm4-xts, the xtsStandard option to crypto.createCipheriv() or
crypto.createDecipheriv() selects either the default 'GB' variant from
GB/T 17964-2021 or the 'IEEE' variant from IEEE Std 1619-2007. Encryption and
decryption must use the same variant. The option is available only for
sm4-xts; it does not apply to AES-XTS ciphers. OpenSSL's default provider
supports sm4-xts in OpenSSL 3.2 or later.
AES key wrap modes#
AES key wrap (AES-WRAP) and AES key wrap with padding (AES-WRAP-PAD)
ciphers operate on a complete key-data value rather than on an incremental byte
stream. The inverse-transform variants have the same processing restrictions.
Applications which use an AES key wrap cipher must adhere to these restrictions:
cipher.update()ordecipher.update()must be called exactly once with the complete, non-empty input value.- Do not use AES key wrap ciphers as generic
stream.Transformstreams. Methods such aswrite(data),end(data), andpipe()can split one value across multiple updates, with each update being treated as a separate wrap or unwrap operation. cipher.final()ordecipher.final()must still be called to complete the operation.
SIV and GCM-SIV modes#
SIV2 and GCM-SIV3 are supported AEAD algorithms
when supported by OpenSSL. Applications which use these modes must adhere to
certain restrictions when using the cipher API:
- The authentication tag length is fixed at 16 bytes.
AES-SIVkeys are twice the named AES key size:aes-128-sivrequires a 32-byte key,aes-192-sivrequires a 48-byte key, andaes-256-sivrequires a 64-byte key.AES-SIVciphers do not use an initialization vector. Passnullor a zero-lengthivtocrypto.createCipheriv()orcrypto.createDecipheriv().AES-SIVandAES-GCM-SIVsupport zero-length plaintext only with OpenSSL 3.5 or later.AES-SIVdoes not have a separate nonce or IV parameter. RFC 5297 definesAES-SIVover an ordered list of associated-data inputs. EachsetAAD()call supplies one input in that list. If a protocol uses a nonce withAES-SIV, callsetAAD(nonce)after the other associated-data inputs and beforeupdate(). At most 126 associated-data inputs may be supplied.AES-GCM-SIVciphers require a 12-byte initialization vector.- When decrypting, the authentication tag must be set via
setAuthTag()before callingupdate(). - Using stream methods such as
write(data),end(data)orpipe()might fail as these modes cannot handle more than one chunk of data per instance. - As these modes process the whole message at once,
update()must be called exactly once. - Even though calling
update()is sufficient to encrypt/decrypt the message, applications must callfinal()to compute or verify the authentication tag.
FIPS mode#
Node.js exposes the FIPS support provided by the linked OpenSSL library. Node.js is not itself FIPS validated. Validation belongs to a specific OpenSSL module or provider and only applies when it is deployed according to its security policy. Vendor-provided Node.js or OpenSSL builds can require a different configuration; follow the vendor's documentation for those builds.
With OpenSSL 1.1.1, Node.js must be built against a FIPS-capable OpenSSL library.
With OpenSSL 3, FIPS support uses the provider model described in the OpenSSL FIPS module guide. Using FIPS-approved implementations requires:
- A correctly installed OpenSSL 3 FIPS provider.
- An OpenSSL 3 FIPS module configuration file.
- The FIPS provider to be loaded into the OpenSSL library context used by Node.js, normally by activating it in an OpenSSL configuration file when Node.js starts.
- The default property query to include
fips=yeswhen cryptographic implementations are fetched. This can be set from process startup by the OpenSSL configuration,--enable-fips, or--force-fips, or for subsequent fetches bycrypto.setFips(true).
An example OpenSSL 3 configuration file looks like this:
nodejs_conf = nodejs_init
config_diagnostics = 1
.include /<absolute path>/fipsmodule.cnf
[nodejs_init]
providers = provider_sect
alg_section = algorithm_sect
[provider_sect]
# The fips section name should match the section name inside the
# included fipsmodule.cnf.
fips = fips_sect
base = base_sect
[base_sect]
activate = 1
[algorithm_sect]
default_properties = fips=yes
The fipsmodule.cnf file is generated as part of the FIPS provider installation
and contains module integrity and self-test information. The exact command and
arguments are installation-specific; see OpenSSL FIPS configuration and the
OpenSSL FIPS module guide. The installation uses openssl fipsinstall.
The example activates the provider and enables the fips=yes property query
when Node.js starts. To activate the provider at startup but enable the property
query later with crypto.setFips(true), omit alg_section = algorithm_sect and
the [algorithm_sect] block. The provider must still be loaded; when using this
startup configuration, keep its activation enabled. crypto.setFips(true)
should be called before application code uses other OpenSSL-backed APIs. It is
not equivalent to enabling the property query from process startup because
Node.js initializes some OpenSSL state before application code runs. Use the
example as written, --enable-fips, or --force-fips when the property
query must be active from process startup.
config_diagnostics causes configuration errors to prevent startup instead of
being ignored. The base provider supplies non-cryptographic supporting
algorithms, such as encoders and decoders, that are commonly needed alongside
the FIPS provider. default_properties = fips=yes restricts OpenSSL's default
algorithm selection to implementations that match fips=yes.
Set OPENSSL_CONF to the OpenSSL configuration file. For a dynamically loaded
provider, OPENSSL_MODULES can set the directory containing the provider module.
For example:
export OPENSSL_CONF=/<path to configuration file>/nodejs.cnf
export OPENSSL_MODULES=/<path to openssl lib>/ossl-modules
The --openssl-config command-line option selects the configuration file and
takes precedence over OPENSSL_CONF. If neither is set, OpenSSL's default
configuration file is used.
By default, Node.js reads the nodejs_conf section instead of OpenSSL's usual
openssl_conf section. Use --openssl-shared-config to read openssl_conf,
or build Node.js with ./configure --openssl-conf-name=<name> to change the
default section name.
On OpenSSL 3, the configuration above enables the fips=yes property query at
startup. The following controls are also available:
--enable-fipsand--force-fipsenable the property query and additionally require the configured provider namedfipsto initialize and pass its self-test. Node.js exits if that check fails.--force-fipsalso prevents FIPS mode from being disabled from script code. With--force-fips=strict, Node.js also rejects non-approved operations reported through the OpenSSL FIPS indicator callback.crypto.setFips()changes the FIPS/property-query state. On OpenSSL 3, it does not install, load, initialize, or validate a provider. Implementations fetched before the call are not changed.crypto.getFips()reports the FIPS/property-query state. On OpenSSL 3, a return value of1does not prove that a FIPS provider is loaded or validated.- With
--enable-fips-indicator-events, the'crypto.fips.indicator'diagnostics channel reports non-approved operations permitted by an OpenSSL 3.4 or later FIPS provider configured for backwards compatibility.
With OpenSSL 1.1.1, these controls use the library's FIPS mode support and require a FIPS-capable OpenSSL build.
Only algorithms available under the active FIPS settings can be used. With
OpenSSL 3, if no loaded provider supplies a requested cryptographic
implementation matching fips=yes, fetching it fails, typically with
ERR_OSSL_EVP_UNSUPPORTED. The same error can occur for algorithms that
Node.js supports when FIPS mode is disabled but that are unavailable under the
active FIPS settings.
OpenSSL documents that the same FIPS provider cannot be used by multiple copies
of libcrypto in one process. This can affect native addons that load another
copy of libcrypto; OpenSSL's documented workaround is to use a separate copy
of the provider for each libcrypto instance. See OpenSSL FIPS provider
limitations.
Crypto constants#
The following constants exported by crypto.constants apply to various uses of
the node:crypto, node:tls, and node:https modules and are generally
specific to OpenSSL.
OpenSSL options#
See the list of SSL OP Flags for details.
| Constant | Description |
|---|---|
SSL_OP_ALL |
Applies multiple bug workarounds within OpenSSL. See https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set_options.html for detail. |
SSL_OP_ALLOW_NO_DHE_KEX |
Instructs OpenSSL to allow a non-[EC]DHE-based key exchange mode for TLS v1.3 |
SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION |
Allows legacy insecure renegotiation between OpenSSL and unpatched clients or servers. See https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set_options.html. |
SSL_OP_CIPHER_SERVER_PREFERENCE |
Attempts to use the server's preferences instead of the client's when selecting a cipher. Behavior depends on protocol version. See https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set_options.html. |
SSL_OP_CISCO_ANYCONNECT |
Instructs OpenSSL to use Cisco's version identifier of DTLS_BAD_VER. |
SSL_OP_COOKIE_EXCHANGE |
Instructs OpenSSL to turn on cookie exchange. |
SSL_OP_CRYPTOPRO_TLSEXT_BUG |
Instructs OpenSSL to add server-hello extension from an early version of the cryptopro draft. |
SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS |
Instructs OpenSSL to disable an SSL 3.0/TLS 1.0 vulnerability workaround added in OpenSSL 0.9.6d. |
SSL_OP_LEGACY_SERVER_CONNECT |
Allows initial connection to servers that do not support RI. |
SSL_OP_NO_COMPRESSION |
Instructs OpenSSL to disable support for SSL/TLS compression. |
SSL_OP_NO_ENCRYPT_THEN_MAC |
Instructs OpenSSL to disable encrypt-then-MAC. |
SSL_OP_NO_QUERY_MTU |
|
SSL_OP_NO_RENEGOTIATION |
Instructs OpenSSL to disable renegotiation. |
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
Instructs OpenSSL to always start a new session when performing renegotiation. |
SSL_OP_NO_SSLv2 |
Instructs OpenSSL to turn off SSL v2 |
SSL_OP_NO_SSLv3 |
Instructs OpenSSL to turn off SSL v3 |
SSL_OP_NO_TICKET |
Instructs OpenSSL to disable use of RFC4507bis tickets. |
SSL_OP_NO_TLSv1 |
Instructs OpenSSL to turn off TLS v1 |
SSL_OP_NO_TLSv1_1 |
Instructs OpenSSL to turn off TLS v1.1 |
SSL_OP_NO_TLSv1_2 |
Instructs OpenSSL to turn off TLS v1.2 |
SSL_OP_NO_TLSv1_3 |
Instructs OpenSSL to turn off TLS v1.3 |
SSL_OP_PRIORITIZE_CHACHA |
Instructs OpenSSL server to prioritize ChaCha20-Poly1305
when the client does.
This option has no effect if
SSL_OP_CIPHER_SERVER_PREFERENCE
is not enabled. |
SSL_OP_TLS_ROLLBACK_BUG |
Instructs OpenSSL to disable version rollback attack detection. |
OpenSSL engine constants#
| Constant | Description |
|---|---|
ENGINE_METHOD_RSA |
Limit engine usage to RSA |
ENGINE_METHOD_DSA |
Limit engine usage to DSA |
ENGINE_METHOD_DH |
Limit engine usage to DH |
ENGINE_METHOD_RAND |
Limit engine usage to RAND |
ENGINE_METHOD_EC |
Limit engine usage to EC |
ENGINE_METHOD_CIPHERS |
Limit engine usage to CIPHERS |
ENGINE_METHOD_DIGESTS |
Limit engine usage to DIGESTS |
ENGINE_METHOD_PKEY_METHS |
Limit engine usage to PKEY_METHS |
ENGINE_METHOD_PKEY_ASN1_METHS |
Limit engine usage to PKEY_ASN1_METHS |
ENGINE_METHOD_ALL |
|
ENGINE_METHOD_NONE |
Other OpenSSL constants#
| Constant | Description |
|---|---|
DH_CHECK_P_NOT_SAFE_PRIME |
|
DH_CHECK_P_NOT_PRIME |
|
DH_UNABLE_TO_CHECK_GENERATOR |
|
DH_NOT_SUITABLE_GENERATOR |
|
RSA_PKCS1_PADDING |
|
RSA_SSLV23_PADDING |
|
RSA_NO_PADDING |
|
RSA_PKCS1_OAEP_PADDING |
|
RSA_X931_PADDING |
|
RSA_PKCS1_PSS_PADDING |
|
RSA_PSS_SALTLEN_DIGEST |
Sets the salt length for RSA_PKCS1_PSS_PADDING to the
digest size when signing or verifying. |
RSA_PSS_SALTLEN_MAX_SIGN |
Sets the salt length for RSA_PKCS1_PSS_PADDING to the
maximum permissible value when signing data. |
RSA_PSS_SALTLEN_AUTO |
Causes the salt length for RSA_PKCS1_PSS_PADDING to be
determined automatically when verifying a signature. |
POINT_CONVERSION_COMPRESSED |
|
POINT_CONVERSION_UNCOMPRESSED |
|
POINT_CONVERSION_HYBRID |
Node.js crypto constants#
| Constant | Description |
|---|---|
defaultCoreCipherList |
Specifies the built-in default cipher list used by Node.js. |
defaultCipherList |
Specifies the active default cipher list used by the current Node.js process. |
Footnotes
Debugger#
Stability: 2 - Stable
Node.js includes a command-line debugging utility. The Node.js debugger client is not a full-featured debugger, but simple stepping and inspection are possible.
The debugger supports two modes of operation: interactive mode and non-interactive probe mode.
Interactive mode#
$ node inspect [--port=<port>] [<node-option> ...] [<script> [<script-args>] | <host>:<port> | -p <pid>]
To use it, start Node.js with the inspect argument followed by the path to the
script to debug.
$ node inspect myscript.js
< Debugger listening on ws://127.0.0.1:9229/621111f9-ffcb-4e82-b718-48a145fa5db8
< For help, see: https://nodejs.org/learn/getting-started/debugging
<
connecting to 127.0.0.1:9229 ... ok
< Debugger attached.
<
ok
Break on start in myscript.js:2
1 // myscript.js
> 2 global.x = 5;
3 setTimeout(() => {
4 debugger;
debug>
The debugger automatically breaks on the first executable line. To instead
run until the first breakpoint (specified by a debugger statement), set
the NODE_INSPECT_RESUME_ON_START environment variable to 1.
$ cat myscript.js
// myscript.js
global.x = 5;
setTimeout(() => {
debugger;
console.log('world');
}, 1000);
console.log('hello');
$ NODE_INSPECT_RESUME_ON_START=1 node inspect myscript.js
< Debugger listening on ws://127.0.0.1:9229/f1ed133e-7876-495b-83ae-c32c6fc319c2
< For help, see: https://nodejs.org/learn/getting-started/debugging
<
connecting to 127.0.0.1:9229 ... ok
< Debugger attached.
<
< hello
<
break in myscript.js:4
2 global.x = 5;
3 setTimeout(() => {
> 4 debugger;
5 console.log('world');
6 }, 1000);
debug> next
break in myscript.js:5
3 setTimeout(() => {
4 debugger;
> 5 console.log('world');
6 }, 1000);
7 console.log('hello');
debug> repl
Press Ctrl+C to leave debug repl
> x
5
> 2 + 2
4
debug> next
< world
<
break in myscript.js:6
4 debugger;
5 console.log('world');
> 6 }, 1000);
7 console.log('hello');
8
debug> .exit
$
The repl command allows code to be evaluated remotely. The next command
steps to the next line. Type help to see what other commands are available.
Pressing enter without typing a command will repeat the previous debugger
command.
Watchers#
It is possible to watch expression and variable values while debugging. On every breakpoint, each expression from the watchers list will be evaluated in the current context and displayed immediately before the breakpoint's source code listing.
To begin watching an expression, type watch('my_expression'). The command
watchers will print the active watchers. To remove a watcher, type
unwatch('my_expression').
Command reference#
Stepping#
cont,c: Continue executionnext,n: Step nextstep,s: Step inout,o: Step outpause: Pause running code (like pause button in Developer Tools)
Breakpoints#
setBreakpoint(),sb(): Set breakpoint on current linesetBreakpoint(line),sb(line): Set breakpoint on specific linesetBreakpoint('fn()'),sb(...): Set breakpoint on a first statement in function's bodysetBreakpoint('script.js', 1),sb(...): Set breakpoint on first line ofscript.jssetBreakpoint('script.js', 1, 'num < 4'),sb(...): Set conditional breakpoint on first line ofscript.jsthat only breaks whennum < 4evaluates totrueclearBreakpoint('script.js', 1),cb(...): Clear breakpoint inscript.json line 1
It is also possible to set a breakpoint in a file (module) that is not loaded yet:
$ node inspect main.js
< Debugger listening on ws://127.0.0.1:9229/48a5b28a-550c-471b-b5e1-d13dd7165df9
< For help, see: https://nodejs.org/learn/getting-started/debugging
<
connecting to 127.0.0.1:9229 ... ok
< Debugger attached.
<
Break on start in main.js:1
> 1 const mod = require('./mod.js');
2 mod.hello();
3 mod.hello();
debug> setBreakpoint('mod.js', 22)
Warning: script 'mod.js' was not loaded yet.
debug> c
break in mod.js:22
20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
21
>22 exports.hello = function() {
23 return 'hello from module';
24 };
debug>
It is also possible to set a conditional breakpoint that only breaks when a
given expression evaluates to true:
$ node inspect main.js
< Debugger listening on ws://127.0.0.1:9229/ce24daa8-3816-44d4-b8ab-8273c8a66d35
< For help, see: https://nodejs.org/learn/getting-started/debugging
<
connecting to 127.0.0.1:9229 ... ok
< Debugger attached.
Break on start in main.js:7
5 }
6
> 7 addOne(10);
8 addOne(-1);
9
debug> setBreakpoint('main.js', 4, 'num < 0')
1 'use strict';
2
3 function addOne(num) {
> 4 return num + 1;
5 }
6
7 addOne(10);
8 addOne(-1);
9
debug> cont
break in main.js:4
2
3 function addOne(num) {
> 4 return num + 1;
5 }
6
debug> exec('num')
-1
debug>
Information#
backtrace,bt: Print backtrace of current execution framelist(5): List scripts source code with 5 line context (5 lines before and after)watch(expr): Add expression to watch listunwatch(expr): Remove expression from watch listunwatch(index): Remove expression at specific index from watch listwatchers: List all watchers and their values (automatically listed on each breakpoint)repl: Open debugger's repl for evaluation in debugging script's contextexec expr,p expr: Execute an expression in debugging script's context and print its valueprofile: Start CPU profiling sessionprofileEnd: Stop current CPU profiling sessionprofiles: List all completed CPU profiling sessionsprofiles[n].save(filepath = 'node.cpuprofile'): Save CPU profiling session to disk as JSONtakeHeapSnapshot(filepath = 'node.heapsnapshot'): Take a heap snapshot and save to disk as JSON
Execution control#
run: Run script (automatically runs on debugger's start)restart: Restart scriptkill: Kill script
Various#
scripts: List all loaded scriptsversion: Display V8's version
Probe mode#
Stability: 1 - Experimental
node inspect supports a non-interactive probe mode for inspecting runtime values
in an application via the flag --probe.
Currently, probe mode only supports launching a new process from the entry point script specified on the command line.
The probe mode sets one or more source breakpoints, evaluates specified expressions whenever the execution reaches a breakpoint, and prints one final report of all the evaluated expressions when the session ends (either on normal completion, error, or timeout). This allows developers to perform printf-style debugging without having to modify the application code and clean up afterwards. It also supports structured JSON output for tool use.
$ node inspect --probe <file>:<line>[:<col>] --expr <expr> [--cond <expr>] [--max-hit <n>]
[--probe <file>:<line>[:<col>] --expr <expr> [--cond <expr>] [--max-hit <n>] ...]
[--json] [--preview] [--timeout=<ms>] [--port=<port>]
[--] [<node-option> ...] <script> [<script-args> ...]
--probe <file>:<line>[:<col>]: Source location of the probe. When execution reaches the location, the provided expressions are evaluated and printed in the output.<file>matches the URL suffix of the script to probe.<line>and<col>numbers are 1-based. When<col>is omitted, the probe binds to the first executable column on the line.--expr <expr>: JavaScript expression to evaluate whenever execution reaches the location specified by the preceding--probe. Must immediately follow the--probeit belongs to.--cond <expr>: An optional condition for the probe location. The probe only records a hit when<expr>is truthy at the location. A condition that throws is treated as false.--max-hit <n>: An optional per-probe limit on the number of times the probe can be hit. When not specified, there's no hit limit. When any probe reaches its hit limit, the probing process will detach and report the results. The process being probed will continue to run. If any other probe is never reached by the time the session ends, it will be reported as a missed probe.--timeout=<ms>: A global wall-clock deadline for the entire probe session. The default is30000. This can be used to probe a long-running application that can be terminated externally.--json: If used, prints a structured JSON report instead of the default text report.--preview: If used, non-primitive values will include CDP property previews for object-like JSON probe values.--port=<port>: Selects the local inspector port where the probing session will listen. Defaults to0, which requests a random port.--is optional unless the child needs its own Node.js flags.
Additional rules about the composition of the options:
--probe <file>:<line>[:<col>]and--expr <expr>are strict pairs. Each--probemust be followed immediately by exactly one--expr.--cond <expr>and--max-hit <n>are optional modifiers written after the--probe/--exprpair they apply to, each at most once per pair. They may not appear before the first--probeor between a--probeand its matching--expr.--max-hitscopes to the--probe/--exprpair it follows, so pairs sharing a location may set different limits.--condscopes to the whole location, probes sharing a location must share one condition (or none).--timeout,--json,--preview, and--portare global probe options for the whole probe session. They may appear before or between probe pairs, but not between a--probeand its matching--expr.- If additional Node.js execution arguments need to be passed to the child
script,
--must be used to separate the probe options from the Node.js options for the child script.
Example:
$ node inspect --probe app.js:10 --expr "user"
--probe src/utils.js:5:15 --expr "config.options"
--json --preview -- --no-warnings app.js --arg-for-app=foo
Probe output format#
When the probe session ends, the probing process prints a final report of all the probe hits and results.
Consider this script:
// cli.js
let maxRSS = 0;
for (let i = 0; i < 2; i++) {
const { rss } = process.memoryUsage();
maxRSS = Math.max(maxRSS, rss);
}
Without --json, by default the output is printed in a human-readable text format:
$ node inspect --probe cli.js:5 --expr 'rss' cli.js
Hit 1 at file:///path/to/cli.js:5:3
rss = 54935552
Hit 2 at file:///path/to/cli.js:5:3
rss = 55083008
Completed
The original <file>:<line>[:<col>] passed to --probe may be resolved to a different
location to ensure it's pausable, or it can match multiple loaded scripts, so the actual
evaluation location helps disambiguate the results.
Primitive results are printed directly, while objects and arrays use Chrome
DevTools Protocol preview data when available. Other non-primitive values
fall back to the Chrome DevTools Protocol description string.
Expression failures are recorded as [error] ... lines and do not fail
the overall session. If richer text formatting is needed, wrap the expression
in JSON.stringify(...) or util.inspect(...).
When --json is used, the output shape looks like this:
$ node inspect --json --probe cli.js:5 --expr 'rss' cli.js
{"v":2,"probes":[{"expr":"rss","target":{"suffix":"cli.js","line":5}}],"results":[{"probe":0,"event":"hit","hit":1,"location":{"url":"file:///path/to/cli.js","line":5,"column":3},"result":{"type":"number","value":55443456,"description":"55443456"}},{"probe":0,"event":"hit","hit":2,"location":{"url":"file:///path/to/cli.js","line":5,"column":3},"result":{"type":"number","value":55574528,"description":"55574528"}},{"event":"completed"}]}
{
"v": 2, // Probe JSON schema version.
"probes": [
{
"expr": "rss", // The expression paired with --probe.
"target": {
// The user's probe specification. `suffix` is the raw <file> passed
// to --probe and is matched as a path-separator-anchored suffix
// against every loaded script's URL. `column` is present only if the
// user supplied `:col`. The actual evaluation location may differ
// from the target and will be reported in each hit's `location` field.
"suffix": "cli.js",
"line": 5
}
// `condition` is present only when the probe was given a --cond expression.
// `maxHit` is present only when the probe was given a --max-hit limit.
}
],
"results": [
{
"probe": 0, // Index into probes[].
"event": "hit", // Hit events are recorded in observation order.
"hit": 1, // 1-based hit count for this probe.
"location": {
// The actual location where the execution is paused to evaluate
// the expression of the probe. This may differ from the probe's
// target due to pausability adjustments or multiple matches.
"url": "file:///path/to/cli.js",
"line": 5,
"column": 3
},
"result": {
"type": "number",
"value": 55443456,
"description": "55443456"
}
// If the probe expression throws, fails, or never completes, the entry
// carries an `error` field instead of `result` with the shape
// `{ message: string, details?: object }`. The `message` and `details`
// content is informational only and may change between releases.
},
{
"probe": 0,
"event": "hit",
"hit": 2,
"location": { "url": "file:///path/to/cli.js", "line": 5, "column": 3 },
"result": {
"type": "number",
"value": 55574528,
"description": "55574528"
}
},
{
"event": "completed"
// The final entry is always a terminal event, for example:
// 1. { "event": "completed" }
// 2. { "event": "miss", "pending": [0, 1] }
// 3. {
// "event": "timeout",
// "pending": [0],
// "error": {
// "code": "probe_timeout",
// "message": "Timed out after 30000ms waiting for probes: app.js:10"
// }
// }
// 4. {
// "event": "error",
// "pending": [0],
// "error": {
// "code": "probe_target_exit",
// "exitCode": 1,
// "stderr": "Error: boom",
// "message": "Target exited with code 1 before probes: app.js:10"
// }
// }
// 5. {
// "event": "error",
// "pending": [1],
// "error": {
// "code": "probe_failure",
// "probe": 0,
// "stderr": "...",
// "message": "Target process exited during probe evaluation before probes: app.js:12. If the failure repeats, review the probe expression.",
// "details": { "lastCdpMethod": "Debugger.evaluateOnCallFrame" }
// }
// }
}
]
}
Output and exit codes#
Probe mode only prints the final probe report to stdout, and otherwise silences
stdout/stderr from the child process. When the probing session ends,
the probing process typically exits with code 0 and prints a final report to
stdout. If the child process exits with a non-zero code before the probe
session ends, or the probe session cannot complete for another reason, the
final report records a terminal error event.
When error.code is 'probe_failure' or 'probe_timeout', the probing process
exits with a non-zero code, indicating recorded hits may be incomplete.
In this case, error.message will contain recovery hints, and error.probe,
when present, is an index into the report's probes array that identifies
the possible culprit probe on a best-effort basis to help guide debugging.
Invalid arguments and fatal launch or connect failures may cause the probing process to exit with a non-zero code and print an error message to stderr without a final probe report.
Probing multiple expressions at the same execution point#
When multiple --probe/--expr pairs share the same --probe, the
expressions will be evaluated on the same pause in the order they appear
on the command line.
For each location, there can only be at most one --cond (or none).
Multiple --probe/--expr pairs with conflicting conditions
at the same location will be rejected at launch time.
// app.js
const x = { x: 42 }; // line 2
const y = { y: 35 }; // line 3
const z = { ...x, ...y }; // line 4
$ node inspect --probe app.js:4 --expr 'x' --probe app.js:4 --expr 'y' -- app.js
Prints
Hit 1 at file:///path/to/app.js:4:1
x = {x: 42}
Hit 1 at file:///path/to/app.js:4:1
y = {y: 35}
Completed
$ node inspect --probe app.js:4 --expr 'x' --probe app.js:4 --expr 'y' --json --preview -- app.js
Prints
{"v":2,"probes":[{"expr":"x","target":{"suffix":"app.js","line":4}},{"expr":"y","target":{"suffix":"app.js","line":4}}],"results":[{"probe":0,"event":"hit","hit":1,"location":{"url":"file:///path/to/app.js","line":4,"column":1},"result":{"type":"object","description":"Object","preview":{"type":"object","description":"Object","overflow":false,"properties":[{"name":"x","type":"number","value":"42"}]}}},{"probe":1,"event":"hit","hit":1,"location":{"url":"file:///path/to/app.js","line":4,"column":1},"result":{"type":"object","description":"Object","preview":{"type":"object","description":"Object","overflow":false,"properties":[{"name":"y","type":"number","value":"35"}]}}},{"event":"completed"}]}
Selecting the probe location#
The expressions are evaluated in the lexical scope of the probe location when
execution reaches it. Avoid probing a variable declared by let or const at its
declaration site, as this leads to a ReferenceError caused by
accessing the variable in its temporal dead zone (TDZ).
// app.js
const x = 42; // line 2
console.log(x); // line 3
$ node inspect --probe app.js:1 --expr 'x' app.js
Hit 1 at file:///path/to/app.js:1:1
[error] x = ReferenceError: Cannot access 'x' from debugger
...
Completed
Instead, probe at a location where the variable is already initialized:
$ node inspect --probe app.js:3 --expr 'x' app.js
Hit 1 at file:///path/to/app.js:3:1
x = 42
Completed
The <file> argument is matched as a path suffix of every loaded
script URL, anchored on a path separator. Passing only a basename
matches every loaded script with that basename, similar to how native
debuggers typically match breakpoints, while passing a partial path
narrows the match. Given:
project/
- src/utils.js
- lib/utils.js
--probe utils.js:10 binds to both files and produces one hit per match.
Each hit carries its own location field identifying where the expression
was actually executed, so consumers can attribute the result to one of the
two files accurately. To disambiguate at bind time, specify a fuller path
that only matches the intended file:
$ node inspect --probe src/utils.js:10 --expr 'x' main.js # matches only src/utils.js
Probe examples#
Probing a variable conditionally#
// app.js
let total = 0;
for (let i = 0; i < 10; i++) {
total += i; // line 4
}
$ out/Release/node inspect --probe app.js:4 --expr 'total' \
--cond 'i % 3 === 0' app.js
Hit 1 at file:///path/to/app.js:3:3
total = 0
Hit 2 at file:///path/to/app.js:3:3
total = 3
Hit 3 at file:///path/to/app.js:3:3
total = 15
Hit 4 at file:///path/to/app.js:3:3
total = 36
Completed
Advanced usage#
V8 inspector integration for Node.js#
V8 Inspector integration allows attaching Chrome DevTools to Node.js instances for debugging and profiling. It uses the Chrome DevTools Protocol.
V8 Inspector can be enabled by passing the --inspect flag when starting a
Node.js application. It is also possible to supply a custom port with that flag,
e.g. --inspect=9222 will accept DevTools connections on port 9222.
Using the --inspect flag will execute the code immediately before debugger is connected.
This means that the code will start running before you can start debugging, which might
not be ideal if you want to debug from the very beginning.
In such cases, you have two alternatives:
--inspect-waitflag: This flag will wait for debugger to be attached before executing the code. This allows you to start debugging right from the beginning of the execution.--inspect-brkflag: Unlike--inspect, this flag will break on the first line of the code as soon as debugger is attached. This is useful when you want to debug the code step by step from the very beginning, without any code execution prior to debugging.
So, when deciding between --inspect, --inspect-wait, and --inspect-brk, consider whether you want
the code to start executing immediately, wait for debugger to be attached before execution,
or break on the first line for step-by-step debugging.
$ node --inspect index.js
Debugger listening on ws://127.0.0.1:9229/dc9010dd-f8b8-4ac5-a510-c1a114ec7d29
For help, see: https://nodejs.org/learn/getting-started/debugging
(In the example above, the UUID dc9010dd-f8b8-4ac5-a510-c1a114ec7d29 at the end of the URL is generated on the fly, it varies in different debugging sessions.)
Deprecated APIs#
Node.js APIs might be deprecated for any of the following reasons:
- Use of the API is unsafe.
- An improved alternative API is available.
- Breaking changes to the API are expected in a future major release.
Node.js uses four kinds of deprecations:
- Documentation-only
- Application (non-
node_modulescode only) - Runtime (all code)
- End-of-Life
A Documentation-only deprecation is one that is expressed only within the
Node.js API docs. These generate no side-effects while running Node.js.
Some Documentation-only deprecations trigger a runtime warning when launched
with --pending-deprecation flag (or its alternative,
NODE_PENDING_DEPRECATION=1 environment variable), similarly to Runtime
deprecations below. Documentation-only deprecations that support that flag
are explicitly labeled as such in the
list of Deprecated APIs.
An Application deprecation for only non-node_modules code will, by default,
generate a process warning that will be printed to stderr the first time
the deprecated API is used in code that's not loaded from node_modules.
When the --throw-deprecation command-line flag is used, a Runtime
deprecation will cause an error to be thrown. When
--pending-deprecation is used, warnings will also be emitted for
code loaded from node_modules.
A runtime deprecation for all code is similar to the runtime deprecation
for non-node_modules code, except that it also emits a warning for
code loaded from node_modules.
An End-of-Life deprecation is used when functionality is or will soon be removed from Node.js.
Revoking deprecations#
Occasionally, the deprecation of an API might be reversed. In such situations, this document will be updated with information relevant to the decision. However, the deprecation identifier will not be modified.
List of deprecated APIs#
DEP0001: http.OutgoingMessage.prototype.flush#
Type: End-of-Life
OutgoingMessage.prototype.flush() has been removed. Use
OutgoingMessage.prototype.flushHeaders() instead.
DEP0002: require('_linklist')#
Type: End-of-Life
The _linklist module is deprecated. Please use a userland alternative.
DEP0003: _writableState.buffer#
Type: End-of-Life
The _writableState.buffer has been removed. Use _writableState.getBuffer()
instead.
DEP0004: CryptoStream.prototype.readyState#
Type: End-of-Life
The CryptoStream.prototype.readyState property was removed.
DEP0005: Buffer() constructor#
Type: Application (non-node_modules code only)
The Buffer() function and new Buffer() constructor are deprecated due to
API usability issues that can lead to accidental security issues.
As an alternative, use one of the following methods of constructing Buffer
objects:
Buffer.alloc(size[, fill[, encoding]]): Create aBufferwith initialized memory.Buffer.allocUnsafe(size): Create aBufferwith uninitialized memory.Buffer.allocUnsafeSlow(size): Create aBufferwith uninitialized memory.Buffer.from(array): Create aBufferwith a copy ofarrayBuffer.from(arrayBuffer[, byteOffset[, length]])- Create aBufferthat wraps the givenarrayBuffer.Buffer.from(buffer): Create aBufferthat copiesbuffer.Buffer.from(string[, encoding]): Create aBufferthat copiesstring.
Without --pending-deprecation, runtime warnings occur only for code not in
node_modules. This means there will not be deprecation warnings for
Buffer() usage in dependencies. With --pending-deprecation, a runtime
warning results no matter where the Buffer() usage occurs.
DEP0006: child_process options.customFds#
Type: End-of-Life
Within the child_process module's spawn(), fork(), and exec()
methods, the options.customFds option is deprecated. The options.stdio
option should be used instead.
DEP0007: Replace cluster worker.suicide with worker.exitedAfterDisconnect#
Type: End-of-Life
In an earlier version of the Node.js cluster, a boolean property with the name
suicide was added to the Worker object. The intent of this property was to
provide an indication of how and why the Worker instance exited. In Node.js
6.0.0, the old property was deprecated and replaced with a new
worker.exitedAfterDisconnect property. The old property name did not
precisely describe the actual semantics and was unnecessarily emotion-laden.
DEP0008: require('node:constants')#
Type: Documentation-only
The node:constants module is deprecated. When requiring access to constants
relevant to specific Node.js builtin modules, developers should instead refer
to the constants property exposed by the relevant module. For instance,
require('node:fs').constants and require('node:os').constants.
DEP0009: crypto.pbkdf2 without digest#
Type: End-of-Life
Use of the crypto.pbkdf2() API without specifying a digest was deprecated
in Node.js 6.0 because the method defaulted to using the non-recommended
'SHA1' digest. Previously, a deprecation warning was printed. Starting in
Node.js 8.0.0, calling crypto.pbkdf2() or crypto.pbkdf2Sync() with
digest set to undefined will throw a TypeError.
Beginning in Node.js 11.0.0, calling these functions with digest set to
null would print a deprecation warning to align with the behavior when digest
is undefined.
Now, however, passing either undefined or null will throw a TypeError.
DEP0010: crypto.createCredentials#
Type: End-of-Life
The crypto.createCredentials() API was removed. Please use
tls.createSecureContext() instead.
DEP0011: crypto.Credentials#
Type: End-of-Life
The crypto.Credentials class was removed. Please use tls.SecureContext
instead.
DEP0012: Domain.dispose#
Type: End-of-Life
Domain.dispose() has been removed. Recover from failed I/O actions
explicitly via error event handlers set on the domain instead.
DEP0013: fs asynchronous function without callback#
Type: End-of-Life
Calling an asynchronous function without a callback throws a TypeError
in Node.js 10.0.0 onwards. See https://github.com/nodejs/node/pull/12562.
DEP0014: fs.read legacy String interface#
Type: End-of-Life
The fs.read() legacy String interface is deprecated. Use the Buffer
API as mentioned in the documentation instead.
DEP0015: fs.readSync legacy String interface#
Type: End-of-Life
The fs.readSync() legacy String interface is deprecated. Use the
Buffer API as mentioned in the documentation instead.
DEP0016: GLOBAL/root#
Type: End-of-Life
The GLOBAL and root aliases for the global property were deprecated
in Node.js 6.0.0 and have since been removed.
DEP0017: Intl.v8BreakIterator#
Type: End-of-Life
Intl.v8BreakIterator was a non-standard extension and has been removed.
See Intl.Segmenter.
DEP0018: Unhandled promise rejections#
Type: End-of-Life
Unhandled promise rejections are deprecated. By default, promise rejections
that are not handled terminate the Node.js process with a non-zero exit
code. To change the way Node.js treats unhandled rejections, use the
--unhandled-rejections command-line option.
DEP0019: require('.') resolved outside directory#
Type: End-of-Life
In certain cases, require('.') could resolve outside the package directory.
This behavior has been removed.
DEP0020: Server.connections#
Type: End-of-Life
The Server.connections property was deprecated in Node.js 0.9.7 and has
been removed. Please use the Server.getConnections() method instead.
DEP0021: Server.listenFD#
Type: End-of-Life
The Server.listenFD() method was deprecated and removed. Please use
Server.listen({fd: <number>}) instead.
DEP0022: os.tmpDir()#
Type: End-of-Life
The os.tmpDir() API was deprecated in Node.js 7.0.0 and has since been
removed. Please use os.tmpdir() instead.
An automated migration is available (source):
npx codemod@latest @nodejs/tmpDir-to-tmpdir
DEP0023: os.getNetworkInterfaces()#
Type: End-of-Life
The os.getNetworkInterfaces() method is deprecated. Please use the
os.networkInterfaces() method instead.
DEP0024: REPLServer.prototype.convertToContext()#
Type: End-of-Life
The REPLServer.prototype.convertToContext() API has been removed.
DEP0025: require('node:sys')#
Type: Runtime
The node:sys module is deprecated. Please use the util module instead.
DEP0026: util.print()#
Type: End-of-Life
util.print() has been removed. Please use console.log() instead.
An automated migration is available (source):
npx codemod@latest @nodejs/util-print-to-console-log
DEP0027: util.puts()#
Type: End-of-Life
util.puts() has been removed. Please use console.log() instead.
An automated migration is available (source):
npx codemod@latest @nodejs/util-print-to-console-log
DEP0028: util.debug()#
Type: End-of-Life
util.debug() has been removed. Please use console.error() instead.
An automated migration is available (source):
npx codemod@latest @nodejs/util-print-to-console-log
DEP0029: util.error()#
Type: End-of-Life
util.error() has been removed. Please use console.error() instead.
An automated migration is available (source):
npx codemod@latest @nodejs/util-print-to-console-log
DEP0030: SlowBuffer#
Type: End-of-Life
The SlowBuffer class has been removed. Please use
Buffer.allocUnsafeSlow(size) instead.
An automated migration is available (source).
npx codemod@latest @nodejs/slow-buffer-to-buffer-alloc-unsafe-slow
DEP0031: ecdh.setPublicKey()#
Type: Runtime
The ecdh.setPublicKey() method is now deprecated as its inclusion in
the API is not useful.
DEP0032: node:domain module#
Type: Documentation-only
The domain module is deprecated and should not be used.
DEP0033: EventEmitter.listenerCount()#
Type: Revoked
The events.listenerCount(emitter, eventName) API was deprecated, as it
provided identical functionality to emitter.listenerCount(eventName). The
deprecation was revoked because this function has been repurposed to also
accept <EventTarget> arguments.
DEP0034: fs.exists(path, callback)#
Type: Documentation-only
The fs.exists(path, callback) API is deprecated. Please use
fs.stat() or fs.access() instead.
DEP0035: fs.lchmod(path, mode, callback)#
Type: Documentation-only
The fs.lchmod(path, mode, callback) API is deprecated.
DEP0036: fs.lchmodSync(path, mode)#
Type: Documentation-only
The fs.lchmodSync(path, mode) API is deprecated.
DEP0037: fs.lchown(path, uid, gid, callback)#
Type: Deprecation revoked
The fs.lchown(path, uid, gid, callback) API was deprecated. The
deprecation was revoked because the requisite supporting APIs were added in
libuv.
DEP0038: fs.lchownSync(path, uid, gid)#
Type: Deprecation revoked
The fs.lchownSync(path, uid, gid) API was deprecated. The deprecation was
revoked because the requisite supporting APIs were added in libuv.
DEP0039: require.extensions#
Type: Documentation-only
The require.extensions property is deprecated.
DEP0040: node:punycode module#
Type: Application (non-node_modules code only)
The punycode module is deprecated. Please use a userland alternative
instead.
DEP0041: NODE_REPL_HISTORY_FILE environment variable#
Type: End-of-Life
The NODE_REPL_HISTORY_FILE environment variable was removed. Please use
NODE_REPL_HISTORY instead.
DEP0042: tls.CryptoStream#
Type: End-of-Life
The tls.CryptoStream class was removed. Please use
tls.TLSSocket instead.
DEP0043: tls.SecurePair#
Type: End-of-Life
The tls.SecurePair class is deprecated. Please use
tls.TLSSocket instead.
DEP0044: util.isArray()#
Type: Runtime
The util.isArray() API is deprecated. Please use Array.isArray()
instead.
An automated migration is available (source):
npx codemod@latest @nodejs/util-is
DEP0045: util.isBoolean()#
Type: End-of-Life
The util.isBoolean() API has been removed. Please use
typeof arg === 'boolean' instead.
An automated migration is available (source):
npx codemod@latest @nodejs/util-is
DEP0046: util.isBuffer()#
Type: End-of-Life
The util.isBuffer() API has been removed. Please use
Buffer.isBuffer() instead.
An automated migration is available (source):
npx codemod@latest @nodejs/util-is
DEP0047: util.isDate()#
Type: End-of-Life
The util.isDate() API has been removed. Please use
arg instanceof Date instead.
Also for stronger approaches, consider using:
Date.prototype.toString.call(arg) === '[object Date]' && !isNaN(arg).
This can also be used in a try/catch block to handle invalid date objects.
An automated migration is available (source):
npx codemod@latest @nodejs/util-is
DEP0048: util.isError()#
Type: End-of-Life
The util.isError() API has been removed. Please use Error.isError(arg).
An automated migration is available (source):
npx codemod@latest @nodejs/util-is
DEP0049: util.isFunction()#
Type: End-of-Life
The util.isFunction() API has been removed. Please use
typeof arg === 'function' instead.
An automated migration is available (source):
npx codemod@latest @nodejs/util-is
DEP0050: util.isNull()#
Type: End-of-Life
The util.isNull() API has been removed. Please use
arg === null instead.
An automated migration is available (source):
npx codemod@latest @nodejs/util-is
DEP0051: util.isNullOrUndefined()#
Type: End-of-Life
The util.isNullOrUndefined() API has been removed. Please use
arg === null || arg === undefined instead.
An automated migration is available (source):
npx codemod@latest @nodejs/util-is
DEP0052: util.isNumber()#
Type: End-of-Life
The util.isNumber() API has been removed. Please use
typeof arg === 'number' instead.
An automated migration is available (source):
npx codemod@latest @nodejs/util-is
DEP0053: util.isObject()#
Type: End-of-Life
The util.isObject() API has been removed. Please use
arg && typeof arg === 'object' instead.
An automated migration is available (source):
npx codemod@latest @nodejs/util-is
DEP0054: util.isPrimitive()#
Type: End-of-Life
The util.isPrimitive() API has been removed. Please use Object(arg) !== arg instead.
An automated migration is available (source):
npx codemod@latest @nodejs/util-is
DEP0055: util.isRegExp()#
Type: End-of-Life
The util.isRegExp() API has been removed. Please use
arg instanceof RegExp instead.
An automated migration is available (source):
npx codemod@latest @nodejs/util-is
DEP0056: util.isString()#
Type: End-of-Life
The util.isString() API has been removed. Please use
typeof arg === 'string' instead.
An automated migration is available (source):
npx codemod@latest @nodejs/util-is
DEP0057: util.isSymbol()#
Type: End-of-Life
The util.isSymbol() API has been removed. Please use
typeof arg === 'symbol' instead.
An automated migration is available (source):
npx codemod@latest @nodejs/util-is
DEP0058: util.isUndefined()#
Type: End-of-Life
The util.isUndefined() API has been removed. Please use
arg === undefined instead.
An automated migration is available (source):
npx codemod@latest @nodejs/util-is
DEP0059: util.log()#
Type: End-of-Life
The util.log() API has been removed because it's an unmaintained
legacy API that was exposed to user land by accident. Instead,
consider the following alternatives based on your specific needs:
-
Third-Party Logging Libraries
-
Use
console.log(new Date().toLocaleString(), message)
By adopting one of these alternatives, you can transition away from util.log()
and choose a logging strategy that aligns with the specific
requirements and complexity of your application.
An automated migration is available (source):
npx codemod@latest @nodejs/util-log-to-console-log
DEP0060: util._extend()#
Type: Runtime
The util._extend() API is deprecated because it's an unmaintained
legacy API that was exposed to user land by accident.
Please use target = Object.assign(target, source) instead.
An automated migration is available (source):
npx codemod@latest @nodejs/util-extend-to-object-assign
DEP0061: fs.SyncWriteStream#
Type: End-of-Life
The fs.SyncWriteStream class was never intended to be a publicly accessible
API and has been removed. No alternative API is available. Please use a userland
alternative.
DEP0062: node --debug#
Type: End-of-Life
--debug activates the legacy V8 debugger interface, which was removed as
of V8 5.8. It is replaced by Inspector which is activated with --inspect
instead.
DEP0063: ServerResponse.prototype.writeHeader()#
Type: End-of-Life
The node:http module ServerResponse.prototype.writeHeader() API is
deprecated. Please use ServerResponse.prototype.writeHead() instead.
The ServerResponse.prototype.writeHeader() method was never documented as an
officially supported API.
DEP0064: tls.createSecurePair()#
Type: End-of-Life
The tls.createSecurePair() API was deprecated in documentation in Node.js
0.11.3. Users should use tls.Socket instead.
An automated migration is available (source):
npx codemod @nodejs/tls-create-secure-pair-to-tls-socket
DEP0065: repl.REPL_MODE_MAGIC and NODE_REPL_MODE=magic#
Type: End-of-Life
The node:repl module's REPL_MODE_MAGIC constant, used for replMode option,
has been removed. Its behavior has been functionally identical to that of
REPL_MODE_SLOPPY since Node.js 6.0.0, when V8 5.0 was imported. Please use
REPL_MODE_SLOPPY instead.
The NODE_REPL_MODE environment variable is used to set the underlying
replMode of an interactive node session. Its value, magic, is also
removed. Please use sloppy instead.
DEP0066: OutgoingMessage.prototype._headers, OutgoingMessage.prototype._headerNames#
Type: End-of-Life
The node:http module OutgoingMessage.prototype._headers and
OutgoingMessage.prototype._headerNames properties are deprecated. Use one of
the public methods (e.g. OutgoingMessage.prototype.getHeader(),
OutgoingMessage.prototype.getHeaders(),
OutgoingMessage.prototype.getHeaderNames(),
OutgoingMessage.prototype.getRawHeaderNames(),
OutgoingMessage.prototype.hasHeader(),
OutgoingMessage.prototype.removeHeader(),
OutgoingMessage.prototype.setHeader()) for working with outgoing headers.
The OutgoingMessage.prototype._headers and
OutgoingMessage.prototype._headerNames properties were never documented as
officially supported properties.
An automated migration is available (source):
npx codemod@latest @nodejs/http-outgoingmessage-headers
DEP0067: OutgoingMessage.prototype._renderHeaders#
Type: Documentation-only
The node:http module OutgoingMessage.prototype._renderHeaders() API is
deprecated.
The OutgoingMessage.prototype._renderHeaders property was never documented as
an officially supported API.
DEP0068: node debug#
Type: End-of-Life
node debug corresponds to the legacy CLI debugger which has been replaced with
a V8-inspector based CLI debugger available through node inspect.
DEP0069: vm.runInDebugContext(string)#
Type: End-of-Life
DebugContext has been removed in V8 and is not available in Node.js 10+.
DebugContext was an experimental API.
DEP0070: async_hooks.currentId()#
Type: End-of-Life
async_hooks.currentId() was renamed to async_hooks.executionAsyncId() for
clarity.
This change was made while async_hooks was an experimental API.
DEP0071: async_hooks.triggerId()#
Type: End-of-Life
async_hooks.triggerId() was renamed to async_hooks.triggerAsyncId() for
clarity.
This change was made while async_hooks was an experimental API.
DEP0072: async_hooks.AsyncResource.triggerId()#
Type: End-of-Life
async_hooks.AsyncResource.triggerId() was renamed to
async_hooks.AsyncResource.triggerAsyncId() for clarity.
This change was made while async_hooks was an experimental API.
DEP0073: Several internal properties of net.Server#
Type: End-of-Life
Accessing several internal, undocumented properties of net.Server instances
with inappropriate names is deprecated.
As the original API was undocumented and not generally useful for non-internal code, no replacement API is provided.
DEP0074: REPLServer.bufferedCommand#
Type: End-of-Life
The REPLServer.bufferedCommand property was deprecated in favor of
REPLServer.clearBufferedCommand().
DEP0075: REPLServer.parseREPLKeyword()#
Type: End-of-Life
REPLServer.parseREPLKeyword() was removed from userland visibility.
DEP0076: tls.parseCertString()#
Type: End-of-Life
tls.parseCertString() was a trivial parsing helper that was made public by
mistake. While it was supposed to parse certificate subject and issuer strings,
it never handled multi-value Relative Distinguished Names correctly.
Earlier versions of this document suggested using querystring.parse() as an
alternative to tls.parseCertString(). However, querystring.parse() also does
not handle all certificate subjects correctly and should not be used.
DEP0077: Module._debug()#
Type: End-of-Life
Module._debug() has been removed.
The Module._debug() function was never documented as an officially
supported API.
DEP0078: REPLServer.turnOffEditorMode()#
Type: End-of-Life
REPLServer.turnOffEditorMode() was removed from userland visibility.
DEP0079: Custom inspection function on objects via .inspect()#
Type: End-of-Life
Using a property named inspect on an object to specify a custom inspection
function for util.inspect() is deprecated. Use util.inspect.custom
instead. For backward compatibility with Node.js prior to version 6.4.0, both
can be specified.
DEP0080: path._makeLong()#
Type: Documentation-only
The internal path._makeLong() was not intended for public use. However,
userland modules have found it useful. The internal API is deprecated
and replaced with an identical, public path.toNamespacedPath() method.
DEP0081: fs.truncate() using a file descriptor#
Type: End-of-Life
fs.truncate() fs.truncateSync() usage with a file descriptor is
deprecated. Please use fs.ftruncate() or fs.ftruncateSync() to work with
file descriptors.
An automated migration is available (source):
npx codemod@latest @nodejs/fs-truncate-fd-deprecation
DEP0082: REPLServer.prototype.memory()#
Type: End-of-Life
REPLServer.prototype.memory() is only necessary for the internal mechanics of
the REPLServer itself. Do not use this function.
DEP0083: Disabling ECDH by setting ecdhCurve to false#
Type: End-of-Life
The ecdhCurve option to tls.createSecureContext() and tls.TLSSocket could
be set to false to disable ECDH entirely on the server only. This mode was
deprecated in preparation for migrating to OpenSSL 1.1.0 and consistency with
the client and is now unsupported. Use the ciphers parameter instead.
DEP0084: requiring bundled internal dependencies#
Type: End-of-Life
Since Node.js versions 4.4.0 and 5.2.0, several modules only intended for
internal usage were mistakenly exposed to user code through require(). These
modules were:
v8/tools/codemapv8/tools/consarrayv8/tools/csvparserv8/tools/logreaderv8/tools/profile_viewv8/tools/profilev8/tools/SourceMapv8/tools/splaytreev8/tools/tickprocessor-driverv8/tools/tickprocessornode-inspect/lib/_inspect(from 7.6.0)node-inspect/lib/internal/inspect_client(from 7.6.0)node-inspect/lib/internal/inspect_repl(from 7.6.0)
The v8/* modules do not have any exports, and if not imported in a specific
order would in fact throw errors. As such there are virtually no legitimate use
cases for importing them through require().
On the other hand, node-inspect can be installed locally through a package
manager, as it is published on the npm registry under the same name. No source
code modification is necessary if that is done.
DEP0085: AsyncHooks sensitive API#
Type: End-of-Life
The AsyncHooks sensitive API was never documented and had various minor issues.
Use the AsyncResource API instead. See
https://github.com/nodejs/node/issues/15572.
DEP0086: Remove runInAsyncIdScope#
Type: End-of-Life
runInAsyncIdScope doesn't emit the 'before' or 'after' event and can thus
cause a lot of issues. See https://github.com/nodejs/node/issues/14328.
DEP0089: require('node:assert')#
Type: Deprecation revoked
Importing assert directly was not recommended as the exposed functions use
loose equality checks. The deprecation was revoked because use of the
node:assert module is not discouraged, and the deprecation caused developer
confusion.
DEP0090: Invalid GCM authentication tag lengths#
Type: End-of-Life
Node.js used to support all GCM authentication tag lengths which are accepted by
OpenSSL when calling decipher.setAuthTag(). Beginning with Node.js
v11.0.0, only authentication tag lengths of 128, 120, 112, 104, 96, 64, and 32
bits are allowed. Authentication tags of other lengths are invalid per
NIST SP 800-38D.
DEP0091: crypto.DEFAULT_ENCODING#
Type: End-of-Life
The crypto.DEFAULT_ENCODING property only existed for compatibility with
Node.js releases prior to versions 0.9.3 and has been removed.
DEP0092: Top-level this bound to module.exports#
Type: Documentation-only
Assigning properties to the top-level this as an alternative
to module.exports is deprecated. Developers should use exports
or module.exports instead.
DEP0093: crypto.fips is deprecated and replaced#
Type: Runtime
The crypto.fips property is deprecated. Please use crypto.setFips()
and crypto.getFips() instead.
An automated migration is available (source).
npx codemod@latest @nodejs/crypto-fips-to-getFips
DEP0094: Using assert.fail() with more than one argument#
Type: End-of-Life
Using assert.fail() with more than one argument is deprecated. Use
assert.fail() with only one argument or use a different node:assert module
method.
DEP0095: timers.enroll()#
Type: End-of-Life
timers.enroll() has been removed. Please use the publicly documented
setTimeout() or setInterval() instead.
An automated migration is available (source).
npx codemod @nodejs/timers-deprecations
DEP0096: timers.unenroll()#
Type: End-of-Life
timers.unenroll() has been removed. Please use the publicly documented
clearTimeout() or clearInterval() instead.
An automated migration is available (source).
npx codemod @nodejs/timers-deprecations
DEP0097: MakeCallback with domain property#
Type: Runtime
Users of MakeCallback that add the domain property to carry context,
should start using the async_context variant of MakeCallback or
CallbackScope, or the high-level AsyncResource class.
DEP0098: AsyncHooks embedder AsyncResource.emitBefore and AsyncResource.emitAfter APIs#
Type: End-of-Life
The embedded API provided by AsyncHooks exposes .emitBefore() and
.emitAfter() methods which are very easy to use incorrectly which can lead
to unrecoverable errors.
Use asyncResource.runInAsyncScope() API instead which provides a much
safer, and more convenient, alternative. See
https://github.com/nodejs/node/pull/18513.
DEP0099: Async context-unaware node::MakeCallback C++ APIs#
Type: Compile-time
Certain versions of node::MakeCallback APIs available to native addons are
deprecated. Please use the versions of the API that accept an async_context
parameter.
DEP0100: process.assert()#
Type: End-of-Life
process.assert() is deprecated. Please use the assert module instead.
This was never a documented feature.
An automated migration is available (source).
npx codemod@latest @nodejs/process-assert-to-node-assert
DEP0101: --with-lttng#
Type: End-of-Life
The --with-lttng compile-time option has been removed.
DEP0102: Using noAssert in Buffer#(read|write) operations#
Type: End-of-Life
Using the noAssert argument has no functionality anymore. All input is
verified regardless of the value of noAssert. Skipping the verification
could lead to hard-to-find errors and crashes.
DEP0103: process.binding('util').is[...] typechecks#
Type: Documentation-only (supports --pending-deprecation)
Using process.binding() in general should be avoided. The type checking
methods in particular can be replaced by using util.types.
This deprecation has been superseded by the deprecation of the
process.binding() API (DEP0111).
DEP0104: process.env string coercion#
Type: Documentation-only (supports --pending-deprecation)
When assigning a non-string property to process.env, the assigned value is
implicitly converted to a string. This behavior is deprecated if the assigned
value is not a string, boolean, or number. In the future, such assignment might
result in a thrown error. Please convert the property to a string before
assigning it to process.env.
DEP0105: decipher.finaltol#
Type: End-of-Life
decipher.finaltol() has never been documented and was an alias for
decipher.final(). This API has been removed, and it is recommended to use
decipher.final() instead.
DEP0106: crypto.createCipher and crypto.createDecipher#
Type: End-of-Life
crypto.createCipher() and crypto.createDecipher() have been removed
as they use a weak key derivation function (MD5 with no salt) and static
initialization vectors.
It is recommended to derive a key using
crypto.pbkdf2() or crypto.scrypt() with random salts and to use
crypto.createCipheriv() and crypto.createDecipheriv() to obtain the
Cipheriv and Decipheriv objects respectively.
An automated migration is available (source):
npx codemod @nodejs/crypto-createcipheriv-migration
DEP0107: tls.convertNPNProtocols()#
Type: End-of-Life
This was an undocumented helper function not intended for use outside Node.js core and obsoleted by the removal of NPN (Next Protocol Negotiation) support.
DEP0108: zlib.bytesRead#
Type: End-of-Life
Deprecated alias for zlib.bytesWritten. This original name was chosen
because it also made sense to interpret the value as the number of bytes
read by the engine, but is inconsistent with other streams in Node.js that
expose values under these names.
An automated migration is available (source):
npx codemod@latest @nodejs/zlib-bytesread-to-byteswritten
DEP0109: http, https, and tls support for invalid URLs#
Type: End-of-Life
Some previously supported (but strictly invalid) URLs were accepted through the
http.request(), http.get(), https.request(),
https.get(), and tls.checkServerIdentity() APIs because those were
accepted by the legacy url.parse() API. The mentioned APIs now use the WHATWG
URL parser that requires strictly valid URLs. Passing an invalid URL is
deprecated and support will be removed in the future.
DEP0110: vm.Script cached data#
Type: Documentation-only
The produceCachedData option is deprecated. Use
script.createCachedData() instead.
DEP0111: process.binding()#
Type: Documentation-only (supports --pending-deprecation)
process.binding() is for use by Node.js internal code only.
While process.binding() has not reached End-of-Life status in general, it is
unavailable when the permission model is enabled.
DEP0112: dgram private APIs#
Type: End-of-Life
The node:dgram module previously contained several APIs that were never meant
to accessed outside of Node.js core: Socket.prototype._handle,
Socket.prototype._receiving, Socket.prototype._bindState,
Socket.prototype._queue, Socket.prototype._reuseAddr,
Socket.prototype._healthCheck(), Socket.prototype._stopReceiving(), and
dgram._createSocketHandle(). These have been removed.
DEP0113: Cipher.setAuthTag(), Decipher.getAuthTag()#
Type: End-of-Life
Cipher.setAuthTag() and Decipher.getAuthTag() are no longer available. They
were never documented and would throw when called.
DEP0114: crypto._toBuf()#
Type: End-of-Life
The crypto._toBuf() function was not designed to be used by modules outside
of Node.js core and was removed.
DEP0115: crypto.prng(), crypto.pseudoRandomBytes(), crypto.rng()#
Type: Documentation-only (supports --pending-deprecation)
In recent versions of Node.js, there is no difference between
crypto.randomBytes() and crypto.pseudoRandomBytes(). The latter is
deprecated along with the undocumented aliases crypto.prng() and
crypto.rng() in favor of crypto.randomBytes() and might be removed in a
future release.
DEP0116: Legacy URL API#
Type: Deprecation revoked
The legacy URL API is deprecated. This includes url.format(),
url.parse(), url.resolve(), and the legacy urlObject. Please
use the WHATWG URL API instead.
An automated migration is available (source).
npx codemod@latest @nodejs/node-url-to-whatwg-url
DEP0117: Native crypto handles#
Type: End-of-Life
Previous versions of Node.js exposed handles to internal native objects through
the _handle property of the Cipher, Decipher, DiffieHellman,
DiffieHellmanGroup, ECDH, Hash, Hmac, Sign, and Verify classes.
The _handle property has been removed because improper use of the native
object can lead to crashing the application.
DEP0118: dns.lookup() support for a falsy host name#
Type: End-of-Life
Previous versions of Node.js supported dns.lookup() with a falsy host name
like dns.lookup(false) due to backward compatibility. This has been removed.
DEP0119: process.binding('uv').errname() private API#
Type: Documentation-only (supports --pending-deprecation)
process.binding('uv').errname() is deprecated. Please use
util.getSystemErrorName() instead.
DEP0120: Windows Performance Counter support#
Type: End-of-Life
Windows Performance Counter support has been removed from Node.js. The
undocumented COUNTER_NET_SERVER_CONNECTION(),
COUNTER_NET_SERVER_CONNECTION_CLOSE(), COUNTER_HTTP_SERVER_REQUEST(),
COUNTER_HTTP_SERVER_RESPONSE(), COUNTER_HTTP_CLIENT_REQUEST(), and
COUNTER_HTTP_CLIENT_RESPONSE() functions have been deprecated.
DEP0121: net._setSimultaneousAccepts()#
Type: End-of-Life
The undocumented net._setSimultaneousAccepts() function was originally
intended for debugging and performance tuning when using the
node:child_process and node:cluster modules on Windows. The function is not
generally useful and is being removed. See discussion here:
https://github.com/nodejs/node/issues/18391
DEP0122: tls Server.prototype.setOptions()#
Type: End-of-Life
Please use Server.prototype.setSecureContext() instead.
DEP0123: setting the TLS ServerName to an IP address#
Type: End-of-Life
Setting the TLS ServerName to an IP address is not permitted by RFC 6066.
DEP0124: using REPLServer.rli#
Type: End-of-Life
This property is a reference to the instance itself.
DEP0125: require('node:_stream_wrap')#
Type: End-of-Life
The node:_stream_wrap module is deprecated.
DEP0126: timers.active()#
Type: End-of-Life
The previously undocumented timers.active() has been removed.
Please use the publicly documented timeout.refresh() instead.
If re-referencing the timeout is necessary, timeout.ref() can be used
with no performance impact since Node.js 10.
An automated migration is available (source).
npx codemod @nodejs/timers-deprecations
DEP0127: timers._unrefActive()#
Type: End-of-Life
The previously undocumented and "private" timers._unrefActive() has been removed.
Please use the publicly documented timeout.refresh() instead.
If unreferencing the timeout is necessary, timeout.unref() can be used
with no performance impact since Node.js 10.
An automated migration is available (source).
npx codemod @nodejs/timers-deprecations
DEP0128: modules with an invalid main entry and an index.js file#
Type: Runtime
Modules that have an invalid main entry (e.g., ./does-not-exist.js) and
also have an index.js file in the top level directory will resolve the
index.js file. That is deprecated and is going to throw an error in future
Node.js versions.
DEP0129: ChildProcess._channel#
Type: End-of-Life
The _channel property of child process objects returned by spawn() and
similar functions is not intended for public use. Use ChildProcess.channel
instead.
DEP0130: Module.createRequireFromPath()#
Type: End-of-Life
Use module.createRequire() instead.
An automated migration is available (source):
npx codemod@latest @nodejs/create-require-from-path
DEP0131: Legacy HTTP parser#
Type: End-of-Life
The legacy HTTP parser, used by default in versions of Node.js prior to 12.0.0,
is deprecated and has been removed in v13.0.0. Prior to v13.0.0, the
--http-parser=legacy command-line flag could be used to revert to using the
legacy parser.
DEP0132: worker.terminate() with callback#
Type: End-of-Life
Passing a callback to worker.terminate() is deprecated. Use the returned
Promise instead, or a listener to the worker's 'exit' event.
DEP0133: http connection#
Type: Documentation-only
Prefer response.socket over response.connection and
request.socket over request.connection.
DEP0134: process._tickCallback#
Type: Documentation-only (supports --pending-deprecation)
The process._tickCallback property was never documented as
an officially supported API.
DEP0135: WriteStream.open() and ReadStream.open() are internal#
Type: End-of-Life
WriteStream.open() and ReadStream.open() are undocumented internal
APIs that do not make sense to use in userland. File streams should always be
opened through their corresponding factory methods fs.createWriteStream()
and fs.createReadStream()) or by passing a file descriptor in options.
DEP0136: http finished#
Type: Documentation-only
response.finished indicates whether response.end() has been
called, not whether 'finish' has been emitted and the underlying data
is flushed.
Use response.writableFinished or response.writableEnded
accordingly instead to avoid the ambiguity.
To maintain existing behavior response.finished should be replaced with
response.writableEnded.
DEP0137: Closing fs.FileHandle on garbage collection#
Type: End-of-Life
Allowing a fs.FileHandle object to be closed on garbage collection used
to be allowed, but now throws an error.
Please ensure that all fs.FileHandle objects are explicitly closed using
FileHandle.prototype.close() when the fs.FileHandle is no longer needed:
const fsPromises = require('node:fs').promises;
async function openAndClose() {
let filehandle;
try {
filehandle = await fsPromises.open('thefile.txt', 'r');
} finally {
if (filehandle !== undefined)
await filehandle.close();
}
}
DEP0138: process.mainModule#
Type: Documentation-only
process.mainModule is a CommonJS-only feature while process global
object is shared with non-CommonJS environment. Its use within ECMAScript
modules is unsupported.
It is deprecated in favor of require.main, because it serves the same
purpose and is only available on CommonJS environment.
An automated migration is available (source):
npx codemod@latest @nodejs/process-main-module
DEP0139: process.umask() with no arguments#
Type: Documentation-only
Calling process.umask() with no argument causes the process-wide umask to be
written twice. This introduces a race condition between threads, and is a
potential security vulnerability. There is no safe, cross-platform alternative
API.
DEP0140: Use request.destroy() instead of request.abort()#
Type: Documentation-only
Use request.destroy() instead of request.abort().
DEP0141: repl.inputStream and repl.outputStream#
Type: Documentation-only (supports --pending-deprecation)
The node:repl module exported the input and output stream twice. Use .input
instead of .inputStream and .output instead of .outputStream.
DEP0142: repl._builtinLibs#
Type: Documentation-only (supports --pending-deprecation)
The node:repl module exports a _builtinLibs property that contains an array
of built-in modules. It was incomplete so far and instead it's better to rely
upon require('node:module').builtinModules.
An automated migration is available (source):
npx codemod@latest @nodejs/repl-builtin-modules
DEP0143: Transform._transformState#
Type: End-of-Life
Transform._transformState will be removed in future versions where it is
no longer required due to simplification of the implementation.
DEP0144: module.parent#
Type: Documentation-only (supports --pending-deprecation)
A CommonJS module can access the first module that required it using
module.parent. This feature is deprecated because it does not work
consistently in the presence of ECMAScript modules and because it gives an
inaccurate representation of the CommonJS module graph.
Some modules use it to check if they are the entry point of the current process.
Instead, it is recommended to compare require.main and module:
if (require.main === module) {
// Code section that will run only if current file is the entry point.
}
When looking for the CommonJS modules that have required the current one,
require.cache and module.children can be used:
const moduleParents = Object.values(require.cache)
.filter((m) => m.children.includes(module));
DEP0145: socket.bufferSize#
Type: Documentation-only
socket.bufferSize is just an alias for writable.writableLength.
DEP0146: new crypto.Certificate()#
Type: Documentation-only
The crypto.Certificate() constructor is deprecated. Use
static methods of crypto.Certificate() instead.
DEP0147: fs.rmdir(path, { recursive: true })#
Type: End-of-Life
The fs.rmdir, fs.rmdirSync, and fs.promises.rmdir methods used
to support a recursive option. That option has been removed.
Use fs.rm(path, { recursive: true, force: true }),
fs.rmSync(path, { recursive: true, force: true }) or
fs.promises.rm(path, { recursive: true, force: true }) instead.
An automated migration is available (source):
npx codemod@latest @nodejs/rmdir
DEP0148: Folder mappings in "exports" (trailing "/")#
Type: End-of-Life
Using a trailing "/" to define subpath folder mappings in the
subpath exports or subpath imports fields is no longer supported.
Use subpath patterns instead.
DEP0149: http.IncomingMessage#connection#
Type: Documentation-only
Prefer message.socket over message.connection.
DEP0150: Changing the value of process.config#
Type: End-of-Life
The process.config property provides access to Node.js compile-time settings.
However, the property is mutable and therefore subject to tampering. The ability
to change the value will be removed in a future version of Node.js.
DEP0151: Main index lookup and extension searching#
Type: Runtime
Previously, index.js and extension searching lookups would apply to
import 'pkg' main entry point resolution, even when resolving ES modules.
With this deprecation, all ES module main entry point resolutions require
an explicit "exports" or "main" entry with the exact file extension.
DEP0152: Extension PerformanceEntry properties#
Type: End-of-Life
The 'gc', 'http2', and 'http' <PerformanceEntry> object types used to have
additional properties assigned to them that provide additional information.
These properties are now available within the standard detail property
of the PerformanceEntry object. The deprecated accessors have been
removed.
DEP0153: dns.lookup and dnsPromises.lookup options type coercion#
Type: End-of-Life
Using a non-nullish non-integer value for family option, a non-nullish
non-number value for hints option, a non-nullish non-boolean value for all
option, or a non-nullish non-boolean value for verbatim option in
dns.lookup() and dnsPromises.lookup() throws an
ERR_INVALID_ARG_TYPE error.
DEP0154: RSA-PSS generate key pair options#
Type: End-of-Life
Use 'hashAlgorithm' instead of 'hash', and 'mgf1HashAlgorithm' instead of 'mgf1Hash'.
An automated migration is available (source):
npx codemod@latest @nodejs/crypto-rsa-pss-update
DEP0155: Trailing slashes in pattern specifier resolutions#
Type: Runtime
The remapping of specifiers ending in "/" like import 'pkg/x/' is deprecated
for package "exports" and "imports" pattern resolutions.
DEP0156: .aborted property and 'abort', 'aborted' event in http#
Type: Documentation-only
Move to <Stream> API instead, as the http.ClientRequest,
http.ServerResponse, and http.IncomingMessage are all stream-based.
Check stream.destroyed instead of the .aborted property, and listen for
'close' instead of 'abort', 'aborted' event.
The .aborted property and 'abort' event are only useful for detecting
.abort() calls. For closing a request early, use the Stream
.destroy([error]) then check the .destroyed property and 'close' event
should have the same effect. The receiving end should also check the
readable.readableEnded value on http.IncomingMessage to get whether
it was an aborted or graceful destroy.
DEP0157: Thenable support in streams#
Type: End-of-Life
An undocumented feature of Node.js streams was to support thenables in implementation methods. This is now deprecated, use callbacks instead and avoid use of async function for streams implementation methods.
This feature caused users to encounter unexpected problems where the user implements the function in callback style but uses e.g. an async method which would cause an error since mixing promise and callback semantics is not valid.
const w = new Writable({
async final(callback) {
await someOp();
callback();
},
});
DEP0158: buffer.slice(start, end)#
Type: Documentation-only
This method was deprecated because it is not compatible with
Uint8Array.prototype.slice(), which is a superclass of Buffer.
Use buffer.subarray which does the same thing instead.
DEP0159: ERR_INVALID_CALLBACK#
Type: End-of-Life
This error code was removed due to adding more confusion to the errors used for value type validation.
An automated migration is available (source):
npx codemod @nodejs/err-invalid-callback
DEP0160: process.on('multipleResolves', handler)#
Type: End-of-Life
This event was deprecated and removed because it did not work with V8 promise combinators which diminished its usefulness.
DEP0161: process._getActiveRequests() and process._getActiveHandles()#
Type: Documentation-only
The process._getActiveHandles() and process._getActiveRequests()
functions are not intended for public use and can be removed in future
releases.
Use process.getActiveResourcesInfo() to get a list of types of active
resources and not the actual references.
DEP0162: fs.write(), fs.writeFileSync() coercion to string#
Type: End-of-Life
Implicit coercion of objects with own toString property, passed as second
parameter in fs.write(), fs.writeFile(), fs.appendFile(),
fs.writeFileSync(), and fs.appendFileSync() is deprecated.
Convert them to primitive strings.
DEP0163: channel.subscribe(onMessage), channel.unsubscribe(onMessage)#
Type: Deprecation revoked
These methods were deprecated because their use could leave the channel object vulnerable to being garbage-collected if not strongly referenced by the user. The deprecation was revoked because channel objects are now resistant to garbage collection when the channel has active subscribers.
DEP0164: process.exit(code), process.exitCode coercion to integer#
Type: End-of-Life
Values other than undefined, null, integer numbers, and integer strings
(e.g., '1') are deprecated as value for the code parameter in
process.exit() and as value to assign to process.exitCode.
DEP0165: --trace-atomics-wait#
Type: End-of-Life
The --trace-atomics-wait flag has been removed because
it uses the V8 hook SetAtomicsWaitCallback,
that will be removed in a future V8 release.
DEP0166: Double slashes in imports and exports targets#
Type: Runtime
Package imports and exports targets mapping into paths including a double slash (of "/" or "\") are deprecated and will fail with a resolution validation error in a future release. This same deprecation also applies to pattern matches starting or ending in a slash.
DEP0167: Weak DiffieHellmanGroup instances (modp1, modp2, modp5)#
Type: Documentation-only
The well-known MODP groups modp1, modp2, and modp5 are deprecated because
they are not secure against practical attacks. See RFC 8247 Section 2.4 for
details.
These groups might be removed in future versions of Node.js. Applications that rely on these groups should evaluate using stronger MODP groups instead.
DEP0168: Unhandled exception in Node-API callbacks#
Type: Runtime
The implicit suppression of uncaught exceptions in Node-API callbacks is now deprecated.
Set the flag --force-node-api-uncaught-exceptions-policy to force Node.js
to emit an 'uncaughtException' event if the exception is not handled in
Node-API callbacks.
DEP0169: Insecure url.parse()#
Type: Application (non-node_modules code only)
url.parse() behavior is not standardized and prone to errors that
have security implications. Use the WHATWG URL API instead. CVEs are not
issued for url.parse() vulnerabilities.
Calling url.format(urlString) or url.resolve() invokes url.parse()
internally, and is therefore also covered by this deprecation.
DEP0170: Invalid port when using url.parse()#
Type: End-of-Life
url.parse() used to accept URLs with ports that are not numbers. This
behavior might result in host name spoofing with unexpected input. These URLs
will throw an error (which the WHATWG URL API also does).
DEP0171: Setters for http.IncomingMessage headers and trailers#
Type: Documentation-only
In a future version of Node.js, message.headers,
message.headersDistinct, message.trailers, and
message.trailersDistinct will be read-only.
DEP0172: The asyncResource property of AsyncResource bound functions#
Type: End-of-Life
Older versions of Node.js would add the asyncResource when a function is
bound to an AsyncResource. It no longer does.
DEP0173: the assert.CallTracker class#
Type: End-of-Life
The assert.CallTracker API has been removed.
DEP0174: calling promisify on a function that returns a Promise#
Type: Runtime
Calling util.promisify on a function that returns a Promise will ignore
the result of said promise, which can lead to unhandled promise rejections.
DEP0175: util.toUSVString#
Type: Documentation-only
The util.toUSVString() API is deprecated. Please use
String.prototype.toWellFormed instead.
DEP0176: fs.F_OK, fs.R_OK, fs.W_OK, fs.X_OK#
Type: End-of-Life
F_OK, R_OK, W_OK and X_OK getters exposed directly on node:fs were
removed. Get them from fs.constants or fs.promises.constants instead.
An automated migration is available (source):
npx codemod@latest @nodejs/fs-access-mode-constants
DEP0177: util.types.isWebAssemblyCompiledModule#
Type: End-of-Life
The util.types.isWebAssemblyCompiledModule API has been removed.
Please use value instanceof WebAssembly.Module instead.
DEP0178: dirent.path#
Type: End-of-Life
The dirent.path property has been removed due to its lack of consistency across
release lines. Please use dirent.parentPath instead.
An automated migration is available (source):
npx codemod@latest @nodejs/dirent-path-to-parent-path
DEP0179: Hash constructor#
Type: Runtime
Calling Hash class directly with Hash() or new Hash() is
deprecated due to being internals, not intended for public use.
Please use the crypto.createHash() method to create Hash instances.
DEP0180: fs.Stats constructor#
Type: Runtime
Calling fs.Stats class directly with Stats() or new Stats() is
deprecated due to being internals, not intended for public use.
DEP0181: Hmac constructor#
Type: Runtime
Calling Hmac class directly with Hmac() or new Hmac() is
deprecated due to being internals, not intended for public use.
Please use the crypto.createHmac() method to create Hmac instances.
DEP0182: Short GCM authentication tags without explicit authTagLength#
Type: End-of-Life
For ciphers in GCM mode, the decipher.setAuthTag() function used to accept
authentication tags of any valid length (see also DEP0090). This
exception has been removed to better align with recommendations per
NIST SP 800-38D, and applications that intend to use authentication tags
that are shorter than the default authentication tag length (i.e., shorter than
16 bytes for AES-GCM) must explicitly set the authTagLength option of the
crypto.createDecipheriv() function to the appropriate length.
DEP0183: OpenSSL engine-based APIs#
Type: Documentation-only
OpenSSL 3 has deprecated support for custom engines with a recommendation to
switch to its new provider model. The clientCertEngine option for
https.request(), tls.createSecureContext(), and tls.createServer();
the privateKeyEngine and privateKeyIdentifier for tls.createSecureContext();
and crypto.setEngine() all depend on this functionality from OpenSSL.
DEP0184: Instantiating node:zlib classes without new#
Type: Runtime
Instantiating classes without the new qualifier exported by the node:zlib module is deprecated.
It is recommended to use the new qualifier instead. This applies to all Zlib classes, such as Deflate,
DeflateRaw, Gunzip, Inflate, InflateRaw, Unzip, and Zlib.
DEP0185: Instantiating node:repl classes without new#
Type: End-of-Life
Instantiating classes without the new qualifier exported by the node:repl module is deprecated.
The new qualifier must be used instead. This applies to all REPL classes, including
REPLServer and Recoverable.
An automated migration is available (source):
npx codemod@latest @nodejs/repl-classes-with-new
DEP0187: Passing invalid argument types to fs.existsSync#
Type: Runtime
Passing non-supported argument types is deprecated and, instead of returning false,
will throw an error in a future version.
DEP0188: process.features.ipv6 and process.features.uv#
Type: Documentation-only
These properties are unconditionally true. Any checks based on these properties are redundant.
DEP0189: process.features.tls_*#
Type: Documentation-only
process.features.tls_alpn, process.features.tls_ocsp, and process.features.tls_sni are
deprecated, as their values are guaranteed to be identical to that of process.features.tls.
DEP0190: Passing args to node:child_process execFile/spawn with shell option#
Type: Runtime
When an args array is passed to child_process.execFile or child_process.spawn with the option
{ shell: true } or { shell: '/path/to/shell' }, the values are not escaped, only space-separated,
which can lead to shell injection.
DEP0191: repl.builtinModules#
Type: Documentation-only (supports --pending-deprecation)
The node:repl module exports a builtinModules property that contains an array
of built-in modules. This was incomplete and matched the already deprecated
repl._builtinLibs (DEP0142) instead it's better to rely
upon require('node:module').builtinModules.
An automated migration is available (source):
npx codemod@latest @nodejs/repl-builtin-modules
DEP0192: require('node:_tls_common') and require('node:_tls_wrap')#
Type: Runtime
The node:_tls_common and node:_tls_wrap modules are deprecated as they should be considered
an internal nodejs implementation rather than a public facing API, use node:tls instead.
DEP0193: require('node:_stream_*')#
Type: End-of-Life
The node:_stream_duplex, node:_stream_passthrough, node:_stream_readable, node:_stream_transform,
node:_stream_wrap and node:_stream_writable modules are deprecated as they should be considered
an internal nodejs implementation rather than a public facing API, use node:stream instead.
DEP0194: HTTP/2 priority signaling#
Type: End-of-Life
The support for priority signaling has been removed following its deprecation in the RFC 9113.
An automated migration is available (source):
npx codemod@latest @nodejs/http2-priority-signaling
DEP0195: Instantiating node:http classes without new#
Type: Documentation-only
Instantiating classes without the new qualifier exported by the node:http module is deprecated.
It is recommended to use the new qualifier instead. This applies to all http classes, such as
OutgoingMessage, IncomingMessage, ServerResponse and ClientRequest.
An automated migration is available (source):
npx codemod@latest @nodejs/http-classes-with-new
DEP0196: Calling node:child_process functions with options.shell as an empty string#
Type: Documentation-only
Calling the process-spawning functions with { shell: '' } is almost certainly
unintentional, and can cause aberrant behavior.
To make child_process.execFile or child_process.spawn invoke the
default shell, use { shell: true }. If the intention is not to invoke a shell
(default behavior), either omit the shell option, or set it to false or a
nullish value.
To make child_process.exec invoke the default shell, either omit the
shell option, or set it to a nullish value. If the intention is not to invoke
a shell, use child_process.execFile instead.
DEP0197: util.types.isNativeError()#
Type: Documentation-only
The util.types.isNativeError API is deprecated. Please use Error.isError instead.
An automated migration is available (source):
npx codemod@latest @nodejs/types-is-native-error
DEP0198: Creating SHAKE-128 and SHAKE-256 digests without an explicit options.outputLength#
Type: Runtime
Creating SHAKE-128 and SHAKE-256 digests without an explicit options.outputLength is deprecated.
DEP0199: require('node:_http_*')#
Type: Documentation-only
The node:_http_agent, node:_http_client, node:_http_common, node:_http_incoming,
node:_http_outgoing and node:_http_server modules are deprecated as they should be considered
an internal nodejs implementation rather than a public facing API, use node:http instead.
DEP0200: Closing fs.Dir on garbage collection#
Type: Documentation-only
Allowing a fs.Dir object to be closed on garbage collection is
deprecated. In the future, doing so might result in a thrown error that will
terminate the process.
Please ensure that all fs.Dir objects are explicitly closed using
Dir.prototype.close() or using keyword:
import { opendir } from 'node:fs/promises';
{
await using dir = await opendir('/async/disposable/directory');
} // Closed by dir[Symbol.asyncDispose]()
{
using dir = await opendir('/sync/disposable/directory');
} // Closed by dir[Symbol.dispose]()
{
const dir = await opendir('/unconditionally/iterated/directory');
for await (const entry of dir) {
// process an entry
} // Closed by iterator
}
{
let dir;
try {
dir = await opendir('/legacy/closeable/directory');
} finally {
await dir?.close();
}
}
DEP0201: Passing options.type to Duplex.toWeb()#
Type: Runtime
Passing the type option to Duplex.toWeb() is deprecated. To specify the
type of the readable half of the constructed readable-writable pair, use the
readableType option instead.
DEP0202: Http1IncomingMessage and Http1ServerResponse options of HTTP/2 servers#
Type: Documentation-only
The Http1IncomingMessage and Http1ServerResponse options of
http2.createServer() and http2.createSecureServer() are
deprecated. Use http1Options.IncomingMessage and
http1Options.ServerResponse instead.
// Deprecated
const server = http2.createSecureServer({
allowHTTP1: true,
Http1IncomingMessage: MyIncomingMessage,
Http1ServerResponse: MyServerResponse,
});
// Use this instead
const server = http2.createSecureServer({
allowHTTP1: true,
http1Options: {
IncomingMessage: MyIncomingMessage,
ServerResponse: MyServerResponse,
},
});
DEP0203: Passing CryptoKey to node:crypto APIs#
Type: Runtime
Passing a CryptoKey to node:crypto functions is deprecated and
will throw an error in a future version. This includes
crypto.createPublicKey(), crypto.createPrivateKey(),
crypto.sign(), crypto.verify(),
crypto.publicEncrypt(), crypto.publicDecrypt(),
crypto.privateEncrypt(), crypto.privateDecrypt(),
Sign.prototype.sign(), Verify.prototype.verify(),
crypto.createHmac(), crypto.createCipheriv(),
crypto.createDecipheriv(), crypto.encapsulate(), and
crypto.decapsulate().
DEP0204: KeyObject.from() with non-extractable CryptoKey#
Type: Runtime
Passing a non-extractable CryptoKey to KeyObject.from() is
deprecated and will throw an error in a future version.
DEP0205: module.register()#
Type: Runtime
module.register() is deprecated. Use module.registerHooks()
instead.
The module.register() API provides off-thread async hooks for customizing ES modules;
the module.registerHooks() API provides similar hooks that are synchronous, in-thread, and
work for all types of modules.
Supporting async hooks has proven to be complex, involving worker threads orchestration, and there are issues
that have proven unresolvable. See caveats of asynchronous customization hooks. Please migrate to
module.registerHooks() as soon as possible as module.register() will be
removed in a future version of Node.js.
DEP0206: Calling digest() on an already-finalized Hmac instance#
Type: Documentation-only
Calling hmac.digest() more than once returns an empty buffer instead of
throwing an error. This behavior is inconsistent with hash.digest() and
may lead to subtle bugs. Calling hmac.digest() on a finalized Hmac instance
will throw an error in a future version.
DEP0208: Server.prototype._listen2#
Type: Documentation-only
net.Server.prototype._listen2 is an undocumented alias for an internal
function that sets up the listening handle. It is kept only so that code
replacing it keeps being called by server.listen(), and it will be
removed in a future version of Node.js. Use server.listen() instead of
calling or overriding _listen2.
DEP0209: Using AbortSignal to dispose of resources#
Type: Documentation-only
Using AbortSignal to destroy long-lived resources is deprecated. Prefer
using for resource cleanup.
AbortSignal is still a good fit for canceling actions, propagating
cancellation from the outside, and timeouts.
// Deprecated
async function example() {
const ac = new AbortController();
const server = http.createServer(handler);
server.listen({ port: 3000, signal: ac.signal });
await doWork();
ac.abort();
}
// Use this instead
async function example() {
await using server = http.createServer(handler);
server.listen(3000);
await doWork();
}
// Deprecated
async function example() {
const ac = new AbortController();
const stream = addAbortSignal(ac.signal, fs.createReadStream(file));
await consume(stream);
ac.abort();
}
// Use this instead
async function example() {
await using stream = fs.createReadStream(file);
await consume(stream);
}
// Deprecated
async function example() {
const ac = new AbortController();
const child = spawn(command, args, { signal: ac.signal });
await doWork();
ac.abort();
}
// Use this instead
async function example() {
using child = spawn(command, args);
await doWork();
}
DEP0210: sqlite.DatabaseSync#
Type: Documentation-only
node:sqlite's DatabaseSync class was renamed to Database. DatabaseSync
is kept as a deprecated alias. Use Database instead.
DEP0211: sqlite.StatementSync#
Type: Documentation-only
node:sqlite's StatementSync class was renamed to Statement.
StatementSync is kept as a deprecated alias. Use Statement instead.
Diagnostic report#
Stability: 2 - Stable
Delivers a JSON-formatted diagnostic summary, written to a file.
The report is intended for development, test, and production use, to capture and preserve information for problem determination. It includes JavaScript and native stack traces, heap statistics, platform information, resource usage etc. With the report option enabled, diagnostic reports can be triggered on unhandled exceptions, fatal errors and user signals, in addition to triggering programmatically through API calls.
A complete example report that was generated on an uncaught exception is provided below for reference.
{
"header": {
"reportVersion": 5,
"event": "exception",
"trigger": "Exception",
"filename": "report.20181221.005011.8974.0.001.json",
"dumpEventTime": "2018-12-21T00:50:11Z",
"dumpEventTimeStamp": "1545371411331",
"processId": 8974,
"cwd": "/home/nodeuser/project/node",
"commandLine": [
"/home/nodeuser/project/node/out/Release/node",
"--report-uncaught-exception",
"/home/nodeuser/project/node/test/report/test-exception.js",
"child"
],
"nodejsVersion": "v12.0.0-pre",
"glibcVersionRuntime": "2.17",
"glibcVersionCompiler": "2.17",
"wordSize": "64 bit",
"arch": "x64",
"platform": "linux",
"componentVersions": {
"node": "12.0.0-pre",
"v8": "7.1.302.28-node.5",
"uv": "1.24.1",
"zlib": "1.2.11",
"ares": "1.15.0",
"modules": "68",
"nghttp2": "1.34.0",
"napi": "3",
"llhttp": "1.0.1",
"openssl": "1.1.0j"
},
"release": {
"name": "node"
},
"osName": "Linux",
"osRelease": "3.10.0-862.el7.x86_64",
"osVersion": "#1 SMP Wed Mar 21 18:14:51 EDT 2018",
"osMachine": "x86_64",
"cpus": [
{
"model": "Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz",
"speed": 2700,
"user": 88902660,
"nice": 0,
"sys": 50902570,
"idle": 241732220,
"irq": 0
},
{
"model": "Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz",
"speed": 2700,
"user": 88902660,
"nice": 0,
"sys": 50902570,
"idle": 241732220,
"irq": 0
}
],
"networkInterfaces": [
{
"name": "en0",
"internal": false,
"mac": "13:10:de:ad:be:ef",
"address": "10.0.0.37",
"netmask": "255.255.255.0",
"family": "IPv4"
}
],
"host": "test_machine"
},
"javascriptStack": {
"message": "Error: *** test-exception.js: throwing uncaught Error",
"stack": [
"at myException (/home/nodeuser/project/node/test/report/test-exception.js:9:11)",
"at Object.<anonymous> (/home/nodeuser/project/node/test/report/test-exception.js:12:3)",
"at Module._compile (internal/modules/cjs/loader.js:718:30)",
"at Object.Module._extensions..js (internal/modules/cjs/loader.js:729:10)",
"at Module.load (internal/modules/cjs/loader.js:617:32)",
"at tryModuleLoad (internal/modules/cjs/loader.js:560:12)",
"at Function.Module._load (internal/modules/cjs/loader.js:552:3)",
"at Function.Module.runMain (internal/modules/cjs/loader.js:771:12)",
"at executeUserCode (internal/bootstrap/node.js:332:15)"
]
},
"nativeStack": [
{
"pc": "0x000055b57f07a9ef",
"symbol": "report::GetNodeReport(v8::Isolate*, node::Environment*, char const*, char const*, v8::Local<v8::String>, std::ostream&) [./node]"
},
{
"pc": "0x000055b57f07cf03",
"symbol": "report::GetReport(v8::FunctionCallbackInfo<v8::Value> const&) [./node]"
},
{
"pc": "0x000055b57f1bccfd",
"symbol": " [./node]"
},
{
"pc": "0x000055b57f1be048",
"symbol": "v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*) [./node]"
},
{
"pc": "0x000055b57feeda0e",
"symbol": " [./node]"
}
],
"javascriptHeap": {
"totalMemory": 5660672,
"executableMemory": 524288,
"totalCommittedMemory": 5488640,
"availableMemory": 4341379928,
"totalGlobalHandlesMemory": 8192,
"usedGlobalHandlesMemory": 3136,
"usedMemory": 4816432,
"memoryLimit": 4345298944,
"mallocedMemory": 254128,
"externalMemory": 315644,
"peakMallocedMemory": 98752,
"nativeContextCount": 1,
"detachedContextCount": 0,
"doesZapGarbage": 0,
"heapSpaces": {
"read_only_space": {
"memorySize": 524288,
"committedMemory": 39208,
"capacity": 515584,
"used": 30504,
"available": 485080
},
"new_space": {
"memorySize": 2097152,
"committedMemory": 2019312,
"capacity": 1031168,
"used": 985496,
"available": 45672
},
"old_space": {
"memorySize": 2273280,
"committedMemory": 1769008,
"capacity": 1974640,
"used": 1725488,
"available": 249152
},
"code_space": {
"memorySize": 696320,
"committedMemory": 184896,
"capacity": 152128,
"used": 152128,
"available": 0
},
"map_space": {
"memorySize": 536576,
"committedMemory": 344928,
"capacity": 327520,
"used": 327520,
"available": 0
},
"large_object_space": {
"memorySize": 0,
"committedMemory": 0,
"capacity": 1520590336,
"used": 0,
"available": 1520590336
},
"new_large_object_space": {
"memorySize": 0,
"committedMemory": 0,
"capacity": 0,
"used": 0,
"available": 0
}
}
},
"resourceUsage": {
"rss": "35766272",
"free_memory": "1598337024",
"total_memory": "17179869184",
"available_memory": "1598337024",
"maxRss": "36624662528",
"constrained_memory": "36624662528",
"userCpuSeconds": 0.040072,
"kernelCpuSeconds": 0.016029,
"cpuConsumptionPercent": 5.6101,
"userCpuConsumptionPercent": 4.0072,
"kernelCpuConsumptionPercent": 1.6029,
"pageFaults": {
"IORequired": 0,
"IONotRequired": 4610
},
"fsActivity": {
"reads": 0,
"writes": 0
}
},
"uvthreadResourceUsage": {
"userCpuSeconds": 0.039843,
"kernelCpuSeconds": 0.015937,
"cpuConsumptionPercent": 5.578,
"userCpuConsumptionPercent": 3.9843,
"kernelCpuConsumptionPercent": 1.5937,
"fsActivity": {
"reads": 0,
"writes": 0
}
},
"libuv": [
{
"type": "async",
"is_active": true,
"is_referenced": false,
"address": "0x0000000102910900",
"details": ""
},
{
"type": "timer",
"is_active": false,
"is_referenced": false,
"address": "0x00007fff5fbfeab0",
"repeat": 0,
"firesInMsFromNow": 94403548320796,
"expired": true
},
{
"type": "check",
"is_active": true,
"is_referenced": false,
"address": "0x00007fff5fbfeb48"
},
{
"type": "idle",
"is_active": false,
"is_referenced": true,
"address": "0x00007fff5fbfebc0"
},
{
"type": "prepare",
"is_active": false,
"is_referenced": false,
"address": "0x00007fff5fbfec38"
},
{
"type": "check",
"is_active": false,
"is_referenced": false,
"address": "0x00007fff5fbfecb0"
},
{
"type": "async",
"is_active": true,
"is_referenced": false,
"address": "0x000000010188f2e0"
},
{
"type": "tty",
"is_active": false,
"is_referenced": true,
"address": "0x000055b581db0e18",
"width": 204,
"height": 55,
"fd": 17,
"writeQueueSize": 0,
"readable": true,
"writable": true
},
{
"type": "signal",
"is_active": true,
"is_referenced": false,
"address": "0x000055b581d80010",
"signum": 28,
"signal": "SIGWINCH"
},
{
"type": "tty",
"is_active": true,
"is_referenced": true,
"address": "0x000055b581df59f8",
"width": 204,
"height": 55,
"fd": 19,
"writeQueueSize": 0,
"readable": true,
"writable": true
},
{
"type": "loop",
"is_active": true,
"address": "0x000055fc7b2cb180",
"loopIdleTimeSeconds": 22644.8
},
{
"type": "tcp",
"is_active": true,
"is_referenced": true,
"address": "0x000055e70fcb85d8",
"localEndpoint": {
"host": "localhost",
"ip4": "127.0.0.1",
"port": 48986
},
"remoteEndpoint": {
"host": "localhost",
"ip4": "127.0.0.1",
"port": 38573
},
"sendBufferSize": 2626560,
"recvBufferSize": 131072,
"fd": 24,
"writeQueueSize": 0,
"readable": true,
"writable": true
}
],
"workers": [],
"environmentVariables": {
"REMOTEHOST": "REMOVED",
"MANPATH": "/opt/rh/devtoolset-3/root/usr/share/man:",
"XDG_SESSION_ID": "66126",
"HOSTNAME": "test_machine",
"HOST": "test_machine",
"TERM": "xterm-256color",
"SHELL": "/bin/csh",
"SSH_CLIENT": "REMOVED",
"PERL5LIB": "/opt/rh/devtoolset-3/root//usr/lib64/perl5/vendor_perl:/opt/rh/devtoolset-3/root/usr/lib/perl5:/opt/rh/devtoolset-3/root//usr/share/perl5/vendor_perl",
"OLDPWD": "/home/nodeuser/project/node/src",
"JAVACONFDIRS": "/opt/rh/devtoolset-3/root/etc/java:/etc/java",
"SSH_TTY": "/dev/pts/0",
"PCP_DIR": "/opt/rh/devtoolset-3/root",
"GROUP": "normaluser",
"USER": "nodeuser",
"LD_LIBRARY_PATH": "/opt/rh/devtoolset-3/root/usr/lib64:/opt/rh/devtoolset-3/root/usr/lib",
"HOSTTYPE": "x86_64-linux",
"XDG_CONFIG_DIRS": "/opt/rh/devtoolset-3/root/etc/xdg:/etc/xdg",
"MAIL": "/var/spool/mail/nodeuser",
"PATH": "/home/nodeuser/project/node:/opt/rh/devtoolset-3/root/usr/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin",
"PWD": "/home/nodeuser/project/node",
"LANG": "en_US.UTF-8",
"PS1": "\\u@\\h : \\[\\e[31m\\]\\w\\[\\e[m\\] > ",
"SHLVL": "2",
"HOME": "/home/nodeuser",
"OSTYPE": "linux",
"VENDOR": "unknown",
"PYTHONPATH": "/opt/rh/devtoolset-3/root/usr/lib64/python2.7/site-packages:/opt/rh/devtoolset-3/root/usr/lib/python2.7/site-packages",
"MACHTYPE": "x86_64",
"LOGNAME": "nodeuser",
"XDG_DATA_DIRS": "/opt/rh/devtoolset-3/root/usr/share:/usr/local/share:/usr/share",
"LESSOPEN": "||/usr/bin/lesspipe.sh %s",
"INFOPATH": "/opt/rh/devtoolset-3/root/usr/share/info",
"XDG_RUNTIME_DIR": "/run/user/50141",
"_": "./node"
},
"userLimits": {
"core_file_size_blocks": {
"soft": "",
"hard": "unlimited"
},
"data_seg_size_bytes": {
"soft": "unlimited",
"hard": "unlimited"
},
"file_size_blocks": {
"soft": "unlimited",
"hard": "unlimited"
},
"max_locked_memory_bytes": {
"soft": "unlimited",
"hard": 65536
},
"max_memory_size_bytes": {
"soft": "unlimited",
"hard": "unlimited"
},
"open_files": {
"soft": "unlimited",
"hard": 4096
},
"stack_size_bytes": {
"soft": "unlimited",
"hard": "unlimited"
},
"cpu_time_seconds": {
"soft": "unlimited",
"hard": "unlimited"
},
"max_user_processes": {
"soft": "unlimited",
"hard": 4127290
},
"virtual_memory_bytes": {
"soft": "unlimited",
"hard": "unlimited"
}
},
"sharedObjects": [
"/lib64/libdl.so.2",
"/lib64/librt.so.1",
"/lib64/libstdc++.so.6",
"/lib64/libm.so.6",
"/lib64/libgcc_s.so.1",
"/lib64/libpthread.so.0",
"/lib64/libc.so.6",
"/lib64/ld-linux-x86-64.so.2"
]
}
Usage#
node --report-uncaught-exception --report-on-signal \
--report-on-fatalerror app.js
-
--report-uncaught-exceptionEnables report to be generated on un-caught exceptions. Useful when inspecting JavaScript stack in conjunction with native stack and other runtime environment data. -
--report-on-signalEnables report to be generated upon receiving the specified (or predefined) signal to the running Node.js process. (See below on how to modify the signal that triggers the report.) Default signal isSIGUSR2. Useful when a report needs to be triggered from another program. Application monitors may leverage this feature to collect report at regular intervals and plot rich set of internal runtime data to their views.
Signal based report generation is not supported in Windows.
Under normal circumstances, there is no need to modify the report triggering
signal. However, if SIGUSR2 is already used for other purposes, then this
flag helps to change the signal for report generation and preserve the original
meaning of SIGUSR2 for the said purposes.
-
--report-on-fatalerrorEnables the report to be triggered on fatal errors (internal errors within the Node.js runtime, such as out of memory) that leads to termination of the application. Useful to inspect various diagnostic data elements such as heap, stack, event loop state, resource consumption etc. to reason about the fatal error. -
--report-on-process-timeoutEnables the report to be triggered when the duration set with--process-timeoutelapses before the process exits. Useful to reason about why the process did not exit. -
--report-compactWrite reports in a compact format, single-line JSON, more easily consumable by log processing systems than the default multi-line format designed for human consumption. -
--report-directoryLocation at which the report will be generated. -
--report-filenameName of the file to which the report will be written. -
--report-signalSets or resets the signal for report generation (not supported on Windows). Default signal isSIGUSR2. -
--report-exclude-networkExcludeheader.networkInterfacesand disable the reverse DNS queries inlibuv.*.(remote|local)Endpoint.hostfrom the diagnostic report. By default this is not set and the network interfaces are included. -
--report-exclude-envExcludeenvironmentVariablesfrom the diagnostic report. By default this is not set and the environment variables are included.
A report can also be triggered via an API call from a JavaScript application:
process.report.writeReport();
This function takes an optional additional argument filename, which is
the name of a file into which the report is written.
process.report.writeReport('./foo.json');
This function takes an optional additional argument err which is an Error
object that will be used as the context for the JavaScript stack printed in the
report. When using report to handle errors in a callback or an exception
handler, this allows the report to include the location of the original error as
well as where it was handled.
try {
process.chdir('/non-existent-path');
} catch (err) {
process.report.writeReport(err);
}
// Any other code
If both filename and error object are passed to writeReport() the
error object must be the second parameter.
try {
process.chdir('/non-existent-path');
} catch (err) {
process.report.writeReport(filename, err);
}
// Any other code
The content of the diagnostic report can be returned as a JavaScript Object via an API call from a JavaScript application:
const report = process.report.getReport();
console.log(typeof report === 'object'); // true
// Similar to process.report.writeReport() output
console.log(JSON.stringify(report, null, 2));
This function takes an optional additional argument err, which is an Error
object that will be used as the context for the JavaScript stack printed in the
report.
const report = process.report.getReport(new Error('custom error'));
console.log(typeof report === 'object'); // true
The API versions are useful when inspecting the runtime state from within the application, in expectation of self-adjusting the resource consumption, load balancing, monitoring etc.
The content of the report consists of a header section containing the event
type, date, time, PID, and Node.js version, sections containing JavaScript and
native stack traces, a section containing V8 heap information, a section
containing libuv handle information, and an OS platform information section
showing CPU and memory usage and system limits. An example report can be
triggered using the Node.js REPL:
$ node
> process.report.writeReport();
Writing Node.js report to file: report.20181126.091102.8480.0.001.json
Node.js report completed
>
When a report is written, start and end messages are issued to stderr and the filename of the report is returned to the caller. The default filename includes the date, time, PID, and a sequence number. The sequence number helps in associating the report dump with the runtime state if generated multiple times for the same Node.js process.
Report Version#
Diagnostic report has an associated single-digit version number (report.header.reportVersion),
uniquely representing the report format. The version number is bumped
when new key is added or removed, or the data type of a value is changed.
Report version definitions are consistent across LTS releases.
Version history#
Version 5#
Replace the keys data_seg_size_kbytes, max_memory_size_kbytes, and virtual_memory_kbytes
with data_seg_size_bytes, max_memory_size_bytes, and virtual_memory_bytes
respectively in the userLimits section, as these values are given in bytes.
{
"userLimits": {
// Skip some keys ...
"data_seg_size_bytes": { // replacing data_seg_size_kbytes
"soft": "unlimited",
"hard": "unlimited"
},
// ...
"max_memory_size_bytes": { // replacing max_memory_size_kbytes
"soft": "unlimited",
"hard": "unlimited"
},
// ...
"virtual_memory_bytes": { // replacing virtual_memory_kbytes
"soft": "unlimited",
"hard": "unlimited"
}
}
}
Version 4#
New fields ipv4 and ipv6 are added to tcp and udp libuv handles endpoints. Examples:
{
"libuv": [
{
"type": "tcp",
"is_active": true,
"is_referenced": true,
"address": "0x000055e70fcb85d8",
"localEndpoint": {
"host": "localhost",
"ip4": "127.0.0.1", // new key
"port": 48986
},
"remoteEndpoint": {
"host": "localhost",
"ip4": "127.0.0.1", // new key
"port": 38573
},
"sendBufferSize": 2626560,
"recvBufferSize": 131072,
"fd": 24,
"writeQueueSize": 0,
"readable": true,
"writable": true
},
{
"type": "tcp",
"is_active": true,
"is_referenced": true,
"address": "0x000055e70fcd68c8",
"localEndpoint": {
"host": "ip6-localhost",
"ip6": "::1", // new key
"port": 52266
},
"remoteEndpoint": {
"host": "ip6-localhost",
"ip6": "::1", // new key
"port": 38573
},
"sendBufferSize": 2626560,
"recvBufferSize": 131072,
"fd": 25,
"writeQueueSize": 0,
"readable": false,
"writable": false
}
]
}
Version 3#
The following memory usage keys are added to the resourceUsage section.
{
"resourceUsage": {
"rss": "35766272",
"free_memory": "1598337024",
"total_memory": "17179869184",
"available_memory": "1598337024",
"constrained_memory": "36624662528"
}
}
Version 2#
Added Worker support. Refer to Interaction with workers section for more details.
Version 1#
This is the first version of the diagnostic report.
Configuration#
Additional runtime configuration of report generation is available via
the following properties of process.report:
reportOnFatalError triggers diagnostic reporting on fatal errors when true.
Defaults to false.
reportOnSignal triggers diagnostic reporting on signal when true. This is
not supported on Windows. Defaults to false.
reportOnUncaughtException triggers diagnostic reporting on uncaught exception
when true. Defaults to false.
signal specifies the POSIX signal identifier that will be used
to intercept external triggers for report generation. Defaults to
'SIGUSR2'.
filename specifies the name of the output file in the file system.
Special meaning is attached to stdout and stderr. Usage of these
will result in report being written to the associated standard streams.
In cases where standard streams are used, the value in directory is ignored.
URLs are not supported. Defaults to a composite filename that contains
timestamp, PID, and sequence number.
directory specifies the file system directory where the report will be
written. URLs are not supported. Defaults to the current working directory of
the Node.js process.
excludeNetwork excludes header.networkInterfaces from the diagnostic report.
// Trigger report only on uncaught exceptions.
process.report.reportOnFatalError = false;
process.report.reportOnSignal = false;
process.report.reportOnUncaughtException = true;
// Trigger report for both internal errors as well as external signal.
process.report.reportOnFatalError = true;
process.report.reportOnSignal = true;
process.report.reportOnUncaughtException = false;
// Change the default signal to 'SIGQUIT' and enable it.
process.report.reportOnFatalError = false;
process.report.reportOnUncaughtException = false;
process.report.reportOnSignal = true;
process.report.signal = 'SIGQUIT';
// Disable network interfaces reporting
process.report.excludeNetwork = true;
Configuration on module initialization is also available via environment variables:
NODE_OPTIONS="--report-uncaught-exception \
--report-on-fatalerror --report-on-signal \
--report-signal=SIGUSR2 --report-filename=./report.json \
--report-directory=/home/nodeuser"
Specific API documentation can be found under
process API documentation section.
Interaction with workers#
Worker threads can create reports in the same way that the main thread
does.
Reports will include information on any Workers that are children of the current
thread as part of the workers section, with each Worker generating a report
in the standard report format.
The thread which is generating the report will wait for the reports from Worker threads to finish. However, the latency for this will usually be low, as both running JavaScript and the event loop are interrupted to generate the report.
Diagnostics Channel#
Stability: 2 - Stable
The node:diagnostics_channel module provides an API to create named channels
to report arbitrary message data for diagnostics purposes.
It can be accessed using:
import diagnostics_channel from 'node:diagnostics_channel';const diagnostics_channel = require('node:diagnostics_channel');
It is intended that a module writer wanting to report diagnostics messages will create one or many top-level channels to report messages through. Channels may also be acquired at runtime but it is not encouraged due to the additional overhead of doing so. Channels may be exported for convenience, but as long as the name is known it can be acquired anywhere.
If you intend for your module to produce diagnostics data for others to consume it is recommended that you include documentation of what named channels are used along with the shape of the message data. Channel names should generally include the module name to avoid collisions with data from other modules.
Public API#
Overview#
Following is a simple overview of the public API.
import diagnostics_channel from 'node:diagnostics_channel'; // Get a reusable channel object const channel = diagnostics_channel.channel('my-channel'); function onMessage(message, name) { // Received data } // Subscribe to the channel diagnostics_channel.subscribe('my-channel', onMessage); // Check if the channel has an active subscriber if (channel.hasSubscribers) { // Publish data to the channel channel.publish({ some: 'data', }); } // Unsubscribe from the channel diagnostics_channel.unsubscribe('my-channel', onMessage);const diagnostics_channel = require('node:diagnostics_channel'); // Get a reusable channel object const channel = diagnostics_channel.channel('my-channel'); function onMessage(message, name) { // Received data } // Subscribe to the channel diagnostics_channel.subscribe('my-channel', onMessage); // Check if the channel has an active subscriber if (channel.hasSubscribers) { // Publish data to the channel channel.publish({ some: 'data', }); } // Unsubscribe from the channel diagnostics_channel.unsubscribe('my-channel', onMessage);
diagnostics_channel.hasSubscribers(name)#
Check if there are active subscribers to the named channel. This is helpful if the message you want to send might be expensive to prepare.
This API is optional but helpful when trying to publish messages from very performance-sensitive code.
import diagnostics_channel from 'node:diagnostics_channel'; if (diagnostics_channel.hasSubscribers('my-channel')) { // There are subscribers, prepare and publish message }const diagnostics_channel = require('node:diagnostics_channel'); if (diagnostics_channel.hasSubscribers('my-channel')) { // There are subscribers, prepare and publish message }
diagnostics_channel.channel(name)#
This is the primary entry-point for anyone wanting to publish to a named channel. It produces a channel object which is optimized to reduce overhead at publish time as much as possible.
import diagnostics_channel from 'node:diagnostics_channel'; const channel = diagnostics_channel.channel('my-channel');const diagnostics_channel = require('node:diagnostics_channel'); const channel = diagnostics_channel.channel('my-channel');
diagnostics_channel.subscribe(name, onMessage)#
name<string>|<symbol>The channel nameonMessage<Function>The handler to receive channel messages
Register a message handler to subscribe to this channel. This message handler
will be run synchronously whenever a message is published to the channel. Any
errors thrown in the message handler will trigger an 'uncaughtException'.
import diagnostics_channel from 'node:diagnostics_channel'; diagnostics_channel.subscribe('my-channel', (message, name) => { // Received data });const diagnostics_channel = require('node:diagnostics_channel'); diagnostics_channel.subscribe('my-channel', (message, name) => { // Received data });
diagnostics_channel.unsubscribe(name, onMessage)#
name<string>|<symbol>The channel nameonMessage<Function>The previous subscribed handler to remove- Returns:
<boolean>trueif the handler was found,falseotherwise.
Remove a message handler previously registered to this channel with
diagnostics_channel.subscribe(name, onMessage).
import diagnostics_channel from 'node:diagnostics_channel'; function onMessage(message, name) { // Received data } diagnostics_channel.subscribe('my-channel', onMessage); diagnostics_channel.unsubscribe('my-channel', onMessage);const diagnostics_channel = require('node:diagnostics_channel'); function onMessage(message, name) { // Received data } diagnostics_channel.subscribe('my-channel', onMessage); diagnostics_channel.unsubscribe('my-channel', onMessage);
diagnostics_channel.tracingChannel(nameOrChannels)#
Stability: 2 - Stable
nameOrChannels<string>|<TracingChannel>Channel name or object containing all the TracingChannel Channels- Returns:
<TracingChannel>Collection of channels to trace with
Creates a TracingChannel wrapper for the given
TracingChannel Channels. If a name is given, the corresponding tracing
channels will be created in the form of tracing:${name}:${eventType} where
eventType corresponds to the types of TracingChannel Channels.
import diagnostics_channel from 'node:diagnostics_channel'; const channelsByName = diagnostics_channel.tracingChannel('my-channel'); // or... const channelsByCollection = diagnostics_channel.tracingChannel({ start: diagnostics_channel.channel('tracing:my-channel:start'), end: diagnostics_channel.channel('tracing:my-channel:end'), asyncStart: diagnostics_channel.channel('tracing:my-channel:asyncStart'), asyncEnd: diagnostics_channel.channel('tracing:my-channel:asyncEnd'), error: diagnostics_channel.channel('tracing:my-channel:error'), });const diagnostics_channel = require('node:diagnostics_channel'); const channelsByName = diagnostics_channel.tracingChannel('my-channel'); // or... const channelsByCollection = diagnostics_channel.tracingChannel({ start: diagnostics_channel.channel('tracing:my-channel:start'), end: diagnostics_channel.channel('tracing:my-channel:end'), asyncStart: diagnostics_channel.channel('tracing:my-channel:asyncStart'), asyncEnd: diagnostics_channel.channel('tracing:my-channel:asyncEnd'), error: diagnostics_channel.channel('tracing:my-channel:error'), });
diagnostics_channel.boundedChannel(nameOrChannels)#
Stability: 1 - Experimental
nameOrChannels<string>|<BoundedChannel>Channel name or object containing all the BoundedChannel Channels- Returns:
<BoundedChannel>Collection of channels to trace with
Creates a BoundedChannel wrapper for the given channels. If a name is
given, the corresponding channels will be created in the form of
tracing:${name}:${eventType} where eventType is start or end.
A BoundedChannel is a simplified version of TracingChannel that only
traces synchronous operations. It only has start and end events, without
asyncStart, asyncEnd, or error events, making it suitable for tracing
operations that don't involve asynchronous continuations or error handling.
import { boundedChannel, channel } from 'node:diagnostics_channel'; const wc = boundedChannel('my-operation'); // or... const wc2 = boundedChannel({ start: channel('tracing:my-operation:start'), end: channel('tracing:my-operation:end'), });const { boundedChannel, channel } = require('node:diagnostics_channel'); const wc = boundedChannel('my-operation'); // or... const wc2 = boundedChannel({ start: channel('tracing:my-operation:start'), end: channel('tracing:my-operation:end'), });
Class: Channel#
The class Channel represents an individual named channel within the data
pipeline. It is used to track subscribers and to publish messages when there
are subscribers present. It exists as a separate object to avoid channel
lookups at publish time, enabling very fast publish speeds and allowing
for heavy use while incurring very minimal cost. Channels are created with
diagnostics_channel.channel(name), constructing a channel directly
with new Channel(name) is not supported.
channel.hasSubscribers#
- Returns:
<boolean>If there are active subscribers
Check if there are active subscribers to this channel. This is helpful if the message you want to send might be expensive to prepare.
This API is optional but helpful when trying to publish messages from very performance-sensitive code.
import diagnostics_channel from 'node:diagnostics_channel'; const channel = diagnostics_channel.channel('my-channel'); if (channel.hasSubscribers) { // There are subscribers, prepare and publish message }const diagnostics_channel = require('node:diagnostics_channel'); const channel = diagnostics_channel.channel('my-channel'); if (channel.hasSubscribers) { // There are subscribers, prepare and publish message }
channel.publish(message)#
message<any>The message to send to the channel subscribers
Publish a message to any subscribers to the channel. This will trigger message handlers synchronously so they will execute within the same context.
import diagnostics_channel from 'node:diagnostics_channel'; const channel = diagnostics_channel.channel('my-channel'); channel.publish({ some: 'message', });const diagnostics_channel = require('node:diagnostics_channel'); const channel = diagnostics_channel.channel('my-channel'); channel.publish({ some: 'message', });
channel.subscribe(onMessage)#
onMessage<Function>The handler to receive channel messages
Register a message handler to subscribe to this channel. This message handler
will be run synchronously whenever a message is published to the channel. Any
errors thrown in the message handler will trigger an 'uncaughtException'.
import diagnostics_channel from 'node:diagnostics_channel'; const channel = diagnostics_channel.channel('my-channel'); channel.subscribe((message, name) => { // Received data });const diagnostics_channel = require('node:diagnostics_channel'); const channel = diagnostics_channel.channel('my-channel'); channel.subscribe((message, name) => { // Received data });
channel.unsubscribe(onMessage)#
onMessage<Function>The previous subscribed handler to remove- Returns:
<boolean>trueif the handler was found,falseotherwise.
Remove a message handler previously registered to this channel with
channel.subscribe(onMessage).
import diagnostics_channel from 'node:diagnostics_channel'; const channel = diagnostics_channel.channel('my-channel'); function onMessage(message, name) { // Received data } channel.subscribe(onMessage); channel.unsubscribe(onMessage);const diagnostics_channel = require('node:diagnostics_channel'); const channel = diagnostics_channel.channel('my-channel'); function onMessage(message, name) { // Received data } channel.subscribe(onMessage); channel.unsubscribe(onMessage);
channel.bindStore(store[, transform])#
Stability: 1 - Experimental
store<AsyncLocalStorage>The store to which to bind the context datatransform<Function>Transform context data before setting the store context
When channel.runStores(context, ...) is called, the given context data
will be applied to any store bound to the channel. If the store has already been
bound the previous transform function will be replaced with the new one.
The transform function may be omitted to set the given context data as the
context directly.
import diagnostics_channel from 'node:diagnostics_channel'; import { AsyncLocalStorage } from 'node:async_hooks'; const store = new AsyncLocalStorage(); const channel = diagnostics_channel.channel('my-channel'); channel.bindStore(store, (data) => { return { data }; });const diagnostics_channel = require('node:diagnostics_channel'); const { AsyncLocalStorage } = require('node:async_hooks'); const store = new AsyncLocalStorage(); const channel = diagnostics_channel.channel('my-channel'); channel.bindStore(store, (data) => { return { data }; });
channel.unbindStore(store)#
Stability: 1 - Experimental
store<AsyncLocalStorage>The store to unbind from the channel.- Returns:
<boolean>trueif the store was found,falseotherwise.
Remove a message handler previously registered to this channel with
channel.bindStore(store).
import diagnostics_channel from 'node:diagnostics_channel'; import { AsyncLocalStorage } from 'node:async_hooks'; const store = new AsyncLocalStorage(); const channel = diagnostics_channel.channel('my-channel'); channel.bindStore(store); channel.unbindStore(store);const diagnostics_channel = require('node:diagnostics_channel'); const { AsyncLocalStorage } = require('node:async_hooks'); const store = new AsyncLocalStorage(); const channel = diagnostics_channel.channel('my-channel'); channel.bindStore(store); channel.unbindStore(store);
channel.runStores(context, fn[, thisArg[, ...args]])#
Stability: 1 - Experimental
context<any>Message to send to subscribers and bind to storesfn<Function>Handler to run within the entered storage contextthisArg<any>The receiver to be used for the function call....args<any>Optional arguments to pass to the function.
Applies the given data to any AsyncLocalStorage instances bound to the channel for the duration of the given function, then publishes to the channel within the scope of that data is applied to the stores.
If a transform function was given to channel.bindStore(store) it will be
applied to transform the message data before it becomes the context value for
the store. The prior storage context is accessible from within the transform
function in cases where context linking is required.
The context applied to the store should be accessible in any async code which continues from execution which began during the given function, however there are some situations in which context loss may occur.
import diagnostics_channel from 'node:diagnostics_channel'; import { AsyncLocalStorage } from 'node:async_hooks'; const store = new AsyncLocalStorage(); const channel = diagnostics_channel.channel('my-channel'); channel.bindStore(store, (message) => { const parent = store.getStore(); return new Span(message, parent); }); channel.runStores({ some: 'message' }, () => { store.getStore(); // Span({ some: 'message' }) });const diagnostics_channel = require('node:diagnostics_channel'); const { AsyncLocalStorage } = require('node:async_hooks'); const store = new AsyncLocalStorage(); const channel = diagnostics_channel.channel('my-channel'); channel.bindStore(store, (message) => { const parent = store.getStore(); return new Span(message, parent); }); channel.runStores({ some: 'message' }, () => { store.getStore(); // Span({ some: 'message' }) });
channel.withStoreScope(data)#
Stability: 1 - Experimental
data<any>Message to bind to stores- Returns:
<RunStoresScope>Disposable scope object
Creates a disposable scope that binds the given data to any AsyncLocalStorage instances bound to the channel and publishes it to subscribers. The scope automatically restores the previous storage contexts when disposed.
This method enables the use of JavaScript's explicit resource management
(using syntax with Symbol.dispose) to manage store contexts without
closure wrapping.
import { channel } from 'node:diagnostics_channel'; import { AsyncLocalStorage } from 'node:async_hooks'; const store = new AsyncLocalStorage(); const ch = channel('my-channel'); ch.bindStore(store, (message) => { return { ...message, timestamp: Date.now() }; }); { using scope = ch.withStoreScope({ request: 'data' }); // Store is entered, data is published console.log(store.getStore()); // { request: 'data', timestamp: ... } } // Store is automatically restored on scope exitconst { channel } = require('node:diagnostics_channel'); const { AsyncLocalStorage } = require('node:async_hooks'); const store = new AsyncLocalStorage(); const ch = channel('my-channel'); ch.bindStore(store, (message) => { return { ...message, timestamp: Date.now() }; }); { using scope = ch.withStoreScope({ request: 'data' }); // Store is entered, data is published console.log(store.getStore()); // { request: 'data', timestamp: ... } } // Store is automatically restored on scope exit
Class: RunStoresScope#
Stability: 1 - Experimental
The class RunStoresScope represents a disposable scope created by
channel.withStoreScope(data). It manages the lifecycle of store
contexts and ensures they are properly restored when the scope exits.
The scope must be used with the using syntax to ensure proper disposal.
Class: TracingChannel#
Stability: 2 - Stable
The class TracingChannel is a collection of TracingChannel Channels which
together express a single traceable action. It is used to formalize and
simplify the process of producing events for tracing application flow.
diagnostics_channel.tracingChannel() is used to construct a
TracingChannel. As with Channel it is recommended to create and reuse a
single TracingChannel at the top-level of the file rather than creating them
dynamically.
tracingChannel.subscribe(subscribers)#
subscribers<Object>Set of TracingChannel Channels subscribersstart<Function>Thestartevent subscriberend<Function>Theendevent subscriberasyncStart<Function>TheasyncStartevent subscriberasyncEnd<Function>TheasyncEndevent subscribererror<Function>Theerrorevent subscriber
Helper to subscribe a collection of functions to the corresponding channels.
This is the same as calling channel.subscribe(onMessage) on each channel
individually.
import diagnostics_channel from 'node:diagnostics_channel'; const channels = diagnostics_channel.tracingChannel('my-channel'); channels.subscribe({ start(message) { // Handle start message }, end(message) { // Handle end message }, asyncStart(message) { // Handle asyncStart message }, asyncEnd(message) { // Handle asyncEnd message }, error(message) { // Handle error message }, });const diagnostics_channel = require('node:diagnostics_channel'); const channels = diagnostics_channel.tracingChannel('my-channel'); channels.subscribe({ start(message) { // Handle start message }, end(message) { // Handle end message }, asyncStart(message) { // Handle asyncStart message }, asyncEnd(message) { // Handle asyncEnd message }, error(message) { // Handle error message }, });
tracingChannel.unsubscribe(subscribers)#
subscribers<Object>Set of TracingChannel Channels subscribersstart<Function>Thestartevent subscriberend<Function>Theendevent subscriberasyncStart<Function>TheasyncStartevent subscriberasyncEnd<Function>TheasyncEndevent subscribererror<Function>Theerrorevent subscriber
- Returns:
<boolean>trueif all handlers were successfully unsubscribed, andfalseotherwise.
Helper to unsubscribe a collection of functions from the corresponding channels.
This is the same as calling channel.unsubscribe(onMessage) on each channel
individually.
import diagnostics_channel from 'node:diagnostics_channel'; const channels = diagnostics_channel.tracingChannel('my-channel'); channels.unsubscribe({ start(message) { // Handle start message }, end(message) { // Handle end message }, asyncStart(message) { // Handle asyncStart message }, asyncEnd(message) { // Handle asyncEnd message }, error(message) { // Handle error message }, });const diagnostics_channel = require('node:diagnostics_channel'); const channels = diagnostics_channel.tracingChannel('my-channel'); channels.unsubscribe({ start(message) { // Handle start message }, end(message) { // Handle end message }, asyncStart(message) { // Handle asyncStart message }, asyncEnd(message) { // Handle asyncEnd message }, error(message) { // Handle error message }, });
tracingChannel.traceSync(fn[, context[, thisArg[, ...args]]])#
fn<Function>Function to wrap a trace aroundcontext<Object>Shared object to correlate events throughthisArg<any>The receiver to be used for the function call...args<any>Optional arguments to pass to the function- Returns:
<any>The return value of the given function
Trace a synchronous function call. This will always produce a start event
and end event around the execution and may produce an error event
if the given function throws an error. This will run the given function using
channel.runStores(context, ...) on the start channel which ensures all
events should have any bound stores set to match this trace context.
To ensure only correct trace graphs are formed, events will only be published if subscribers are present prior to starting the trace. Subscriptions which are added after the trace begins will not receive future events from that trace, only future traces will be seen.
import diagnostics_channel from 'node:diagnostics_channel'; const channels = diagnostics_channel.tracingChannel('my-channel'); channels.traceSync(() => { // Do something }, { some: 'thing', });const diagnostics_channel = require('node:diagnostics_channel'); const channels = diagnostics_channel.tracingChannel('my-channel'); channels.traceSync(() => { // Do something }, { some: 'thing', });
tracingChannel.tracePromise(fn[, context[, thisArg[, ...args]]])#
fn<Function>Function to wrap a trace aroundcontext<Object>Shared object to correlate trace events throughthisArg<any>The receiver to be used for the function call...args<any>Optional arguments to pass to the function- Returns:
<any>The return value of the given function. If the return value is a Promise or thenable, tracing events will be published when it settles. If the return value is not a Promise or thenable, it is returned as-is and a warning is emitted.
Trace an asynchronous function call which returns a <Promise> or thenable object. This will always produce a start event and
end event around the synchronous portion of the function execution, and
will produce an asyncStart event and asyncEnd event when the
returned promise is resolved or rejected. It may also produce an
error event if the given function throws an error or the returned promise
is rejected. This will run the given function using
channel.runStores(context, ...) on the start channel which ensures all
events should have any bound stores set to match this trace context.
If the value returned by fn is not a Promise or thenable, then it will be
returned with a warning, and no asyncStart or asyncEnd events will be
produced.
To ensure only correct trace graphs are formed, events will only be published if subscribers are present prior to starting the trace. Subscriptions which are added after the trace begins will not receive future events from that trace, only future traces will be seen.
import diagnostics_channel from 'node:diagnostics_channel'; const channels = diagnostics_channel.tracingChannel('my-channel'); channels.tracePromise(async () => { // Do something }, { some: 'thing', });const diagnostics_channel = require('node:diagnostics_channel'); const channels = diagnostics_channel.tracingChannel('my-channel'); channels.tracePromise(async () => { // Do something }, { some: 'thing', });
tracingChannel.traceCallback(fn[, position[, context[, thisArg[, ...args]]]])#
fn<Function>callback using function to wrap a trace aroundposition<number>Zero-indexed argument position of expected callback (defaults to last argument ifundefinedis passed)context<Object>Shared object to correlate trace events through (defaults to{}ifundefinedis passed)thisArg<any>The receiver to be used for the function call...args<any>arguments to pass to the function (must include the callback)- Returns:
<any>The return value of the given function
Trace a callback-receiving function call. The callback is expected to follow
the error as first arg convention typically used. This will always produce a
start event and end event around the synchronous portion of the
function execution, and will produce a asyncStart event and
asyncEnd event around the callback execution. It may also produce an
error event if the given function throws or the first argument passed to
the callback is set. This will run the given function using
channel.runStores(context, ...) on the start channel which ensures all
events should have any bound stores set to match this trace context.
To ensure only correct trace graphs are formed, events will only be published if subscribers are present prior to starting the trace. Subscriptions which are added after the trace begins will not receive future events from that trace, only future traces will be seen.
import diagnostics_channel from 'node:diagnostics_channel'; const channels = diagnostics_channel.tracingChannel('my-channel'); channels.traceCallback((arg1, callback) => { // Do something callback(null, 'result'); }, 1, { some: 'thing', }, thisArg, arg1, callback);const diagnostics_channel = require('node:diagnostics_channel'); const channels = diagnostics_channel.tracingChannel('my-channel'); channels.traceCallback((arg1, callback) => { // Do something callback(null, 'result'); }, 1, { some: 'thing', }, thisArg, arg1, callback);
The callback will also be run with channel.runStores(context, ...) which
enables context loss recovery in some cases.
import diagnostics_channel from 'node:diagnostics_channel'; import { AsyncLocalStorage } from 'node:async_hooks'; const channels = diagnostics_channel.tracingChannel('my-channel'); const myStore = new AsyncLocalStorage(); // The start channel sets the initial store data to something // and stores that store data value on the trace context object channels.start.bindStore(myStore, (data) => { const span = new Span(data); data.span = span; return span; }); // Then asyncStart can restore from that data it stored previously channels.asyncStart.bindStore(myStore, (data) => { return data.span; });const diagnostics_channel = require('node:diagnostics_channel'); const { AsyncLocalStorage } = require('node:async_hooks'); const channels = diagnostics_channel.tracingChannel('my-channel'); const myStore = new AsyncLocalStorage(); // The start channel sets the initial store data to something // and stores that store data value on the trace context object channels.start.bindStore(myStore, (data) => { const span = new Span(data); data.span = span; return span; }); // Then asyncStart can restore from that data it stored previously channels.asyncStart.bindStore(myStore, (data) => { return data.span; });
tracingChannel.hasSubscribers#
- Returns:
<boolean>trueif any of the individual channels has a subscriber,falseif not.
This is a helper method available on a TracingChannel instance to check if
any of the TracingChannel Channels have subscribers. A true is returned if
any of them have at least one subscriber, a false is returned otherwise.
import diagnostics_channel from 'node:diagnostics_channel'; const channels = diagnostics_channel.tracingChannel('my-channel'); if (channels.hasSubscribers) { // Do something }const diagnostics_channel = require('node:diagnostics_channel'); const channels = diagnostics_channel.tracingChannel('my-channel'); if (channels.hasSubscribers) { // Do something }
Class: BoundedChannel#
Stability: 1 - Experimental
The class BoundedChannel is a simplified version of TracingChannel that
only traces synchronous operations. It consists of two channels (start and
end) instead of five, omitting the asyncStart, asyncEnd, and error
events. This makes it suitable for tracing operations that don't involve
asynchronous continuations or error handling.
Like TracingChannel, it is recommended to create and reuse a single
BoundedChannel at the top-level of the file rather than creating them
dynamically.
boundedChannel.hasSubscribers#
- Returns:
<boolean>trueif any of the individual channels has a subscriber,falseif not.
Check if any of the start or end channels have subscribers.
import { boundedChannel } from 'node:diagnostics_channel'; const wc = boundedChannel('my-operation'); if (wc.hasSubscribers) { // There are subscribers, perform traced operation }const { boundedChannel } = require('node:diagnostics_channel'); const wc = boundedChannel('my-operation'); if (wc.hasSubscribers) { // There are subscribers, perform traced operation }
boundedChannel.subscribe(handlers)#
handlers<Object>Set of channel subscribersstart<Function>The start event subscriberend<Function>The end event subscriber
Subscribe to the bounded channel events. This is equivalent to calling
channel.subscribe(onMessage) on each channel individually.
import { boundedChannel } from 'node:diagnostics_channel'; const wc = boundedChannel('my-operation'); wc.subscribe({ start(message) { // Handle start }, end(message) { // Handle end }, });const { boundedChannel } = require('node:diagnostics_channel'); const wc = boundedChannel('my-operation'); wc.subscribe({ start(message) { // Handle start }, end(message) { // Handle end }, });
boundedChannel.unsubscribe(handlers)#
handlers<Object>Set of channel subscribersstart<Function>The start event subscriberend<Function>The end event subscriber
- Returns:
<boolean>trueif all handlers were successfully unsubscribed,falseotherwise.
Unsubscribe from the bounded channel events. This is equivalent to calling
channel.unsubscribe(onMessage) on each channel individually.
import { boundedChannel } from 'node:diagnostics_channel'; const wc = boundedChannel('my-operation'); const handlers = { start(message) {}, end(message) {}, }; wc.subscribe(handlers); wc.unsubscribe(handlers);const { boundedChannel } = require('node:diagnostics_channel'); const wc = boundedChannel('my-operation'); const handlers = { start(message) {}, end(message) {}, }; wc.subscribe(handlers); wc.unsubscribe(handlers);
boundedChannel.run(context, fn[, thisArg[, ...args]])#
context<Object>Shared object to correlate events throughfn<Function>Function to wrap a trace aroundthisArg<any>The receiver to be used for the function call...args<any>Optional arguments to pass to the function- Returns:
<any>The return value of the given function
Trace a synchronous function call. This will produce a start event and end
event around the execution. This runs the given function using
channel.runStores(context, ...) on the start channel which ensures all
events have any bound stores set to match this trace context.
import { boundedChannel } from 'node:diagnostics_channel'; const wc = boundedChannel('my-operation'); const result = wc.run({ operationId: '123' }, () => { // Perform operation return 42; });const { boundedChannel } = require('node:diagnostics_channel'); const wc = boundedChannel('my-operation'); const result = wc.run({ operationId: '123' }, () => { // Perform operation return 42; });
boundedChannel.withScope([context])#
context<Object>Shared object to correlate events through- Returns:
<BoundedChannelScope>Disposable scope object
Create a disposable scope for tracing a synchronous operation using JavaScript's
explicit resource management (using syntax). The scope automatically publishes
start and end events, enters bound stores, and handles cleanup when disposed.
import { boundedChannel } from 'node:diagnostics_channel'; const wc = boundedChannel('my-operation'); const context = { operationId: '123' }; { using scope = wc.withScope(context); // Stores are entered, start event is published // Perform work and set result on context context.result = 42; } // End event is published, stores are restored automaticallyconst { boundedChannel } = require('node:diagnostics_channel'); const wc = boundedChannel('my-operation'); const context = { operationId: '123' }; { using scope = wc.withScope(context); // Stores are entered, start event is published // Perform work and set result on context context.result = 42; } // End event is published, stores are restored automatically
Class: BoundedChannelScope#
Stability: 1 - Experimental
The class BoundedChannelScope represents a disposable scope created by
boundedChannel.withScope(context). It manages the lifecycle of a traced
operation, automatically publishing events and managing store contexts.
The scope must be used with the using syntax to ensure proper disposal.
import { boundedChannel } from 'node:diagnostics_channel'; const wc = boundedChannel('my-operation'); const context = {}; { using scope = wc.withScope(context); // Start event is published, stores are entered context.result = performOperation(); // End event is automatically published at end of block }const { boundedChannel } = require('node:diagnostics_channel'); const wc = boundedChannel('my-operation'); const context = {}; { using scope = wc.withScope(context); // Start event is published, stores are entered context.result = performOperation(); // End event is automatically published at end of block }
BoundedChannel Channels#
A BoundedChannel consists of two diagnostics channels representing the
lifecycle of a scope created with the using syntax:
tracing:${name}:start- Published when theusingstatement executes (scope creation)tracing:${name}:end- Published when exiting the block (scope disposal)
When using the using syntax with [boundedChannel.withScope([context])][], the start
event is published immediately when the statement executes, and the end event
is automatically published when disposal occurs at the end of the block. All
events share the same context object, which can be extended with additional
properties like result during scope execution.
TracingChannel Channels#
A TracingChannel is a collection of several diagnostics_channels representing
specific points in the execution lifecycle of a single traceable action. The
behavior is split into five diagnostics_channels consisting of start,
end, asyncStart, asyncEnd, and error. A single traceable action will
share the same event object between all events, this can be helpful for
managing correlation through a weakmap.
These event objects will be extended with result or error values when
the task "completes". In the case of a synchronous task the result will be
the return value and the error will be anything thrown from the function.
With callback-based async functions the result will be the second argument
of the callback while the error will either be a thrown error visible in the
end event or the first callback argument in either of the asyncStart or
asyncEnd events.
To ensure only correct trace graphs are formed, events should only be published if subscribers are present prior to starting the trace. Subscriptions which are added after the trace begins should not receive future events from that trace, only future traces will be seen.
Tracing channels should follow a naming pattern of:
tracing:module.class.method:startortracing:module.function:starttracing:module.class.method:endortracing:module.function:endtracing:module.class.method:asyncStartortracing:module.function:asyncStarttracing:module.class.method:asyncEndortracing:module.function:asyncEndtracing:module.class.method:errorortracing:module.function:error
start(event)#
- Name:
tracing:${name}:start
The start event represents the point at which a function is called. At this
point the event data may contain function arguments or anything else available
at the very start of the execution of the function.
end(event)#
- Name:
tracing:${name}:end
The end event represents the point at which a function call returns a value.
In the case of an async function this is when the promise returned not when the
function itself makes a return statement internally. At this point, if the
traced function was synchronous the result field will be set to the return
value of the function. Alternatively, the error field may be present to
represent any thrown errors.
It is recommended to listen specifically to the error event to track errors
as it may be possible for a traceable action to produce multiple errors. For
example, an async task which fails may be started internally before the sync
part of the task then throws an error.
asyncStart(event)#
- Name:
tracing:${name}:asyncStart
The asyncStart event represents the callback or continuation of a traceable
function being reached. At this point things like callback arguments may be
available, or anything else expressing the "result" of the action.
For callbacks-based functions, the first argument of the callback will be
assigned to the error field, if not undefined or null, and the second
argument will be assigned to the result field.
For promises, the argument to the resolve path will be assigned to result
or the argument to the reject path will be assign to error.
It is recommended to listen specifically to the error event to track errors
as it may be possible for a traceable action to produce multiple errors. For
example, an async task which fails may be started internally before the sync
part of the task then throws an error.
asyncEnd(event)#
- Name:
tracing:${name}:asyncEnd
The asyncEnd event represents the callback of an asynchronous function
returning. It's not likely event data will change after the asyncStart event,
however it may be useful to see the point where the callback completes.
error(event)#
- Name:
tracing:${name}:error
The error event represents any error produced by the traceable function
either synchronously or asynchronously. If an error is thrown in the
synchronous portion of the traced function the error will be assigned to the
error field of the event and the error event will be triggered. If an error
is received asynchronously through a callback or promise rejection it will also
be assigned to the error field of the event and trigger the error event.
It is possible for a single traceable function call to produce errors multiple
times so this should be considered when consuming this event. For example, if
another async task is triggered internally which fails and then the sync part
of the function then throws and error two error events will be emitted, one
for the sync error and one for the async error.
Built-in Channels#
Console#
Stability: 1 - Experimental
Event: 'console.log'#
args<any>[]
Emitted when console.log() is called. Receives and array of the arguments
passed to console.log().
Event: 'console.info'#
args<any>[]
Emitted when console.info() is called. Receives and array of the arguments
passed to console.info().
Event: 'console.debug'#
args<any>[]
Emitted when console.debug() is called. Receives and array of the arguments
passed to console.debug().
Event: 'console.warn'#
args<any>[]
Emitted when console.warn() is called. Receives and array of the arguments
passed to console.warn().
Event: 'console.error'#
args<any>[]
Emitted when console.error() is called. Receives and array of the arguments
passed to console.error().
Crypto#
Stability: 1 - Experimental
Event: 'crypto.fips.indicator'#
operation<string>The provider-defined operation type.reason<string>The provider-defined description of why the operation is not approved.blocked<boolean>Whether an indicator callback blocked the operation.count<number>The number of matching pending indicator invocations represented by this message.dropped<number>The number of additional indicator invocations dropped before this message was delivered.
Emitted when the OpenSSL FIPS provider used by Node.js detects an operation that
is not FIPS approved after the corresponding provider check was relaxed. Such
operations are possible when the provider is configured for backwards
compatibility. The operation and reason values come from the provider and
should be treated as opaque strings rather than stable enumerations.
Start Node.js with --enable-fips-indicator-events to enable this channel.
Without the option, subscribing does not install the OpenSSL callback and no
messages are published.
Subscribing to the channel is observation-only and never changes the result of
an operation. Node.js preserves the result from any native indicator callback
installed before Node.js initializes its crypto support. When
--force-fips=strict is used, Node.js rejects callback-indicated
non-approved operations whether or not indicator events are enabled or the
channel has subscribers.
Messages are published asynchronously on the main thread because OpenSSL indicators can originate from Workers or other threads. Only subscriptions on the main thread receive messages. Delivery order relative to the originating operation is not defined, and a message cannot be correlated with a particular call or Worker.
One cryptographic operation can invoke the OpenSSL indicator more than once.
Matching pending invocations are coalesced and reflected in count, which does
not necessarily represent a number of cryptographic operations. At most 256
distinct messages are queued. Additional invocations are reported in dropped
on the first queued message. Queued messages do not keep the event loop active,
so this channel is best-effort diagnostics rather than an authoritative audit
log.
This channel observes the default OpenSSL library context used by Node.js. It
does not observe native addons or other code that uses another OSSL_LIB_CTX
or another copy of libcrypto. It is active with OpenSSL 3.4 and later and is
not available with BoringSSL. A provider configured to reject a check directly,
including a pedantic OpenSSL FIPS provider, can reject an operation without
emitting an indicator. Receiving or not receiving a message does not establish
that Node.js or a cryptographic operation is FIPS validated.
import diagnosticsChannel from 'node:diagnostics_channel';
diagnosticsChannel.subscribe('crypto.fips.indicator', (message) => {
console.error('Non-approved cryptographic operation', message);
});
HTTP#
Stability: 1 - Experimental
Event: 'http.client.request.created'#
request<http.ClientRequest>
Emitted when client creates a request object.
Unlike http.client.request.start, this event is emitted before the request has been sent.
Event: 'http.client.request.start'#
request<http.ClientRequest>
Emitted when client starts a request.
Event: 'http.client.request.error'#
request<http.ClientRequest>error<Error>
Emitted when an error occurs during a client request.
Event: 'http.client.response.finish'#
request<http.ClientRequest>response<http.IncomingMessage>
Emitted when client receives a response.
Event: 'http.server.request.start'#
request<http.IncomingMessage>response<http.ServerResponse>socket<net.Socket>server<http.Server>
Emitted when server receives a request.
Event: 'http.server.response.created'#
request<http.IncomingMessage>response<http.ServerResponse>
Emitted when server creates a response. The event is emitted before the response is sent.
Event: 'http.server.response.finish'#
request<http.IncomingMessage>response<http.ServerResponse>socket<net.Socket>server<http.Server>
Emitted when server sends a response.
HTTP/2#
Stability: 1 - Experimental
Event: 'http2.client.stream.created'#
stream<ClientHttp2Stream>headers<HTTP/2 Headers Object>
Emitted when a stream is created on the client.
Event: 'http2.client.stream.start'#
stream<ClientHttp2Stream>headers<HTTP/2 Headers Object>
Emitted when a stream is started on the client.
Event: 'http2.client.stream.error'#
stream<ClientHttp2Stream>error<Error>
Emitted when an error occurs during the processing of a stream on the client.
Event: 'http2.client.stream.finish'#
stream<ClientHttp2Stream>headers<HTTP/2 Headers Object>flags<number>
Emitted when a stream is received on the client.
Event: 'http2.client.stream.bodyChunkSent'#
stream<ClientHttp2Stream>writev<boolean>data<Buffer>|<string>|<Buffer>[] |<Object>[]encoding<string>
Emitted when a chunk of the client stream body is being sent.
Event: 'http2.client.stream.bodySent'#
stream<ClientHttp2Stream>
Emitted after the client stream body has been fully sent.
Event: 'http2.client.stream.close'#
stream<ClientHttp2Stream>
Emitted when a stream is closed on the client. The HTTP/2 error code used when
closing the stream can be retrieved using the stream.rstCode property.
Event: 'http2.server.stream.created'#
stream<ServerHttp2Stream>headers<HTTP/2 Headers Object>
Emitted when a stream is created on the server.
Event: 'http2.server.stream.start'#
stream<ServerHttp2Stream>headers<HTTP/2 Headers Object>
Emitted when a stream is started on the server.
Event: 'http2.server.stream.error'#
stream<ServerHttp2Stream>error<Error>
Emitted when an error occurs during the processing of a stream on the server.
Event: 'http2.server.stream.finish'#
stream<ServerHttp2Stream>headers<HTTP/2 Headers Object>flags<number>
Emitted when a stream is sent on the server.
Event: 'http2.server.stream.close'#
stream<ServerHttp2Stream>
Emitted when a stream is closed on the server. The HTTP/2 error code used when
closing the stream can be retrieved using the stream.rstCode property.
Modules#
Stability: 1 - Experimental
Event: 'tracing:module.require:start'#
event<Object>containing the following propertiesidArgument passed torequire(). Module name.parentFilenameName of the module that attempted to require(id).
Emitted when require() is executed. See start event.
Event: 'tracing:module.require:end'#
event<Object>containing the following propertiesidArgument passed torequire(). Module name.parentFilenameName of the module that attempted to require(id).
Emitted when a require() call returns. See end event.
Event: 'tracing:module.require:error'#
event<Object>containing the following propertiesidArgument passed torequire(). Module name.parentFilenameName of the module that attempted to require(id).
error<Error>
Emitted when a require() throws an error. See error event.
Event: 'tracing:module.import:asyncStart'#
event<Object>containing the following propertiesidArgument passed toimport(). Module name.parentURLURL object of the module that attempted to import(id).
Emitted when import() is invoked. See asyncStart event.
Event: 'tracing:module.import:asyncEnd'#
event<Object>containing the following propertiesidArgument passed toimport(). Module name.parentURLURL object of the module that attempted to import(id).
Emitted when import() has completed. See asyncEnd event.
Event: 'tracing:module.import:error'#
event<Object>containing the following propertiesidArgument passed toimport(). Module name.parentURLURL object of the module that attempted to import(id).
error<Error>
Emitted when a import() throws an error. See error event.
NET#
Stability: 1 - Experimental
Event: 'net.client.socket'#
socket<net.Socket>|<tls.TLSSocket>
Emitted when a new TCP or pipe client socket connection is created.
Event: 'net.server.socket'#
socket<net.Socket>
Emitted when a new TCP or pipe connection is received.
Event: 'tracing:net.server.listen:asyncStart'#
server<net.Server>options<Object>
Emitted when net.Server.listen() is invoked, before the port or pipe is actually setup.
Event: 'tracing:net.server.listen:asyncEnd'#
server<net.Server>
Emitted when net.Server.listen() has completed and thus the server is ready to accept connection.
Event: 'tracing:net.server.listen:error'#
server<net.Server>error<Error>
Emitted when net.Server.listen() is returning an error.
UDP#
Stability: 1 - Experimental
Event: 'udp.socket'#
socket<dgram.Socket>
Emitted when a new UDP socket is created.
Process#
Stability: 1 - Experimental
Event: 'child_process'#
process<ChildProcess>
Emitted when a new process is created.
tracing:child_process.spawn:start
process<ChildProcess>options<Object>
Emitted when child_process.spawn() is invoked, before the process is
actually spawned.
tracing:child_process.spawn:end
process<ChildProcess>
Emitted when child_process.spawn() has completed successfully and the
process has been created.
tracing:child_process.spawn:error
process<ChildProcess>error<Error>
Emitted when child_process.spawn() encounters an error.
Event: 'process.execve'#
Emitted when process.execve() is invoked.
Web Locks#
Stability: 1 - Experimental
These channels are emitted for each locks.request() call. See
worker_threads.locks for details on Web Locks.
Event: 'locks.request.start'#
name<string>The name of the requested lock resource.mode<string>The lock mode:'exclusive'or'shared'.
Emitted when a lock request is initiated, before the lock is granted.
Event: 'locks.request.grant'#
name<string>The name of the requested lock resource.mode<string>The lock mode:'exclusive'or'shared'.
Emitted when a lock is successfully granted and the callback is about to run.
Event: 'locks.request.miss'#
name<string>The name of the requested lock resource.mode<string>The lock mode:'exclusive'or'shared'.
Emitted when ifAvailable is true and the lock is not immediately available,
and the request callback is invoked with null instead of a Lock object.
Event: 'locks.request.end'#
name<string>The name of the requested lock resource.mode<string>The lock mode:'exclusive'or'shared'.steal<boolean>Whether the request uses steal semantics.ifAvailable<boolean>Whether the request uses ifAvailable semantics.error<Error>|<undefined>The error thrown by the callback, if any.
Emitted when a lock request has finished, whether the callback succeeded, threw an error, or the lock was stolen.
Worker Thread#
Stability: 1 - Experimental
Event: 'worker_threads'#
worker<Worker>
Emitted when a new thread is created.
SQLite#
Stability: 1 - Experimental
Event: 'sqlite.db.query'#
sql<string>The expanded SQL with bound parameter values substituted. If expansion fails, the source SQL with unsubstituted placeholders is used instead.database<Database>TheDatabaseinstance that executed the statement.duration<number>SQLite's internal estimate of the statement run time in nanoseconds. This reflects C-layer execution time only and does not include JavaScript binding overhead such as argument marshaling or result-row construction.
Emitted after a SQL statement finishes executing against a Database
instance. This is a profiling event: it fires once per statement upon
completion and reports an estimated duration from SQLite's internal profiler.
It is not a distributed-tracing span. There is no corresponding start event,
no async context propagation, and no parent-span linkage. If you need
OpenTelemetry-compatible spans or async context propagation, wrap your SQLite
calls with a TracingChannel at the JavaScript layer instead.
Publishing is zero-overhead when there are no subscribers.
No event is emitted for a statement that is abandoned mid-iteration and later
finalized, either explicitly through statement.close() or when the
statement is garbage collected. Subscribers must not close the database or the
statement, since both are still in use while the event is being delivered; see
database.close() and statement.close().
DNS#
Stability: 2 - Stable
The node:dns module enables name resolution. For example, use it to look up IP
addresses of host names.
Although named for the Domain Name System (DNS), it does not always use the
DNS protocol for lookups. dns.lookup() uses the operating system
facilities to perform name resolution. It may not need to perform any network
communication. To perform name resolution the way other applications on the same
system do, use dns.lookup().
import dns from 'node:dns'; dns.lookup('example.org', (err, address, family) => { console.log('address: %j family: IPv%s', address, family); }); // address: "2606:2800:21f:cb07:6820:80da:af6b:8b2c" family: IPv6const dns = require('node:dns'); dns.lookup('example.org', (err, address, family) => { console.log('address: %j family: IPv%s', address, family); }); // address: "2606:2800:21f:cb07:6820:80da:af6b:8b2c" family: IPv6
All other functions in the node:dns module connect to an actual DNS server to
perform name resolution. They will always use the network to perform DNS
queries. These functions do not use the same set of configuration files used by
dns.lookup() (e.g. /etc/hosts). Use these functions to always perform
DNS queries, bypassing other name-resolution facilities.
import dns from 'node:dns'; dns.resolve4('archive.org', (err, addresses) => { if (err) throw err; console.log(`addresses: ${JSON.stringify(addresses)}`); addresses.forEach((a) => { dns.reverse(a, (err, hostnames) => { if (err) { throw err; } console.log(`reverse for ${a}: ${JSON.stringify(hostnames)}`); }); }); });const dns = require('node:dns'); dns.resolve4('archive.org', (err, addresses) => { if (err) throw err; console.log(`addresses: ${JSON.stringify(addresses)}`); addresses.forEach((a) => { dns.reverse(a, (err, hostnames) => { if (err) { throw err; } console.log(`reverse for ${a}: ${JSON.stringify(hostnames)}`); }); }); });
See the Implementation considerations section for more information.
Class: dns.Resolver#
An independent resolver for DNS requests.
Creating a new resolver uses the default server settings. Setting
the servers used for a resolver using
resolver.setServers() does not affect
other resolvers:
import { Resolver } from 'node:dns'; const resolver = new Resolver(); resolver.setServers(['4.4.4.4']); // This request will use the server at 4.4.4.4, independent of global settings. resolver.resolve4('example.org', (err, addresses) => { // ... });const { Resolver } = require('node:dns'); const resolver = new Resolver(); resolver.setServers(['4.4.4.4']); // This request will use the server at 4.4.4.4, independent of global settings. resolver.resolve4('example.org', (err, addresses) => { // ... });
The following methods from the node:dns module are available:
resolver.getServers()resolver.resolve()resolver.resolve4()resolver.resolve6()resolver.resolveAny()resolver.resolveCaa()resolver.resolveCname()resolver.resolveMx()resolver.resolveNaptr()resolver.resolveNs()resolver.resolvePtr()resolver.resolveSoa()resolver.resolveSrv()resolver.resolveTlsa()resolver.resolveTxt()resolver.reverse()resolver.setServers()
Resolver([options])#
Create a new resolver.
resolver.cancel()#
Cancel all outstanding DNS queries made by this resolver. The corresponding
callbacks will be called with an error with code ECANCELLED.
resolver.setLocalAddress([ipv4][, ipv6])#
ipv4<string>A string representation of an IPv4 address. Default:'0.0.0.0'ipv6<string>A string representation of an IPv6 address. Default:'::0'
The resolver instance will send its requests from the specified IP address. This allows programs to specify outbound interfaces when used on multi-homed systems.
If a v4 or v6 address is not specified, it is set to the default and the operating system will choose a local address automatically.
The resolver will use the v4 local address when making requests to IPv4 DNS
servers, and the v6 local address when making requests to IPv6 DNS servers.
The rrtype of resolution requests has no impact on the local address used.
dns.getServers()#
- Returns:
<string>[]
Returns an array of IP address strings, formatted according to RFC 5952, that are currently configured for DNS resolution. A string will include a port section if a custom port is used.
[
"8.8.8.8",
"2001:4860:4860::8888",
"8.8.8.8:1053",
"[2001:4860:4860::8888]:1053",
]
dns.lookup(hostname[, options], callback)#
hostname<string>options<integer>|<Object>family<integer>|<string>The record family. Must be4,6, or0. For backward compatibility reasons,'IPv4'and'IPv6'are interpreted as4and6respectively. The value0indicates that either an IPv4 or IPv6 address is returned. If the value0is used with{ all: true }(see below), either one of or both IPv4 and IPv6 addresses are returned, depending on the system's DNS resolver. Default:0.hints<number>One or more supportedgetaddrinfoflags. Multiple flags may be passed by bitwiseORing their values.all<boolean>Whentrue, the callback returns all resolved addresses in an array. Otherwise, returns a single address. Default:false.order<string>Whenverbatim, the resolved addresses are returned unsorted. Whenipv4first, the resolved addresses are sorted by placing IPv4 addresses before IPv6 addresses. Whenipv6first, the resolved addresses are sorted by placing IPv6 addresses before IPv4 addresses. Default:verbatim(addresses are not reordered). Default value is configurable usingdns.setDefaultResultOrder()or--dns-result-order.verbatim<boolean>Whentrue, the callback receives IPv4 and IPv6 addresses in the order the DNS resolver returned them. Whenfalse, IPv4 addresses are placed before IPv6 addresses. This option will be deprecated in favor oforder. When both are specified,orderhas higher precedence. New code should only useorder. Default:true(addresses are not reordered). Default value is configurable usingdns.setDefaultResultOrder()or--dns-result-order.
callback<Function>err<Error>address<string>A string representation of an IPv4 or IPv6 address. Not provided whenoptions.allistrue.family<integer>4or6, denoting the family ofaddress, or0if the address is not an IPv4 or IPv6 address.0is a likely indicator of a bug in the name resolution service used by the operating system. Not provided whenoptions.allistrue.addresses<Object>[] An array of address objects whenoptions.allistrue. Each object has the following properties:
Resolves a host name (e.g. 'nodejs.org') into the first found A (IPv4) or
AAAA (IPv6) record. All option properties are optional. If options is an
integer, then it must be 4 or 6 – if options is not provided, then
either IPv4 or IPv6 addresses, or both, are returned if found.
With the all option set to true, the arguments for callback change to
(err, addresses), with addresses being an array of objects with the
properties address and family.
On error, err is an Error object, where err.code is the error code.
Keep in mind that err.code will be set to 'ENOTFOUND' not only when
the host name does not exist but also when the lookup fails in other ways
such as no available file descriptors.
dns.lookup() does not necessarily have anything to do with the DNS protocol.
The implementation uses an operating system facility that can associate names
with addresses and vice versa. This implementation can have subtle but
important consequences on the behavior of any Node.js program. Please take some
time to consult the Implementation considerations section before using
dns.lookup().
Example usage:
import dns from 'node:dns'; const options = { family: 6, hints: dns.ADDRCONFIG | dns.V4MAPPED, }; dns.lookup('example.org', options, (err, address, family) => console.log('address: %j family: IPv%s', address, family)); // address: "2606:2800:21f:cb07:6820:80da:af6b:8b2c" family: IPv6 // When options.all is true, the result will be an Array. options.all = true; dns.lookup('example.org', options, (err, addresses) => console.log('addresses: %j', addresses)); // addresses: [{"address":"2606:2800:21f:cb07:6820:80da:af6b:8b2c","family":6}]const dns = require('node:dns'); const options = { family: 6, hints: dns.ADDRCONFIG | dns.V4MAPPED, }; dns.lookup('example.org', options, (err, address, family) => console.log('address: %j family: IPv%s', address, family)); // address: "2606:2800:21f:cb07:6820:80da:af6b:8b2c" family: IPv6 // When options.all is true, the result will be an Array. options.all = true; dns.lookup('example.org', options, (err, addresses) => console.log('addresses: %j', addresses)); // addresses: [{"address":"2606:2800:21f:cb07:6820:80da:af6b:8b2c","family":6}]
If this method is invoked as its util.promisify()ed version, and all
is not set to true, it returns a Promise for an Object with address and
family properties.
Supported getaddrinfo flags#
The following flags can be passed as hints to dns.lookup().
dns.ADDRCONFIG: Limits returned address types to the types of non-loopback addresses configured on the system. For example, IPv4 addresses are only returned if the current system has at least one IPv4 address configured.dns.V4MAPPED: If the IPv6 family was specified, but no IPv6 addresses were found, then return IPv4 mapped IPv6 addresses. It is not supported on some operating systems (e.g. FreeBSD 10.1).dns.ALL: Ifdns.V4MAPPEDis specified, return resolved IPv6 addresses as well as IPv4 mapped IPv6 addresses.
dns.lookupService(address, port, callback)#
address<string>port<number>callback<Function>
Resolves the given address and port into a host name and service using
the operating system's underlying getnameinfo implementation.
If address is not a valid IP address, a TypeError will be thrown.
The port will be coerced to a number. If it is not a legal port, a TypeError
will be thrown.
On an error, err is an Error object, where err.code is the error code.
import dns from 'node:dns'; dns.lookupService('127.0.0.1', 22, (err, hostname, service) => { console.log(hostname, service); // Prints: localhost ssh });const dns = require('node:dns'); dns.lookupService('127.0.0.1', 22, (err, hostname, service) => { console.log(hostname, service); // Prints: localhost ssh });
If this method is invoked as its util.promisify()ed version, it returns a
Promise for an Object with hostname and service properties.
dns.resolve(hostname[, rrtype], callback)#
hostname<string>Host name to resolve.rrtype<string>Resource record type. Default:'A'.callback<Function>
Uses the DNS protocol to resolve a host name (e.g. 'nodejs.org') into an array
of the resource records. The callback function has arguments
(err, records). When successful, records will be an array of resource
records. The type and structure of individual results varies based on rrtype:
rrtype |
records contains |
Result type | Shorthand method |
|---|---|---|---|
'A' |
IPv4 addresses (default) | <string> |
dns.resolve4() |
'AAAA' |
IPv6 addresses | <string> |
dns.resolve6() |
'ANY' |
any records | <Object> |
dns.resolveAny() |
'CAA' |
CA authorization records | <Object> |
dns.resolveCaa() |
'CNAME' |
canonical name records | <string> |
dns.resolveCname() |
'MX' |
mail exchange records | <Object> |
dns.resolveMx() |
'NAPTR' |
name authority pointer records | <Object> |
dns.resolveNaptr() |
'NS' |
name server records | <string> |
dns.resolveNs() |
'PTR' |
pointer records | <string> |
dns.resolvePtr() |
'SOA' |
start of authority records | <Object> |
dns.resolveSoa() |
'SRV' |
service records | <Object> |
dns.resolveSrv() |
'TLSA' |
certificate associations | <Object> |
dns.resolveTlsa() |
'TXT' |
text records | <string>[] |
dns.resolveTxt() |
On error, err is an Error object, where err.code is one of the
DNS error codes.
dns.resolve4(hostname[, options], callback)#
hostname<string>Host name to resolve.options<Object>ttl<boolean>Retrieves the Time-To-Live value (TTL) of each record. Whentrue, the callback receives an array of{ address: '1.2.3.4', ttl: 60 }objects rather than an array of strings, with the TTL expressed in seconds.
callback<Function>
Uses the DNS protocol to resolve an IPv4 addresses (A records) for the
hostname. The addresses argument passed to the callback function
will contain an array of IPv4 addresses (e.g.
['74.125.79.104', '74.125.79.105', '74.125.79.106']).
dns.resolve6(hostname[, options], callback)#
hostname<string>Host name to resolve.options<Object>ttl<boolean>Retrieve the Time-To-Live value (TTL) of each record. Whentrue, the callback receives an array of{ address: '0:1:2:3:4:5:6:7', ttl: 60 }objects rather than an array of strings, with the TTL expressed in seconds.
callback<Function>
Uses the DNS protocol to resolve IPv6 addresses (AAAA records) for the
hostname. The addresses argument passed to the callback function
will contain an array of IPv6 addresses.
dns.resolveAny(hostname, callback)#
hostname<string>callback<Function>
Uses the DNS protocol to resolve all records (also known as ANY or * query).
The ret argument passed to the callback function will be an array containing
various types of records. Each object has a property type that indicates the
type of the current record. And depending on the type, additional properties
will be present on the object:
| Type | Properties |
|---|---|
'A' |
address/ttl |
'AAAA' |
address/ttl |
'CAA' |
Refer to dns.resolveCaa() |
'CNAME' |
value |
'MX' |
Refer to dns.resolveMx() |
'NAPTR' |
Refer to dns.resolveNaptr() |
'NS' |
value |
'PTR' |
value |
'SOA' |
Refer to dns.resolveSoa() |
'SRV' |
Refer to dns.resolveSrv() |
'TLSA' |
Refer to dns.resolveTlsa() |
'TXT' |
This type of record contains an array property called entries which refers to dns.resolveTxt(), e.g. { entries: ['...'], type: 'TXT' } |
Here is an example of the ret object passed to the callback:
[ { type: 'A', address: '127.0.0.1', ttl: 299 },
{ type: 'CNAME', value: 'example.com' },
{ type: 'MX', exchange: 'alt4.aspmx.l.example.com', priority: 50 },
{ type: 'NS', value: 'ns1.example.com' },
{ type: 'TXT', entries: [ 'v=spf1 include:_spf.example.com ~all' ] },
{ type: 'SOA',
nsname: 'ns1.example.com',
hostmaster: 'admin.example.com',
serial: 156696742,
refresh: 900,
retry: 900,
expire: 1800,
minttl: 60 } ];
DNS server operators may choose not to respond to ANY
queries. It may be better to call individual methods like dns.resolve4(),
dns.resolveMx(), and so on. For more details, see RFC 8482.
dns.resolveCname(hostname, callback)#
hostname<string>callback<Function>
Uses the DNS protocol to resolve CNAME records for the hostname. The
addresses argument passed to the callback function
will contain an array of canonical name records available for the hostname
(e.g. ['bar.example.com']).
dns.resolveCaa(hostname, callback)#
hostname<string>callback<Function>
Uses the DNS protocol to resolve CAA records for the hostname. The
addresses argument passed to the callback function
will contain an array of certification authority authorization records
available for the hostname (e.g. [{critical: 0, iodef: 'mailto:pki@example.com'}, {critical: 128, issue: 'pki.example.com'}]).
dns.resolveMx(hostname, callback)#
hostname<string>callback<Function>
Uses the DNS protocol to resolve mail exchange records (MX records) for the
hostname. The addresses argument passed to the callback function will
contain an array of objects containing both a priority and exchange
property (e.g. [{priority: 10, exchange: 'mx.example.com'}, ...]).
dns.resolveNaptr(hostname, callback)#
hostname<string>callback<Function>
Uses the DNS protocol to resolve regular expression-based records (NAPTR
records) for the hostname. The addresses argument passed to the callback
function will contain an array of objects with the following properties:
flagsserviceregexpreplacementorderpreference
({
flags: 's',
service: 'SIP+D2U',
regexp: '',
replacement: '_sip._udp.example.com',
order: 30,
preference: 100,
});
dns.resolveNs(hostname, callback)#
hostname<string>callback<Function>
Uses the DNS protocol to resolve name server records (NS records) for the
hostname. The addresses argument passed to the callback function will
contain an array of name server records available for hostname
(e.g. ['ns1.example.com', 'ns2.example.com']).
dns.resolvePtr(hostname, callback)#
hostname<string>callback<Function>
Uses the DNS protocol to resolve pointer records (PTR records) for the
hostname. The addresses argument passed to the callback function will
be an array of strings containing the reply records.
dns.resolveSoa(hostname, callback)#
hostname<string>callback<Function>
Uses the DNS protocol to resolve a start of authority record (SOA record) for
the hostname. The address argument passed to the callback function will
be an object with the following properties:
nsnamehostmasterserialrefreshretryexpireminttl
({
nsname: 'ns.example.com',
hostmaster: 'root.example.com',
serial: 2013101809,
refresh: 10000,
retry: 2400,
expire: 604800,
minttl: 3600,
});
dns.resolveSrv(hostname, callback)#
hostname<string>callback<Function>
Uses the DNS protocol to resolve service records (SRV records) for the
hostname. The addresses argument passed to the callback function will
be an array of objects with the following properties:
priorityweightportname
({
priority: 10,
weight: 5,
port: 21223,
name: 'service.example.com',
});
dns.resolveTlsa(hostname, callback)#
hostname<string>callback<Function>
Uses the DNS protocol to resolve certificate associations (TLSA records) for
the hostname. The records argument passed to the callback function is an
array of objects with these properties:
certUsageselectormatchdata
({
certUsage: 3,
selector: 1,
match: 1,
data: [ArrayBuffer],
});
dns.resolveTxt(hostname, callback)#
hostname<string>callback<Function>
Uses the DNS protocol to resolve text queries (TXT records) for the
hostname. The records argument passed to the callback function is a
two-dimensional array of the text records available for hostname (e.g.
[ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ]). Each sub-array contains TXT chunks of
one record. Depending on the use case, these could be either joined together or
treated separately.
dns.reverse(ip, callback)#
ip<string>callback<Function>
Performs a reverse DNS query that resolves an IPv4 or IPv6 address to an array of host names.
On error, err is an Error object, where err.code is
one of the DNS error codes.
dns.setDefaultResultOrder(order)#
order<string>must be'ipv4first','ipv6first'or'verbatim'.
Set the default value of order in dns.lookup() and
dnsPromises.lookup(). The value could be:
ipv4first: sets defaultordertoipv4first.ipv6first: sets defaultordertoipv6first.verbatim: sets defaultordertoverbatim.
The default is verbatim and dns.setDefaultResultOrder() have higher
priority than --dns-result-order. When using worker threads,
dns.setDefaultResultOrder() from the main thread won't affect the default
dns orders in workers.
dns.getDefaultResultOrder()#
Get the default value for order in dns.lookup() and
dnsPromises.lookup(). The value could be:
ipv4first: fororderdefaulting toipv4first.ipv6first: fororderdefaulting toipv6first.verbatim: fororderdefaulting toverbatim.
dns.setServers(servers)#
Sets the IP address and port of servers to be used when performing DNS
resolution. The servers argument is an array of RFC 5952 formatted
addresses. If the port is the IANA default DNS port (53) it can be omitted.
dns.setServers([
'8.8.8.8',
'[2001:4860:4860::8888]',
'8.8.8.8:1053',
'[2001:4860:4860::8888]:1053',
]);
An error will be thrown if an invalid address is provided.
The dns.setServers() method must not be called while a DNS query is in
progress.
The dns.setServers() method affects only dns.resolve(),
dns.resolve*() and dns.reverse() (and specifically not
dns.lookup()).
This method works much like
resolve.conf.
That is, if attempting to resolve with the first server provided results in a
NOTFOUND error, the resolve() method will not attempt to resolve with
subsequent servers provided. Fallback DNS servers will only be used if the
earlier ones time out or result in some other error.
DNS promises API#
The dns.promises API provides an alternative set of asynchronous DNS methods
that return Promise objects rather than using callbacks. The API is accessible
via require('node:dns').promises or require('node:dns/promises').
Class: dnsPromises.Resolver#
An independent resolver for DNS requests.
Creating a new resolver uses the default server settings. Setting
the servers used for a resolver using
resolver.setServers() does not affect
other resolvers:
import { Resolver } from 'node:dns/promises'; const resolver = new Resolver(); resolver.setServers(['4.4.4.4']); // This request will use the server at 4.4.4.4, independent of global settings. const addresses = await resolver.resolve4('example.org');const { Resolver } = require('node:dns').promises; const resolver = new Resolver(); resolver.setServers(['4.4.4.4']); // This request will use the server at 4.4.4.4, independent of global settings. resolver.resolve4('example.org').then((addresses) => { // ... }); // Alternatively, the same code can be written using async-await style. (async function() { const addresses = await resolver.resolve4('example.org'); })();
The following methods from the dnsPromises API are available:
resolver.getServers()resolver.resolve()resolver.resolve4()resolver.resolve6()resolver.resolveAny()resolver.resolveCaa()resolver.resolveCname()resolver.resolveMx()resolver.resolveNaptr()resolver.resolveNs()resolver.resolvePtr()resolver.resolveSoa()resolver.resolveSrv()resolver.resolveTlsa()resolver.resolveTxt()resolver.reverse()resolver.setServers()
resolver.cancel()#
Cancel all outstanding DNS queries made by this resolver. The corresponding
promises will be rejected with an error with the code ECANCELLED.
dnsPromises.getServers()#
- Returns:
<string>[]
Returns an array of IP address strings, formatted according to RFC 5952, that are currently configured for DNS resolution. A string will include a port section if a custom port is used.
[
"8.8.8.8",
"2001:4860:4860::8888",
"8.8.8.8:1053",
"[2001:4860:4860::8888]:1053"
]
dnsPromises.lookup(hostname[, options])#
hostname<string>options<integer>|<Object>family<integer>The record family. Must be4,6, or0. The value0indicates that either an IPv4 or IPv6 address is returned. If the value0is used with{ all: true }(see below), either one of or both IPv4 and IPv6 addresses are returned, depending on the system's DNS resolver. Default:0.hints<number>One or more supportedgetaddrinfoflags. Multiple flags may be passed by bitwiseORing their values.all<boolean>Whentrue, thePromiseis resolved with all addresses in an array. Otherwise, returns a single address. Default:false.order<string>Whenverbatim, thePromiseis resolved with IPv4 and IPv6 addresses in the order the DNS resolver returned them. Whenipv4first, IPv4 addresses are placed before IPv6 addresses. Whenipv6first, IPv6 addresses are placed before IPv4 addresses. Default:verbatim(addresses are not reordered). Default value is configurable usingdns.setDefaultResultOrder()or--dns-result-order. New code should use{ order: 'verbatim' }.verbatim<boolean>Whentrue, thePromiseis resolved with IPv4 and IPv6 addresses in the order the DNS resolver returned them. Whenfalse, IPv4 addresses are placed before IPv6 addresses. This option will be deprecated in favor oforder. When both are specified,orderhas higher precedence. New code should only useorder. Default:true(addresses are not reordered). Default value is configurable usingdns.setDefaultResultOrder()or--dns-result-order.
Resolves a host name (e.g. 'nodejs.org') into the first found A (IPv4) or
AAAA (IPv6) record. All option properties are optional. If options is an
integer, then it must be 4 or 6 – if options is not provided, then
either IPv4 or IPv6 addresses, or both, are returned if found.
With the all option set to true, the Promise is resolved with addresses
being an array of objects with the properties address and family.
On error, the Promise is rejected with an Error object, where err.code
is the error code.
Keep in mind that err.code will be set to 'ENOTFOUND' not only when
the host name does not exist but also when the lookup fails in other ways
such as no available file descriptors.
dnsPromises.lookup() does not necessarily have anything to do with the DNS
protocol. The implementation uses an operating system facility that can
associate names with addresses and vice versa. This implementation can have
subtle but important consequences on the behavior of any Node.js program. Please
take some time to consult the Implementation considerations section before
using dnsPromises.lookup().
Example usage:
import dns from 'node:dns'; const dnsPromises = dns.promises; const options = { family: 6, hints: dns.ADDRCONFIG | dns.V4MAPPED, }; await dnsPromises.lookup('example.org', options).then((result) => { console.log('address: %j family: IPv%s', result.address, result.family); // address: "2606:2800:21f:cb07:6820:80da:af6b:8b2c" family: IPv6 }); // When options.all is true, the result will be an Array. options.all = true; await dnsPromises.lookup('example.org', options).then((result) => { console.log('addresses: %j', result); // addresses: [{"address":"2606:2800:21f:cb07:6820:80da:af6b:8b2c","family":6}] });const dns = require('node:dns'); const dnsPromises = dns.promises; const options = { family: 6, hints: dns.ADDRCONFIG | dns.V4MAPPED, }; dnsPromises.lookup('example.org', options).then((result) => { console.log('address: %j family: IPv%s', result.address, result.family); // address: "2606:2800:21f:cb07:6820:80da:af6b:8b2c" family: IPv6 }); // When options.all is true, the result will be an Array. options.all = true; dnsPromises.lookup('example.org', options).then((result) => { console.log('addresses: %j', result); // addresses: [{"address":"2606:2800:21f:cb07:6820:80da:af6b:8b2c","family":6}] });
dnsPromises.lookupService(address, port)#
Resolves the given address and port into a host name and service using
the operating system's underlying getnameinfo implementation.
If address is not a valid IP address, a TypeError will be thrown.
The port will be coerced to a number. If it is not a legal port, a TypeError
will be thrown.
On error, the Promise is rejected with an Error object, where err.code
is the error code.
import dnsPromises from 'node:dns/promises'; const result = await dnsPromises.lookupService('127.0.0.1', 22); console.log(result.hostname, result.service); // Prints: localhost sshconst dnsPromises = require('node:dns').promises; dnsPromises.lookupService('127.0.0.1', 22).then((result) => { console.log(result.hostname, result.service); // Prints: localhost ssh });
dnsPromises.resolve(hostname[, rrtype])#
Uses the DNS protocol to resolve a host name (e.g. 'nodejs.org') into an array
of the resource records. When successful, the Promise is resolved with an
array of resource records. The type and structure of individual results vary
based on rrtype:
rrtype |
records contains |
Result type | Shorthand method |
|---|---|---|---|
'A' |
IPv4 addresses (default) | <string> |
dnsPromises.resolve4() |
'AAAA' |
IPv6 addresses | <string> |
dnsPromises.resolve6() |
'ANY' |
any records | <Object> |
dnsPromises.resolveAny() |
'CAA' |
CA authorization records | <Object> |
dnsPromises.resolveCaa() |
'CNAME' |
canonical name records | <string> |
dnsPromises.resolveCname() |
'MX' |
mail exchange records | <Object> |
dnsPromises.resolveMx() |
'NAPTR' |
name authority pointer records | <Object> |
dnsPromises.resolveNaptr() |
'NS' |
name server records | <string> |
dnsPromises.resolveNs() |
'PTR' |
pointer records | <string> |
dnsPromises.resolvePtr() |
'SOA' |
start of authority records | <Object> |
dnsPromises.resolveSoa() |
'SRV' |
service records | <Object> |
dnsPromises.resolveSrv() |
'TLSA' |
certificate associations | <Object> |
dnsPromises.resolveTlsa() |
'TXT' |
text records | <string>[] |
dnsPromises.resolveTxt() |
On error, the Promise is rejected with an Error object, where err.code
is one of the DNS error codes.
dnsPromises.resolve4(hostname[, options])#
hostname<string>Host name to resolve.options<Object>ttl<boolean>Retrieve the Time-To-Live value (TTL) of each record. Whentrue, thePromiseis resolved with an array of{ address: '1.2.3.4', ttl: 60 }objects rather than an array of strings, with the TTL expressed in seconds.
Uses the DNS protocol to resolve IPv4 addresses (A records) for the
hostname. On success, the Promise is resolved with an array of IPv4
addresses (e.g. ['74.125.79.104', '74.125.79.105', '74.125.79.106']).
dnsPromises.resolve6(hostname[, options])#
hostname<string>Host name to resolve.options<Object>ttl<boolean>Retrieve the Time-To-Live value (TTL) of each record. Whentrue, thePromiseis resolved with an array of{ address: '0:1:2:3:4:5:6:7', ttl: 60 }objects rather than an array of strings, with the TTL expressed in seconds.
Uses the DNS protocol to resolve IPv6 addresses (AAAA records) for the
hostname. On success, the Promise is resolved with an array of IPv6
addresses.
dnsPromises.resolveAny(hostname)#
hostname<string>
Uses the DNS protocol to resolve all records (also known as ANY or * query).
On success, the Promise is resolved with an array containing various types of
records. Each object has a property type that indicates the type of the
current record. And depending on the type, additional properties will be
present on the object:
| Type | Properties |
|---|---|
'A' |
address/ttl |
'AAAA' |
address/ttl |
'CAA' |
Refer to dnsPromises.resolveCaa() |
'CNAME' |
value |
'MX' |
Refer to dnsPromises.resolveMx() |
'NAPTR' |
Refer to dnsPromises.resolveNaptr() |
'NS' |
value |
'PTR' |
value |
'SOA' |
Refer to dnsPromises.resolveSoa() |
'SRV' |
Refer to dnsPromises.resolveSrv() |
'TLSA' |
Refer to dnsPromises.resolveTlsa() |
'TXT' |
This type of record contains an array property called entries which refers to dnsPromises.resolveTxt(), e.g. { entries: ['...'], type: 'TXT' } |
Here is an example of the result object:
[ { type: 'A', address: '127.0.0.1', ttl: 299 },
{ type: 'CNAME', value: 'example.com' },
{ type: 'MX', exchange: 'alt4.aspmx.l.example.com', priority: 50 },
{ type: 'NS', value: 'ns1.example.com' },
{ type: 'TXT', entries: [ 'v=spf1 include:_spf.example.com ~all' ] },
{ type: 'SOA',
nsname: 'ns1.example.com',
hostmaster: 'admin.example.com',
serial: 156696742,
refresh: 900,
retry: 900,
expire: 1800,
minttl: 60 } ];
dnsPromises.resolveCaa(hostname)#
hostname<string>
Uses the DNS protocol to resolve CAA records for the hostname. On success,
the Promise is resolved with an array of objects containing available
certification authority authorization records available for the hostname
(e.g. [{critical: 0, iodef: 'mailto:pki@example.com'},{critical: 128, issue: 'pki.example.com'}]).
dnsPromises.resolveCname(hostname)#
hostname<string>
Uses the DNS protocol to resolve CNAME records for the hostname. On success,
the Promise is resolved with an array of canonical name records available for
the hostname (e.g. ['bar.example.com']).
dnsPromises.resolveMx(hostname)#
hostname<string>
Uses the DNS protocol to resolve mail exchange records (MX records) for the
hostname. On success, the Promise is resolved with an array of objects
containing both a priority and exchange property (e.g.
[{priority: 10, exchange: 'mx.example.com'}, ...]).
dnsPromises.resolveNaptr(hostname)#
hostname<string>
Uses the DNS protocol to resolve regular expression-based records (NAPTR
records) for the hostname. On success, the Promise is resolved with an array
of objects with the following properties:
flagsserviceregexpreplacementorderpreference
({
flags: 's',
service: 'SIP+D2U',
regexp: '',
replacement: '_sip._udp.example.com',
order: 30,
preference: 100,
});
dnsPromises.resolveNs(hostname)#
hostname<string>
Uses the DNS protocol to resolve name server records (NS records) for the
hostname. On success, the Promise is resolved with an array of name server
records available for hostname (e.g.
['ns1.example.com', 'ns2.example.com']).
dnsPromises.resolvePtr(hostname)#
hostname<string>
Uses the DNS protocol to resolve pointer records (PTR records) for the
hostname. On success, the Promise is resolved with an array of strings
containing the reply records.
dnsPromises.resolveSoa(hostname)#
hostname<string>
Uses the DNS protocol to resolve a start of authority record (SOA record) for
the hostname. On success, the Promise is resolved with an object with the
following properties:
nsnamehostmasterserialrefreshretryexpireminttl
({
nsname: 'ns.example.com',
hostmaster: 'root.example.com',
serial: 2013101809,
refresh: 10000,
retry: 2400,
expire: 604800,
minttl: 3600,
});
dnsPromises.resolveSrv(hostname)#
hostname<string>
Uses the DNS protocol to resolve service records (SRV records) for the
hostname. On success, the Promise is resolved with an array of objects with
the following properties:
priorityweightportname
({
priority: 10,
weight: 5,
port: 21223,
name: 'service.example.com',
});
dnsPromises.resolveTlsa(hostname)#
hostname<string>
Uses the DNS protocol to resolve certificate associations (TLSA records) for
the hostname. On success, the Promise is resolved with an array of objects
with these properties:
certUsageselectormatchdata
({
certUsage: 3,
selector: 1,
match: 1,
data: [ArrayBuffer],
});
dnsPromises.resolveTxt(hostname)#
hostname<string>
Uses the DNS protocol to resolve text queries (TXT records) for the
hostname. On success, the Promise is resolved with a two-dimensional array
of the text records available for hostname (e.g.
[ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ]). Each sub-array contains TXT chunks of
one record. Depending on the use case, these could be either joined together or
treated separately.
dnsPromises.reverse(ip)#
ip<string>
Performs a reverse DNS query that resolves an IPv4 or IPv6 address to an array of host names.
On error, the Promise is rejected with an Error object, where err.code
is one of the DNS error codes.
dnsPromises.setDefaultResultOrder(order)#
order<string>must be'ipv4first','ipv6first'or'verbatim'.
Set the default value of order in dns.lookup() and
dnsPromises.lookup(). The value could be:
ipv4first: sets defaultordertoipv4first.ipv6first: sets defaultordertoipv6first.verbatim: sets defaultordertoverbatim.
The default is verbatim and dnsPromises.setDefaultResultOrder() have
higher priority than --dns-result-order. When using worker threads,
dnsPromises.setDefaultResultOrder() from the main thread won't affect the
default dns orders in workers.
dnsPromises.getDefaultResultOrder()#
Get the value of dnsOrder.
dnsPromises.setServers(servers)#
Sets the IP address and port of servers to be used when performing DNS
resolution. The servers argument is an array of RFC 5952 formatted
addresses. If the port is the IANA default DNS port (53) it can be omitted.
dnsPromises.setServers([
'8.8.8.8',
'[2001:4860:4860::8888]',
'8.8.8.8:1053',
'[2001:4860:4860::8888]:1053',
]);
An error will be thrown if an invalid address is provided.
The dnsPromises.setServers() method must not be called while a DNS query is in
progress.
This method works much like
resolve.conf.
That is, if attempting to resolve with the first server provided results in a
NOTFOUND error, the resolve() method will not attempt to resolve with
subsequent servers provided. Fallback DNS servers will only be used if the
earlier ones time out or result in some other error.
Error codes#
Each DNS query can return one of the following error codes:
dns.NODATA: DNS server returned an answer with no data.dns.FORMERR: DNS server claims query was misformatted.dns.SERVFAIL: DNS server returned general failure.dns.NOTFOUND: Domain name not found.dns.NOTIMP: DNS server does not implement the requested operation.dns.REFUSED: DNS server refused query.dns.BADQUERY: Misformatted DNS query.dns.BADNAME: Misformatted host name.dns.BADFAMILY: Unsupported address family.dns.BADRESP: Misformatted DNS reply.dns.CONNREFUSED: Could not contact DNS servers.dns.TIMEOUT: Timeout while contacting DNS servers.dns.EOF: End of file.dns.FILE: Error reading file.dns.NOMEM: Out of memory.dns.DESTRUCTION: Channel is being destroyed.dns.BADSTR: Misformatted string.dns.BADFLAGS: Illegal flags specified.dns.NONAME: Given host name is not numeric.dns.BADHINTS: Illegal hints flags specified.dns.NOTINITIALIZED: c-ares library initialization not yet performed.dns.LOADIPHLPAPI: Error loadingiphlpapi.dll.dns.ADDRGETNETWORKPARAMS: Could not findGetNetworkParamsfunction.dns.CANCELLED: DNS query cancelled.
The dnsPromises API also exports the above error codes, e.g., dnsPromises.NODATA.
Implementation considerations#
Although dns.lookup() and the various dns.resolve*()/dns.reverse()
functions have the same goal of associating a network name with a network
address (or vice versa), their behavior is quite different. These differences
can have subtle but significant consequences on the behavior of Node.js
programs.
dns.lookup()#
Under the hood, dns.lookup() uses the same operating system facilities
as most other programs. For instance, dns.lookup() will almost always
resolve a given name the same way as the ping command. On most POSIX-like
operating systems, the behavior of the dns.lookup() function can be
modified by changing settings in nsswitch.conf(5) and/or resolv.conf(5),
but changing these files will change the behavior of all other
programs running on the same operating system.
Though the call to dns.lookup() will be asynchronous from JavaScript's
perspective, it is implemented as a synchronous call to getaddrinfo(3) that runs
on libuv's threadpool. This can have surprising negative performance
implications for some applications, see the UV_THREADPOOL_SIZE
documentation for more information.
Various networking APIs will call dns.lookup() internally to resolve
host names. If that is an issue, consider resolving the host name to an address
using dns.resolve() and using the address instead of a host name. Also, some
networking APIs (such as socket.connect() and dgram.createSocket())
allow the default resolver, dns.lookup(), to be replaced.
dns.resolve(), dns.resolve*(), and dns.reverse()#
These functions are implemented quite differently than dns.lookup(). They
do not use getaddrinfo(3) and they always perform a DNS query on the
network. This network communication is always done asynchronously and does not
use libuv's threadpool.
As a result, these functions cannot have the same negative impact on other
processing that happens on libuv's threadpool that dns.lookup() can have.
They do not use the same set of configuration files that dns.lookup()
uses. For instance, they do not use the configuration from /etc/hosts.
Domain#
Stability: 0 - Deprecated
This module is pending deprecation. Once a replacement API has been finalized, this module will be fully deprecated. Most developers should not have cause to use this module. Users who absolutely must have the functionality that domains provide may rely on it for the time being but should expect to have to migrate to a different solution in the future.
Domains provide a way to handle multiple different IO operations as a
single group. If any of the event emitters or callbacks registered to a
domain emit an 'error' event, or throw an error, then the domain object
will be notified, rather than losing the context of the error in the
process.on('uncaughtException') handler, or causing the program to
exit immediately with an error code.
Warning: Don't ignore errors!#
Domain error handlers are not a substitute for closing down a process when an error occurs.
By the very nature of how throw works in JavaScript, there is almost
never any way to safely "pick up where it left off", without leaking
references, or creating some other sort of undefined brittle state.
The safest way to respond to a thrown error is to shut down the process. Of course, in a normal web server, there may be many open connections, and it is not reasonable to abruptly shut those down because an error was triggered by someone else.
The better approach is to send an error response to the request that triggered the error, while letting the others finish in their normal time, and stop listening for new requests in that worker.
In this way, domain usage goes hand-in-hand with the cluster module,
since the primary process can fork a new worker when a worker
encounters an error. For Node.js programs that scale to multiple
machines, the terminating proxy or service registry can take note of
the failure, and react accordingly.
For example, this is not a good idea:
// XXX WARNING! BAD IDEA!
const d = require('node:domain').create();
d.on('error', (er) => {
// The error won't crash the process, but what it does is worse!
// Though we've prevented abrupt process restarting, we are leaking
// a lot of resources if this ever happens.
// This is no better than process.on('uncaughtException')!
console.log(`error, but oh well ${er.message}`);
});
d.run(() => {
require('node:http').createServer((req, res) => {
handleRequest(req, res);
}).listen(PORT);
});
By using the context of a domain, and the resilience of separating our program into multiple worker processes, we can react more appropriately, and handle errors with much greater safety.
// Much better!
const cluster = require('node:cluster');
const PORT = +process.env.PORT || 1337;
if (cluster.isPrimary) {
// A more realistic scenario would have more than 2 workers,
// and perhaps not put the primary and worker in the same file.
//
// It is also possible to get a bit fancier about logging, and
// implement whatever custom logic is needed to prevent DoS
// attacks and other bad behavior.
//
// See the options in the cluster documentation.
//
// The important thing is that the primary does very little,
// increasing our resilience to unexpected errors.
cluster.fork();
cluster.fork();
cluster.on('disconnect', (worker) => {
console.error('disconnect!');
cluster.fork();
});
} else {
// the worker
//
// This is where we put our bugs!
const domain = require('node:domain');
// See the cluster documentation for more details about using
// worker processes to serve requests. How it works, caveats, etc.
const server = require('node:http').createServer((req, res) => {
const d = domain.create();
d.on('error', (er) => {
console.error(`error ${er.stack}`);
// We're in dangerous territory!
// By definition, something unexpected occurred,
// which we probably didn't want.
// Anything can happen now! Be very careful!
try {
// Make sure we close down within 30 seconds
const killtimer = setTimeout(() => {
process.exit(1);
}, 30000);
// But don't keep the process open just for that!
killtimer.unref();
// Stop taking new requests.
server.close();
// Let the primary know we're dead. This will trigger a
// 'disconnect' in the cluster primary, and then it will fork
// a new worker.
cluster.worker.disconnect();
// Try to send an error to the request that triggered the problem
res.statusCode = 500;
res.setHeader('content-type', 'text/plain');
res.end('Oops, there was a problem!\n');
} catch (er2) {
// Oh well, not much we can do at this point.
console.error(`Error sending 500! ${er2.stack}`);
}
});
// Because req and res were created before this domain existed,
// we need to explicitly add them.
// See the explanation of implicit vs explicit binding below.
d.add(req);
d.add(res);
// Now run the handler function in the domain.
d.run(() => {
handleRequest(req, res);
});
});
server.listen(PORT);
}
// This part is not important. Just an example routing thing.
// Put fancy application logic here.
function handleRequest(req, res) {
switch (req.url) {
case '/error':
// We do some async stuff, and then...
setTimeout(() => {
// Whoops!
flerb.bark();
}, timeout);
break;
default:
res.end('ok');
}
}
Additions to Error objects#
Any time an Error object is routed through a domain, a few extra fields
are added to it.
error.domainThe domain that first handled the error.error.domainEmitterThe event emitter that emitted an'error'event with the error object.error.domainBoundThe callback function which was bound to the domain, and passed an error as its first argument.error.domainThrownA boolean indicating whether the error was thrown, emitted, or passed to a bound callback function.
Implicit binding#
If domains are in use, then all new EventEmitter objects (including
Stream objects, requests, responses, etc.) will be implicitly bound to
the active domain at the time of their creation.
Additionally, callbacks passed to low-level event loop requests (such as
to fs.open(), or other callback-taking methods) will automatically be
bound to the active domain. If they throw, then the domain will catch
the error.
In order to prevent excessive memory usage, Domain objects themselves
are not implicitly added as children of the active domain. If they
were, then it would be too easy to prevent request and response objects
from being properly garbage collected.
To nest Domain objects as children of a parent Domain they must be
explicitly added.
Implicit binding routes thrown errors and 'error' events to the
Domain's 'error' event, but does not register the EventEmitter on the
Domain.
Implicit binding only takes care of thrown errors and 'error' events.
Explicit binding#
Sometimes, the domain in use is not the one that ought to be used for a specific event emitter. Or, the event emitter could have been created in the context of one domain, but ought to instead be bound to some other domain.
For example, there could be one domain in use for an HTTP server, but perhaps we would like to have a separate domain to use for each request.
That is possible via explicit binding.
// Create a top-level domain for the server
const domain = require('node:domain');
const http = require('node:http');
const serverDomain = domain.create();
serverDomain.run(() => {
// Server is created in the scope of serverDomain
http.createServer((req, res) => {
// Req and res are also created in the scope of serverDomain
// however, we'd prefer to have a separate domain for each request.
// create it first thing, and add req and res to it.
const reqd = domain.create();
reqd.add(req);
reqd.add(res);
reqd.on('error', (er) => {
console.error('Error', er, req.url);
try {
res.writeHead(500);
res.end('Error occurred, sorry.');
} catch (er2) {
console.error('Error sending 500', er2, req.url);
}
});
}).listen(1337);
});
domain.create()#
- Returns:
<Domain>
Class: Domain#
- Extends:
<EventEmitter>
The Domain class encapsulates the functionality of routing errors and
uncaught exceptions to the active Domain object.
To handle the errors that it catches, listen to its 'error' event.
domain.members#
- Type:
<Array>
An array of event emitters that have been explicitly added to the domain.
domain.add(emitter)#
emitter<EventEmitter>emitter to be added to the domain
Explicitly adds an emitter to the domain. If any event handlers called by
the emitter throw an error, or if the emitter emits an 'error' event, it
will be routed to the domain's 'error' event, just like with implicit
binding.
If the EventEmitter was already bound to a domain, it is removed from that
one, and bound to this one instead.
domain.bind(callback)#
callback<Function>The callback function- Returns:
<Function>The bound function
The returned function will be a wrapper around the supplied callback
function. When the returned function is called, any errors that are
thrown will be routed to the domain's 'error' event.
const d = domain.create();
function readSomeFile(filename, cb) {
fs.readFile(filename, 'utf8', d.bind((er, data) => {
// If this throws, it will also be passed to the domain.
return cb(er, data ? JSON.parse(data) : null);
}));
}
d.on('error', (er) => {
// An error occurred somewhere. If we throw it now, it will crash the program
// with the normal line number and stack message.
});
domain.enter()#
The enter() method is plumbing used by the run(), bind(), and
intercept() methods to set the active domain. It sets domain.active and
process.domain to the domain, and implicitly pushes the domain onto the domain
stack managed by the domain module (see domain.exit() for details on the
domain stack). The call to enter() delimits the beginning of a chain of
asynchronous calls and I/O operations bound to a domain.
Calling enter() changes only the active domain, and does not alter the domain
itself. enter() and exit() can be called an arbitrary number of times on a
single domain.
domain.exit()#
The exit() method exits the current domain, popping it off the domain stack.
Any time execution is going to switch to the context of a different chain of
asynchronous calls, it's important to ensure that the current domain is exited.
The call to exit() delimits either the end of or an interruption to the chain
of asynchronous calls and I/O operations bound to a domain.
If there are multiple, nested domains bound to the current execution context,
exit() will exit any domains nested within this domain.
Calling exit() changes only the active domain, and does not alter the domain
itself. enter() and exit() can be called an arbitrary number of times on a
single domain.
domain.intercept(callback)#
callback<Function>The callback function- Returns:
<Function>The intercepted function
This method is almost identical to domain.bind(callback). However, in
addition to catching thrown errors, it will also intercept Error
objects sent as the first argument to the function.
In this way, the common if (err) return callback(err); pattern can be replaced
with a single error handler in a single place.
const d = domain.create();
function readSomeFile(filename, cb) {
fs.readFile(filename, 'utf8', d.intercept((data) => {
// Note, the first argument is never passed to the
// callback since it is assumed to be the 'Error' argument
// and thus intercepted by the domain.
// If this throws, it will also be passed to the domain
// so the error-handling logic can be moved to the 'error'
// event on the domain instead of being repeated throughout
// the program.
return cb(null, JSON.parse(data));
}));
}
d.on('error', (er) => {
// An error occurred somewhere. If we throw it now, it will crash the program
// with the normal line number and stack message.
});
domain.remove(emitter)#
emitter<EventEmitter>emitter to be removed from the domain
The opposite of domain.add(emitter). Removes domain handling from the
specified emitter.
domain.run(fn[, ...args])#
fn<Function>...args<any>
Run the supplied function in the context of the domain, implicitly binding all event emitters, timers, and low-level requests that are created in that context. Optionally, arguments can be passed to the function.
This is the most basic way to use a domain.
const domain = require('node:domain');
const fs = require('node:fs');
const d = domain.create();
d.on('error', (er) => {
console.error('Caught error!', er);
});
d.run(() => {
process.nextTick(() => {
setTimeout(() => { // Simulating some various async stuff
fs.open('non-existent file', 'r', (er, fd) => {
if (er) throw er;
// proceed...
});
}, 100);
});
});
In this example, the d.on('error') handler will be triggered, rather
than crashing the program.
Domains and promises#
As of Node.js 8.0.0, the handlers of promises are run inside the domain in
which the call to .then() or .catch() itself was made:
const d1 = domain.create();
const d2 = domain.create();
let p;
d1.run(() => {
p = Promise.resolve(42);
});
d2.run(() => {
p.then((v) => {
// running in d2
});
});
A callback may be bound to a specific domain using domain.bind(callback):
const d1 = domain.create();
const d2 = domain.create();
let p;
d1.run(() => {
p = Promise.resolve(42);
});
d2.run(() => {
p.then(p.domain.bind((v) => {
// running in d1
}));
});
Domains will not interfere with the error handling mechanisms for
promises. In other words, no 'error' event will be emitted for unhandled
Promise rejections.
DTLS#
Stability: 1.1 - Active Development
The node:dtls module provides an implementation of the Datagram Transport
Layer Security (DTLS) protocol over UDP. DTLS provides TLS-equivalent
security guarantees for datagram-based communication, including
confidentiality, integrity, and authentication.
To use this module, it must be enabled at build time with the
--experimental-dtls configure flag and at runtime with the
--experimental-dtls CLI flag.
import { listen, connect } from 'node:dtls';const { listen, connect } = require('node:dtls');
Permission model#
When using the Permission Model, the --allow-net flag must be passed to
allow DTLS network operations. Without it, calling dtls.connect() or
dtls.listen() will throw an ERR_ACCESS_DENIED error.
node --permission --allow-fs-read=* --experimental-dtls index.mjs
Error: Access to this API has been restricted. Use --allow-net to manage permissions.
code: 'ERR_ACCESS_DENIED',
permission: 'Net',
}
Creating a DTLSEndpoint instance without connecting or listening
is permitted even without --allow-net, since no network I/O occurs until
dtls.connect() or dtls.listen() is called.
DTLS vs TLS#
DTLS is designed for UDP transport and differs from TLS in several key ways:
- No stream guarantees: Messages may arrive out of order or be lost. DTLS preserves datagram semantics.
- One socket, many peers: A single UDP socket can serve multiple DTLS
sessions. The
DTLSEndpointmanages this multiplexing. - Cookie exchange: DTLS servers use a stateless cookie mechanism (HelloVerifyRequest) to prevent denial-of-service amplification attacks.
- Retransmission: DTLS handles handshake retransmission internally since UDP does not guarantee delivery.
dtls.listen(callback, options)#
callback<Function>Called for each new DTLS session accepted by the server.session{DTLSSession} The new session.
options<Object>cert<string>|<Buffer>Server certificate in PEM format. Required.key<string>|<Buffer>Server private key in PEM format. Required.secureContext{DTLSSecureContext} A context fromdtls.createSecureContext()to use instead of building one from the credential options below. Must have been created withisServer: true. Cannot be combined with any option the context already carries.sni<Object>|<Function>Server Name Indication. A map of host names to the identity to serve them with, or a function returning one. Cannot be combined withsecureContext; set it on the context instead. See Server Name Indication.passphrase<string>Passphrase to decryptkey, if it is encrypted. Ignored whenkeyis not encrypted. Unlikekeyandcert, this must be a string, matchingtls.createSecureContext().port<number>Port to bind to. Required.host<string>Address to bind to. Default:'0.0.0.0'.ca<string>|<Buffer>|<string>[] |<Buffer>[] CA certificates in PEM format.ciphers<string>OpenSSL cipher list string.alpn<string>[] |<Buffer>ALPN protocol names. Each name must be between 1 and 255 bytes. ABuffermust already be in ALPN wire format: one length byte followed by that many bytes, repeated.srtp<string>Colon-separated SRTP protection profile names (e.g.,'SRTP_AES128_CM_SHA1_80:SRTP_AEAD_AES_128_GCM').requestCert<boolean>Request a certificate from the client. Default:false.rejectUnauthorized<boolean>Only has an effect together withrequestCert. Whentrue, a client that presents no certificate, or one that does not chain to a trusted CA, is rejected during the handshake and receives a TLS alert. Whenfalse, the certificate is still requested and verified but the handshake completes regardless, leaving the decision to the application viasession.authorized. Default:true.mtu<number>Maximum size in bytes of a DTLS datagram. Default:1200.handshakeTimeout<number>Milliseconds a handshake may take before it is abandoned.0disables it. Default:60000. See Handshake timeout.ipv6Only<boolean>Whentrue, an IPv6 endpoint serves IPv6 only. Whenfalse, binding'::'also accepts IPv4 peers, which arrive with mapped addresses such as'::ffff:203.0.113.1'-- anything keyed on the peer address, includingmaxSessionsPerHost, sees them in that form. Has no effect on an IPv4 endpoint. Default:false.reusePort<boolean>Whentrue, setsSO_REUSEPORT, so several processes may bind the same port and the kernel spreads arriving datagrams between them. Every one of them must set it. Default:false.udpReceiveBufferSize<number>Size in bytes for the socket's receive buffer (SO_RCVBUF). Raising it gives the endpoint room for bursts that the default would drop. The kernel clamps this to its own maximum. Default: the system default.udpSendBufferSize<number>Size in bytes for the socket's send buffer (SO_SNDBUF). Clamped as above. Default: the system default.udpTTL<number>IP time-to-live for outgoing datagrams, from1to255. Default: the system default.maxSessions<number>The maximum number of concurrent sessions the endpoint will hold. Set to0for no limit. Default:10000.maxSessionsPerHost<number>The maximum number of concurrent sessions from any single source IP address, ignoring port. Set to0for no limit. Default:1000.sessionIdContext<string>Opaque identifier scoping resumable sessions to this server, at most 32 bytes. Default: a value derived fromprocess.argv, as intls.createServer().
- Returns: {DTLSEndpoint}
Creates a DTLS server bound to the specified address and port. The server uses automatic HMAC-based cookie exchange for DoS protection. See Denial of service.
Binding failures are thrown with the code the operating system gave, as in
net and dgram: an address already in use throws an error whose code is
'EADDRINUSE', with errno and syscall set.
import { listen } from 'node:dtls';
import { readFileSync } from 'node:fs';
const endpoint = listen((session) => {
session.onmessage = (data) => {
console.log('Received:', data.toString());
session.send('pong');
};
session.onhandshake = (protocol) => {
console.log('Handshake complete:', protocol);
};
}, {
cert: readFileSync('server-cert.pem'),
key: readFileSync('server-key.pem'),
port: 4433,
});
console.log('DTLS server listening on', endpoint.address);
dtls.connect(host, port[, options])#
host<string>Remote host to connect to, as an IPv4 or IPv6 literal. Host names are not resolved.port<number>Remote port to connect to.options<Object>ca<string>|<Buffer>|<string>[] |<Buffer>[] CA certificates in PEM format.cert<string>|<Buffer>Client certificate in PEM format.key<string>|<Buffer>Client private key in PEM format.secureContext{DTLSSecureContext} A context fromdtls.createSecureContext()to use instead of building one from the credential options below. Must not have been created withisServer: true. Cannot be combined with any option the context already carries.psk<Object>|<Function>A pre-shared key as{ identity, key }, or a function returning one. See Pre-shared keys.session<Buffer>A session fromsession.sessionon an earlier connection, to resume rather than handshake in full. See Session resumption.passphrase<string>Passphrase to decryptkey, if it is encrypted. Ignored whenkeyis not encrypted. Unlikekeyandcert, this must be a string, matchingtls.createSecureContext().rejectUnauthorized<boolean>Whentrue, the server's certificate must both chain to a trusted CA and match the expected identity (servername, orhostwhenservernameis not set); otherwise the handshake is aborted andsession.openedrejects. Whenfalse, the certificate is still verified and the handshake completes regardless, leaving the decision to the application viasession.authorizedandsession.authorizationError. Default:true.servername<string>Server name used for the SNI (Server Name Indication) extension and as the identity checked during certificate verification. Default: thehostargument. Set to''to disable SNI. SNI is never sent for IP address literals.bindHost<string>Local bind address. Default:'::'whenhostis an IPv6 literal, otherwise'0.0.0.0'. The local socket must be in the same address family as the peer.bindPort<number>Local bind port. Default:0(ephemeral).alpn<string>[] |<Buffer>ALPN protocol names. Each name must be between 1 and 255 bytes. ABuffermust already be in ALPN wire format: one length byte followed by that many bytes, repeated.srtp<string>SRTP protection profile names.mtu<number>Maximum size in bytes of a DTLS datagram. Default:1200.handshakeTimeout<number>Milliseconds a handshake may take before it is abandoned andsession.openedrejects.0disables it. Default:60000. See Handshake timeout.
- Returns: {DTLSSession}
Connects to a DTLS server. Returns a DTLSSession whose opened property
is a Promise that resolves when the handshake completes.
import { connect } from 'node:dtls';
import { readFileSync } from 'node:fs';
const session = connect('127.0.0.1', 4433, {
ca: [readFileSync('ca-cert.pem')],
});
await session.opened;
session.send('hello');
session.onmessage = (data) => {
console.log('Received:', data.toString());
};
dtls.createSecureContext([options])#
options<Object>alpn<string>[] ALPN protocols.ca<string>|<Buffer>|<Array>CA certificates in PEM format. When omitted, the bundled default certificate authorities are used.cert<string>|<Buffer>Certificate in PEM format.ciphers<string>OpenSSL cipher suite list.ecdhCurve<string>Named curve or curve list for ECDH.isServer<boolean>Build a context for a server. Default:false.key<string>|<Buffer>Private key in PEM format.passphrase<string>Passphrase forkey, if it is encrypted.rejectUnauthorized<boolean>Verification behaviour, as fordtls.listen()anddtls.connect().requestCert<boolean>Request a certificate from the peer. Servers only.sessionIdContext<string>Session id context. Servers only.sni<Object>|<Function>Server Name Indication. Servers only. See Server Name Indication.psk<Object>|<Function>Pre-shared keys. See Pre-shared keys.pskIdentityHint<string>Identity hint to advertise, naming which key a client should pick. Requirespsk. Servers only.srtp<string>SRTP profile list.ticketKeys<Buffer>Session ticket keys, for resuming sessions across endpoints and restarts. Servers only. See Session resumption.
- Returns: {DTLSSecureContext}
Options marked "Servers only" require isServer: true. Passing one to a
client context throws ERR_INVALID_ARG_VALUE, rather than being ignored or
applied where it can have no effect.
Creates a reusable secure context. Pass it to dtls.listen() or
dtls.connect() as secureContext in place of the credential options.
A context holds a parsed certificate and key and, when ca is given, its own
certificate store; roughly 28 KiB in total. Building one per connection is
therefore expensive in memory rather than in time -- two thousand of them cost
about 54 MiB, against 2 MiB when a single context is shared. Clients opening
many connections should build the context once.
The peer identity checked during verification is not part of the context.
It is bound to each connection from servername (or the host), so one context
can be used against different peers and still reject the wrong certificate.
isServer is fixed when the context is created, because it selects the
underlying OpenSSL method. Passing a server context to dtls.connect(),
or a client context to dtls.listen(), throws.
import { connect, createSecureContext, listen } from 'node:dtls';
import { readFileSync } from 'node:fs';
const serverContext = createSecureContext({
cert: readFileSync('server-cert.pem'),
key: readFileSync('server-key.pem'),
isServer: true,
});
// One context, several endpoints.
const a = listen(onsession, { secureContext: serverContext, port: 5684 });
const b = listen(onsession, { secureContext: serverContext, port: 5685 });
const clientContext = createSecureContext({
ca: readFileSync('ca-cert.pem'),
});
// One context, many connections, each verified against its own name.
const s1 = connect('192.0.2.1', 5684, {
secureContext: clientContext,
servername: 'a.example.com',
});
const s2 = connect('192.0.2.2', 5684, {
secureContext: clientContext,
servername: 'b.example.com',
});
Server Name Indication#
An endpoint can serve more than one identity by giving listen() an sni
map, or a function. Each key of a map is a host name and each value is either
a
DTLSSecureContext created with isServer: true, or a plain object of
the same options dtls.createSecureContext() takes:
import { createSecureContext, listen } from 'node:dtls';
import { readFileSync } from 'node:fs';
const endpoint = listen(onsession, {
cert: readFileSync('default-cert.pem'),
key: readFileSync('default-key.pem'),
port: 5684,
sni: {
'api.example.com': {
cert: readFileSync('api-cert.pem'),
key: readFileSync('api-key.pem'),
},
'www.example.com': createSecureContext({
cert: readFileSync('www-cert.pem'),
key: readFileSync('www-key.pem'),
isServer: true,
}),
'*': {
cert: readFileSync('default-cert.pem'),
key: readFileSync('default-key.pem'),
},
},
});
The '*' key is the fallback, used when the client's name matches nothing and
when the client sends no name at all. Without it, an unmatched name is
refused with an unrecognized_name alert rather than falling back to the
endpoint's own cert and key; providing an sni map is taken to mean that
only the names in it are served. tls.createServer() differs here: its
SNICallback falls back to the default identity silently.
Verification follows the selected identity, so an entry carrying its own ca
accepts only client certificates issued under it. requestCert and
rejectUnauthorized are not per-identity: they belong to the endpoint and
apply to every name it serves.
A function may be given instead of a map, for identities that are chosen rather than enumerated:
listen(onsession, {
port: 5684,
cert,
key,
sni: (servername) => contexts.get(servername),
});
It is called with the name the client asked for, or undefined if the client
sent no SNI extension, and returns what a map entry holds: a
dtls.createSecureContext() result or the options to build one. Returning
nothing declines the name, which is refused exactly as an unmatched map with no
'*' entry is, rather than falling back to the endpoint's own certificate.
The function runs during the handshake and must return synchronously, so it cannot consult a database. Returning a prepared context is worth doing: building one from options parses the certificate again on every handshake.
An exception thrown by the function fails that handshake and is reported to the session's error handler, like any other handshake failure. It does not reach the process as an uncaught exception.
The certificate and the cipher list both follow the selected context.
Pre-shared keys do not. OpenSSL installs the PSK callbacks on the connection
when it is created, before any name is known, and selecting an identity does
not replace them, so the keys a server accepts are always the endpoint's own.
A psk given on an SNI identity is never consulted, and an identity cannot be
served over PSK alone.
sni belongs to the secure context rather than to the endpoint, so it can be
given to dtls.createSecureContext() and cannot be combined with a
secureContext that already exists. Applying it to a prepared context would
reconfigure that context for every endpoint sharing it, and the identities a
server serves are part of what its context is.
A connection refused for an unrecognized name still reaches the listen()
callback: the session exists once the client's address is validated, which
happens before the name is examined. It then fails like any other handshake
failure.
Denial of service#
Cookie exchange proves a peer can receive at its claimed address, but it does
not limit how many sessions that peer may then establish, and each session
holds a TLS state machine, two buffers and a timer. maxSessions bounds the
total; maxSessionsPerHost is what prevents one peer from taking all of it.
A peer refused by either cap is answered with silence rather than an alert,
because replying to an address that has not completed cookie exchange would
create an amplification vector; a legitimate client retransmits and is
admitted once there is room. Refusals are counted by
endpointStats.serverRefusedCount.
Deployments serving many clients behind a single NAT may need to raise
maxSessionsPerHost.
Handshake timeout#
A handshake that never finishes is abandoned after handshakeTimeout
milliseconds, and its session error is DTLS handshake timeout.
OpenSSL already gives up on its own, but only after twelve retransmits on a
doubling backoff capped at 60 seconds -- around eight minutes in total. Until
then the session holds its place against maxSessions (see
Denial of service),
so handshakes that are started and abandoned can occupy an endpoint for the
cost of starting them. That needs no spoofing: the peer completes the cookie
exchange and then simply stops.
The two limits coexist and whichever comes first ends the handshake. The retransmit schedule itself is untouched, deliberately -- compressing it to force earlier failure would cause spurious retransmissions on exactly the lossy links DTLS is meant for.
The timeout covers resumed and PSK handshakes as well, and stops applying once the handshake completes; it is not an idle timeout.
A handshake can stall without either peer being at fault or aware. DTLS discards records it cannot authenticate rather than answering them (RFC 6347 section 4.1.2.1), so a mismatched pre-shared key or a cipher list with nothing in common produces silence rather than an alert. This timeout is what ends those.
Pre-shared keys#
DTLS can authenticate with a key both peers already hold instead of a certificate (RFC 4279). This is how it is usually deployed to constrained devices, which frequently have no certificate at all.
A server gives the identities it accepts; a client gives the one it is. No certificate is needed on either side:
import { connect, listen } from 'node:dtls';
const endpoint = listen(onsession, {
port: 5684,
psk: { 'device-42': deviceKey },
});
const client = connect('192.0.2.1', 5684, {
psk: { identity: 'device-42', key: deviceKey },
});
Either side may pass a function instead, for keys that are looked up or
derived rather than known up front. A server's is called with the identity the
client offered and returns the key, or nothing to refuse it. A client's is
called with the server's identity hint, if it sent one, and returns
{ identity, key }:
listen(onsession, {
port: 5684,
psk: (identity) => deriveKey(masterSecret, identity),
});
The callback runs during the handshake and must return synchronously, so it cannot consult a database. Where both are given, the map is checked first and the callback is only reached when the map has no answer -- a configuration using only the map never runs JavaScript inside the handshake.
An exception thrown by the callback fails that handshake and is reported to the session's error handler. It does not reach the process as an uncaught exception.
Cipher suites#
The default cipher list excludes PSK, so giving psk without ciphers
enables the PSK suites. Supplying ciphers disables that and uses exactly
what was asked for.
A server keeps the certificate suites as well, since it may serve both kinds of client on one port. A client does not: a client that configured a pre-shared key and no CA wants the key, and leaving the certificate suites enabled would let a server choose one, failing the handshake while verifying a certificate the caller never meant to rely on.
Forward-secret PSK key exchanges are preferred over plain PSK of the same
strength. Plain PSK derives its keys from the shared secret alone, so anyone
who later learns that key can decrypt traffic they recorded earlier. RSA-PSK
is excluded: it needs a certificate and adds no forward secrecy.
CoAP requires TLS_PSK_WITH_AES_128_CCM_8 (RFC 7252), whose 64-bit
authentication tag OpenSSL rejects at security level 1 and above. Node.js
default is above it, so that suite has to be asked for explicitly and with the
security level lowered:
listen(onsession, { port: 5684, psk, ciphers: 'PSK-AES128-CCM8@SECLEVEL=0' });
Failure modes#
A wrong key does not produce an error. The identity only names the key, so the handshake proceeds and the two sides derive different secrets; the first record that fails authentication is then discarded rather than answered, since DTLS discards invalid records instead of replying to them (RFC 6347 section 4.1.2.1). Neither peer is told anything and both retransmit.
A cipher list with nothing in common behaves the same way, which is what makes
the CCM8 case above present as a stall rather than a rejection. Both are
ended by handshakeTimeout, after 60 seconds by default.
An identity the server does not recognise is refused outright, and the client sees the handshake fail.
Session resumption#
A resumed handshake skips the server's certificate, which matters more here
than it does over TCP: the Certificate flight is fragmented across several
datagrams, and losing any one of them costs a retransmission timeout. Measured
on loopback, a full handshake has the server send 1850 bytes in 4 packets
against 280 bytes in 3 for a resumed one.
A client reads session.session once the session is open and passes it to
a later dtls.connect():
import { connect } from 'node:dtls';
const first = connect('192.0.2.1', 5684, { ca, servername: 'device.example' });
await first.opened;
const ticket = first.session; // Buffer.
await first.close();
const second = connect('192.0.2.1', 5684, {
ca,
servername: 'device.example',
session: ticket,
});
await second.opened;
console.log(second.reused); // True.
A session that the server will not accept -- expired, or issued by a different
endpoint -- is not an error. The handshake simply proceeds in full, and
session.reused is false.
The cookie exchange still happens for a resumed handshake, so resumption is not a way around the address validation described under Denial of service.
Binding to the authenticated host#
A session may only be resumed against the identity it was authenticated for --
the servername, or the host when there is none. Reusing it for anything else
throws.
This is not a convenience check. A resumed handshake does not re-send or
re-verify the peer's certificate; it inherits the authenticated identity of the
original session. Replaying a session against a different host would therefore
skip verification while appearing to succeed. For the same reason a session
that did not come from session.session is rejected outright: nothing
records which identity it belongs to, so it cannot be checked.
Resuming under rejectUnauthorized#
A session carries the verification result it was established with, so a session
established with rejectUnauthorized: false cannot be resumed by a connection
that asked for a verified peer. The handshake fails:
import { connect } from 'node:dtls';
// Connected without verifying anything.
const first = connect('192.0.2.1', 5684, { rejectUnauthorized: false });
await first.opened;
console.log(first.authorized); // False.
const ticket = first.session;
await first.close();
const second = connect('192.0.2.1', 5684, {
rejectUnauthorized: true,
session: ticket,
});
await second.opened; // Rejects: verification failed.
The host is the same in both, so binding the session to its authenticated
identity does not cover this on its own; what differs is whether the caller
asked for the peer to be verified. Because a resumed handshake runs no
verification of its own, the recorded result is re-checked once it completes,
and a session whose peer never verified is refused wherever verification is
required. session.authorized and session.authorizationError report
the recorded result on a resumed session either way.
Ticket keys#
The key that encrypts session tickets is generated at random for each context,
so by default a ticket is only good for the endpoint that issued it and only
until the process restarts. Give every endpoint the same ticketKeys to let
tickets be resumed across a restart or a cluster:
import { listen } from 'node:dtls';
import { randomBytes } from 'node:crypto';
const ticketKeys = randomBytes(80); // Share this between processes.
const endpoint = listen(onsession, { cert, key, port: 5684, ticketKeys });
The length is OpenSSL's: a key name followed by an HMAC key and an AES key. It
differs from the 48 bytes tls.createServer() uses, which is a layout
node:tls defines for itself. Supplying the wrong length throws and reports
the length expected.
Ticket keys are long-lived secrets. Anyone holding them can decrypt tickets and recover the sessions they protect, so treat them as key material and rotate them.
Class: DTLSSecureContext#
An opaque, reusable bundle of credentials and TLS settings, created by
dtls.createSecureContext(). It cannot be constructed directly.
secureContext.isServer#
- Returns:
<boolean>trueif the context was created for a server.
Class: DTLSEndpoint#
Manages a UDP socket and multiplexes DTLS sessions.
endpoint.address#
- Returns:
<Object>{ address, family, port }
The local address the endpoint is bound to.
endpoint.stats#
- Type:
<DTLSEndpoint.Stats>
The statistics collected for this endpoint. Read only. The stats object is live and updated as data flows through the endpoint.
endpoint.busy#
When true, the endpoint rejects new incoming connections. Can be set
to implement backpressure.
endpoint.close()#
- Returns:
<Promise>Resolves when the endpoint is fully closed.
Gracefully closes the endpoint. All active sessions are closed with
close_notify alerts before the UDP socket is released.
endpoint.destroy([error])#
Immediately destroys the endpoint without sending close_notify alerts.
endpoint.destroyed#
<boolean>True once the endpoint has been destroyed.
endpoint.closed#
<Promise>Resolves when the endpoint has fully closed.
endpoint[Symbol.asyncDispose]()#
Equivalent to calling endpoint.close().
Class: DTLSEndpoint.Stats#
A view of the collected statistics for an endpoint.
endpointStats.createdAt#
- Type:
<bigint>A timestamp indicating when the endpoint was created. Read only.
endpointStats.destroyedAt#
- Type:
<bigint>A timestamp indicating when the endpoint was destroyed. Read only.
endpointStats.bytesReceived#
- Type:
<bigint>The total number of bytes received by this endpoint. Read only.
endpointStats.bytesSent#
- Type:
<bigint>The total number of bytes sent by this endpoint. Read only.
endpointStats.packetsReceived#
- Type:
<bigint>The total number of UDP packets received by this endpoint. Read only.
endpointStats.packetsSent#
- Type:
<bigint>The total number of UDP packets sent by this endpoint. Read only.
endpointStats.serverSessions#
- Type:
<bigint>The total number of peer-initiated sessions accepted by this endpoint. Read only.
endpointStats.clientSessions#
- Type:
<bigint>The total number of sessions initiated by this endpoint. Read only.
endpointStats.serverBusyCount#
- Type:
<bigint>The total number of incoming connections rejected because the endpoint was marked busy. Read only.
endpointStats.serverRejectedCount#
- Type:
<bigint>The number of datagrams discarded before a handshake was attempted because they could not be a ClientHello. Read only.
Datagrams arriving at a listening endpoint that do not match an existing session are screened for the shape of a DTLS ClientHello record before any state is allocated for them. A steadily rising value indicates junk or scan traffic rather than failing clients, which are counted as sessions that never complete.
endpointStats.serverRefusedCount#
- Type:
<bigint>The number of otherwise valid handshake attempts refused because the endpoint was atmaxSessionsor the peer was atmaxSessionsPerHost. Read only.
endpointStats.isConnected#
- Type:
<boolean>
true if the stats object is still connected to the underlying endpoint.
Once the endpoint is destroyed, the stats become a stale snapshot.
Class: DTLSSession#
Represents a DTLS association with a single remote peer.
session.send(data)#
data<string>|<Buffer>|<TypedArray>|<DataView>The data to send. At most 16384 bytes. A view sends the bytes it covers, so an offset or a subarray is sent as given rather than as the whole buffer behind it.- Returns:
<number>The number of bytes written to the DTLS layer.
Send application data to the peer. The data is encrypted by DTLS before
being sent over UDP. Can only be called after the handshake completes
(session.opened has resolved).
DTLS carries application data in a single record per datagram and does not
fragment it, so data must fit in one record. Sending more throws
ERR_OUT_OF_RANGE. This limit is independent of the mtu option: a record
larger than the path MTU is still sent, and is fragmented by IP.
Throws ERR_INVALID_STATE if the handshake has not completed, or if the
session is closed or destroyed.
A successful return means the data was handed to the DTLS layer and written to the socket, not that the peer received it. DTLS runs over UDP, so application data may still be lost in transit.
session.close()#
- Returns:
<Promise>Resolves when the session is closed.
Initiates a graceful DTLS shutdown by sending a close_notify alert.
session.destroy([error])#
Immediately destroys the session without sending close_notify.
session.destroyed#
<boolean>True once the session has been destroyed, whether bysession.destroy(), by a close, or by its endpoint going away.
session.endpoint#
- {DTLSEndpoint} The endpoint carrying this session. For a session from
dtls.listen()this is the listening endpoint, shared with every other session on it; for one fromdtls.connect()it is the endpoint created to carry that session alone.
session.servername#
<string>|<undefined>The server name for this session: the name the client sent in the SNI extension, read on either side of the connection.undefinedwhen no name was sent. See Server name indication.
session.opened#
<Promise>Resolves with{ protocol }when the DTLS handshake completes.
Rejects if the handshake fails, and also if the session is closed or
destroyed before the handshake completes -- in that case with
ERR_INVALID_STATE, or with the error passed to
session.destroy() if one was given. The promise always settles, so
awaiting it cannot hang.
session.closed#
<Promise>Settles when the session is fully closed. Resolves when the close was graceful, and rejects with the error when the session was destroyed with one, or when its endpoint was. The promise always settles, so awaiting it cannot hang.
session.remoteAddress#
- Returns:
<Object>{ address, family, port }
session.protocol#
- Returns:
<string>The negotiated DTLS protocol version (e.g.,'DTLSv1.2').
session.cipher#
- Returns:
<Object>{ name, standardName, version }
session.peerCertificate#
- Returns:
<string>|<undefined>The peer's certificate in PEM format, orundefinedif the peer sent none.
This is the leaf certificate as PEM text and nothing else. For the issuer chain
and the parsed fields, use session.peerX509Certificate, whose toString()
returns this same PEM. Use session.authorized and
session.authorizationError for the verification result rather than
parsing either.
session.peerX509Certificate#
- Returns:
<X509Certificate>|<undefined>The peer's certificate, orundefinedif the peer sent none.
An X509Certificate for the peer's leaf certificate. The issuer chain is
reachable through its issuerCertificate property, and the parsed fields --
subject, issuer, validFrom, validTo, fingerprint256, serialNumber
and the rest -- are properties of that object.
Where tls.TLSSocket.getPeerCertificate() returns a plain dictionary with
valid_from, valid_to and a chain walked through issuerCertificate, this
returns the same X509Certificate class that
tls.TLSSocket.getPeerX509Certificate() does. Call toLegacyObject() on
it to get the dictionary form.
The same object is returned on every access once the peer's certificate is available.
session.session#
- Returns:
<Buffer>|<undefined>An opaque session for resuming this connection later, orundefinedon a server session or before the handshake completes.
Pass it as the session option to a later dtls.connect(). It is bound to
the host this connection authenticated against and is refused elsewhere; see
Session resumption.
Server sessions return undefined: a server has no identity to bind the value
to, and it is the client that carries a session between connections.
session.reused#
- Returns:
<boolean>trueif this connection resumed an earlier session rather than performing a full handshake.
Like session.authorized, this reads false once the session is closed.
session.authorized#
- Returns:
<boolean>trueif the peer presented a certificate chain that verified against the configured certificate authorities, and, for a client, matched the requested identity.falsebefore the handshake completes.
session.authorizationError#
- Returns:
<string>|<undefined>The short X509 verification error code, for example'CERT_HAS_EXPIRED'or'HOSTNAME_MISMATCH', orundefinedif the peer's chain verified.
A peer that presented no certificate at all reports
'UNABLE_TO_GET_ISSUER_CERT', so this can be used to distinguish "no
certificate" from "a certificate that failed to verify".
The chain is verified even when rejectUnauthorized is false; the result is
simply not enforced. That makes these two properties the way to apply a custom
authorization policy:
import { connect } from 'node:dtls';
const session = connect('192.0.2.1', 4433, {
ca: [caCert],
servername: 'example.com',
rejectUnauthorized: false,
});
await session.opened;
if (!session.authorized && session.authorizationError !== 'CERT_HAS_EXPIRED') {
await session.close();
}
session.alpnProtocol#
- Returns:
<string>|<undefined>The negotiated ALPN protocol, orundefinedif ALPN was not used.
If a server has alpn configured and a client offers only protocols the
server does not support, the server sends a fatal no_application_protocol
alert and the handshake fails, as required by RFC 7301 section 3.2. A
server with no alpn configured declines the extension instead, and the
handshake completes with no protocol negotiated.
session.srtpProfile#
- Returns:
<string>|<undefined>The negotiated SRTP protection profile name.
session.stats#
- Type:
<DTLSSession.Stats>
The statistics collected for this session. Read only. The stats object is live and updated as data flows through the session.
session.exportKeyingMaterial(length, label[, context])#
length<number>Number of bytes to export. Must be an integer between1and65536.label<string>The label for the exported keying material.context<Buffer>Optional context value.- Returns:
<Buffer>
Exports keying material from the DTLS session, as defined in RFC 5705. This is commonly used with DTLS-SRTP to derive encryption keys for media streams.
Throws ERR_OUT_OF_RANGE if length is outside the accepted range. The upper
bound is not imposed by RFC 5705; it exists so that a caller cannot request
an arbitrarily large allocation, and is far above what any defined exporter
needs (DTLS-SRTP uses 60 bytes).
Callback properties#
session.onmessage#
<Function>data<Buffer>
Set to receive application data from the peer.
session.onerror#
<Function>error<Error>
Set to receive error notifications.
session.onhandshake#
<Function>protocol<string>
Set to receive handshake completion notifications.
session.onkeylog#
<Function>line<string>
Set to receive TLS key log lines (for debugging with Wireshark).
session[Symbol.asyncDispose]()#
Equivalent to calling session.close().
Class: DTLSSession.Stats#
A view of the collected statistics for a session.
sessionStats.createdAt#
- Type:
<bigint>A timestamp indicating when the session was created. Read only.
sessionStats.destroyedAt#
- Type:
<bigint>A timestamp indicating when the session was destroyed. Read only.
sessionStats.closingAt#
- Type:
<bigint>A timestamp indicating whenclose()was called. Read only.
sessionStats.handshakeCompletedAt#
- Type:
<bigint>A timestamp indicating when the DTLS handshake completed. Read only.
sessionStats.bytesReceived#
- Type:
<bigint>The total number of application data bytes received. Read only.
sessionStats.bytesSent#
- Type:
<bigint>The total number of application data bytes sent. Read only.
sessionStats.messagesReceived#
- Type:
<bigint>The total number of application messages received. Read only.
sessionStats.messagesSent#
- Type:
<bigint>The total number of application messages sent. Read only.
sessionStats.retransmitCount#
- Type:
<bigint>The total number of DTLS handshake retransmissions. Read only.
sessionStats.isConnected#
- Type:
<boolean>
true if the stats object is still connected to the underlying session.
Once the session is destroyed, the stats become a stale snapshot.
DTLS-SRTP example#
DTLS-SRTP is used by WebRTC for media encryption. The DTLS handshake negotiates the SRTP protection profile and provides keying material.
import { listen, connect } from 'node:dtls';
import { readFileSync } from 'node:fs';
// Server with SRTP
const server = listen((session) => {
session.onhandshake = () => {
console.log('SRTP profile:', session.srtpProfile);
const keys = session.exportKeyingMaterial(
60,
'EXTRACTOR-dtls_srtp',
);
console.log('SRTP keying material:', keys);
};
}, {
cert: readFileSync('server-cert.pem'),
key: readFileSync('server-key.pem'),
port: 5004,
srtp: 'SRTP_AES128_CM_SHA1_80:SRTP_AEAD_AES_128_GCM',
});
// Client with SRTP
const session = connect('127.0.0.1', 5004, {
rejectUnauthorized: false,
srtp: 'SRTP_AEAD_AES_128_GCM:SRTP_AES128_CM_SHA1_80',
});
await session.opened;
console.log('Negotiated SRTP:', session.srtpProfile);
const keys = session.exportKeyingMaterial(60, 'EXTRACTOR-dtls_srtp');
MTU considerations#
Since libuv does not currently support path MTU discovery, the DTLS module uses a conservative default MTU of 1200 bytes. This value works across virtually all network paths but may be suboptimal for local networks.
This bounds the UDP payload, not the application payload: a record carries
somewhat less once its header and MAC are accounted for. It is fixed when the
endpoint is created and cannot be changed afterwards. It does not bound
session.send(), which is limited by the DTLS record size instead.
The MTU can be configured via the mtu option:
// For a local network where you know the path MTU
const endpoint = listen(callback, {
// ...
mtu: 1400,
});
The minimum allowed MTU is 256 bytes. The maximum is 65535.
Inspector#
Stability: 2 - Stable
The node:inspector module provides an API for interacting with the V8
inspector.
It can be accessed using:
import * as inspector from 'node:inspector/promises';const inspector = require('node:inspector/promises');
or
import * as inspector from 'node:inspector';const inspector = require('node:inspector');
Promises API#
Stability: 1 - Experimental
Class: inspector.Session#
- Extends:
<EventEmitter>
The inspector.Session is used for dispatching messages to the V8 inspector
back-end and receiving message responses and notifications.
new inspector.Session()#
Create a new instance of the inspector.Session class. The inspector session
needs to be connected through session.connect() before the messages
can be dispatched to the inspector backend.
When using Session, the object outputted by the console API will not be
released, unless we performed manually Runtime.DiscardConsoleEntries
command.
Event: 'inspectorNotification'#
- Type:
<Object>The notification message object
Emitted when any notification from the V8 Inspector is received.
session.on('inspectorNotification', (message) => console.log(message.method));
// Debugger.paused
// Debugger.resumed
Caveat Breakpoints with same-thread session is not recommended, see support of breakpoints.
It is also possible to subscribe only to notifications with specific method:
Event: <inspector-protocol-method>#
- Type:
<Object>The notification message object
Emitted when an inspector notification is received that has its method field set
to the <inspector-protocol-method> value.
The following snippet installs a listener on the 'Debugger.paused'
event, and prints the reason for program suspension whenever program
execution is suspended (through breakpoints, for example):
session.on('Debugger.paused', ({ params }) => {
console.log(params.hitBreakpoints);
});
// [ '/the/file/that/has/the/breakpoint.js:11:0' ]
Caveat Breakpoints with same-thread session is not recommended, see support of breakpoints.
session.connect()#
Connects a session to the inspector back-end.
session.connectToMainThread()#
Connects a session to the main thread inspector back-end. An exception will
be thrown if this API was not called on a Worker thread, or if
--process-timeout is used, as the session could pause the main thread.
session.disconnect()#
Immediately close the session. All pending message callbacks will be called
with an error. session.connect() will need to be called to be able to send
messages again. Reconnected session will lose all inspector state, such as
enabled agents or configured breakpoints.
session.post(method[, params])#
Posts a message to the inspector back-end.
import { Session } from 'node:inspector/promises';
try {
const session = new Session();
session.connect();
const result = await session.post('Runtime.evaluate', { expression: '2 + 2' });
console.log(result);
} catch (error) {
console.error(error);
}
// Output: { result: { type: 'number', value: 4, description: '4' } }
The latest version of the V8 inspector protocol is published on the Chrome DevTools Protocol Viewer.
Node.js inspector supports all the Chrome DevTools Protocol domains declared by V8. Chrome DevTools Protocol domain provides an interface for interacting with one of the runtime agents used to inspect the application state and listen to the run-time events.
Example usage#
Apart from the debugger, various V8 Profilers are available through the DevTools protocol.
CPU profiler#
Here's an example showing how to use the CPU Profiler:
import { Session } from 'node:inspector/promises';
import fs from 'node:fs';
const session = new Session();
session.connect();
await session.post('Profiler.enable');
await session.post('Profiler.start');
// Invoke business logic under measurement here...
// some time later...
const { profile } = await session.post('Profiler.stop');
// Write profile to disk, upload, etc.
fs.writeFileSync('./profile.cpuprofile', JSON.stringify(profile));
Heap profiler#
Here's an example showing how to use the Heap Profiler:
import { Session } from 'node:inspector/promises';
import fs from 'node:fs';
const session = new Session();
const fd = fs.openSync('profile.heapsnapshot', 'w');
session.connect();
session.on('HeapProfiler.addHeapSnapshotChunk', (m) => {
fs.writeSync(fd, m.params.chunk);
});
const result = await session.post('HeapProfiler.takeHeapSnapshot', null);
console.log('HeapProfiler.takeHeapSnapshot done:', result);
session.disconnect();
fs.closeSync(fd);
Callback API#
Class: inspector.Session#
- Extends:
<EventEmitter>
The inspector.Session is used for dispatching messages to the V8 inspector
back-end and receiving message responses and notifications.
new inspector.Session()#
Create a new instance of the inspector.Session class. The inspector session
needs to be connected through session.connect() before the messages
can be dispatched to the inspector backend.
When using Session, the object outputted by the console API will not be
released, unless we performed manually Runtime.DiscardConsoleEntries
command.
Event: 'inspectorNotification'#
- Type:
<Object>The notification message object
Emitted when any notification from the V8 Inspector is received.
session.on('inspectorNotification', (message) => console.log(message.method));
// Debugger.paused
// Debugger.resumed
Caveat Breakpoints with same-thread session is not recommended, see support of breakpoints.
It is also possible to subscribe only to notifications with specific method:
Event: <inspector-protocol-method>;#
- Type:
<Object>The notification message object
Emitted when an inspector notification is received that has its method field set
to the <inspector-protocol-method> value.
The following snippet installs a listener on the 'Debugger.paused'
event, and prints the reason for program suspension whenever program
execution is suspended (through breakpoints, for example):
session.on('Debugger.paused', ({ params }) => {
console.log(params.hitBreakpoints);
});
// [ '/the/file/that/has/the/breakpoint.js:11:0' ]
Caveat Breakpoints with same-thread session is not recommended, see support of breakpoints.
session.connect()#
Connects a session to the inspector back-end.
session.connectToMainThread()#
Connects a session to the main thread inspector back-end. An exception will
be thrown if this API was not called on a Worker thread, or if
--process-timeout is used, as the session could pause the main thread.
session.disconnect()#
Immediately close the session. All pending message callbacks will be called
with an error. session.connect() will need to be called to be able to send
messages again. Reconnected session will lose all inspector state, such as
enabled agents or configured breakpoints.
session.post(method[, params][, callback])#
method<string>params<Object>callback<Function>
Posts a message to the inspector back-end. callback will be notified when
a response is received. callback is a function that accepts two optional
arguments: error and message-specific result.
session.post('Runtime.evaluate', { expression: '2 + 2' },
(error, { result }) => console.log(result));
// Output: { type: 'number', value: 4, description: '4' }
The latest version of the V8 inspector protocol is published on the Chrome DevTools Protocol Viewer.
Node.js inspector supports all the Chrome DevTools Protocol domains declared by V8. Chrome DevTools Protocol domain provides an interface for interacting with one of the runtime agents used to inspect the application state and listen to the run-time events.
You can not set reportProgress to true when sending a
HeapProfiler.takeHeapSnapshot or HeapProfiler.stopTrackingHeapObjects
command to V8.
Example usage#
Apart from the debugger, various V8 Profilers are available through the DevTools protocol.
CPU profiler#
Here's an example showing how to use the CPU Profiler:
const inspector = require('node:inspector');
const fs = require('node:fs');
const session = new inspector.Session();
session.connect();
session.post('Profiler.enable', () => {
session.post('Profiler.start', () => {
// Invoke business logic under measurement here...
// some time later...
session.post('Profiler.stop', (err, { profile }) => {
// Write profile to disk, upload, etc.
if (!err) {
fs.writeFileSync('./profile.cpuprofile', JSON.stringify(profile));
}
});
});
});
Heap profiler#
Here's an example showing how to use the Heap Profiler:
const inspector = require('node:inspector');
const fs = require('node:fs');
const session = new inspector.Session();
const fd = fs.openSync('profile.heapsnapshot', 'w');
session.connect();
session.on('HeapProfiler.addHeapSnapshotChunk', (m) => {
fs.writeSync(fd, m.params.chunk);
});
session.post('HeapProfiler.takeHeapSnapshot', null, (err, r) => {
console.log('HeapProfiler.takeHeapSnapshot done:', err, r);
session.disconnect();
fs.closeSync(fd);
});
Common Objects#
inspector.close()#
Deactivates the inspector. If there are active connections, they are forcibly terminated. Blocks until the inspector server has fully stopped.
inspector.console#
- Type:
<Object>An object to send messages to the remote inspector console.
require('node:inspector').console.log('a message');
The inspector console does not have API parity with Node.js console.
inspector.open([port[, host[, wait]]])#
port<number>Port to listen on for inspector connections. Optional. Default: what was specified on the CLI.host<string>Host to listen on for inspector connections. Optional. Default: what was specified on the CLI.wait<boolean>Block until a client has connected. Optional. Default:false.- Returns:
<Disposable>A Disposable that callsinspector.close().
Activate inspector on host and port. Equivalent to
node --inspect=[[host:]port], but can be done programmatically after node has
started.
If wait is true, will block until a client has connected to the inspect port
and flow control has been passed to the debugger client.
See the security warning regarding the host
parameter usage.
Throws an ERR_INSPECTOR_NOT_AVAILABLE error if --process-timeout is
used.
inspector.url()#
- Returns:
<string>|<undefined>
Return the URL of the active inspector, or undefined if there is none.
$ node --inspect -p 'inspector.url()'
Debugger listening on ws://127.0.0.1:9229/166e272e-7a30-4d09-97ce-f1c012b43c34
For help, see: https://nodejs.org/learn/getting-started/debugging
ws://127.0.0.1:9229/166e272e-7a30-4d09-97ce-f1c012b43c34
$ node --inspect=localhost:3000 -p 'inspector.url()'
Debugger listening on ws://localhost:3000/51cf8d0e-3c36-4c59-8efd-54519839e56a
For help, see: https://nodejs.org/learn/getting-started/debugging
ws://localhost:3000/51cf8d0e-3c36-4c59-8efd-54519839e56a
$ node -p 'inspector.url()'
undefined
inspector.waitForDebugger()#
Blocks until a client (existing or connected later) has sent
Runtime.runIfWaitingForDebugger command.
An exception will be thrown if there is no active inspector.
Integration with DevTools#
Stability: 1.1 - Active development
The node:inspector module provides an API for integrating with devtools that support Chrome DevTools Protocol.
DevTools frontends connected to a running Node.js instance can capture protocol events emitted from the instance
and display them accordingly to facilitate debugging.
The following methods broadcast a protocol event to all connected frontends.
The params passed to the methods can be optional, depending on the protocol.
// The `Network.requestWillBeSent` event will be fired.
inspector.Network.requestWillBeSent({
requestId: 'request-id-1',
timestamp: Date.now() / 1000,
wallTime: Date.now(),
request: {
url: 'https://nodejs.org/en',
method: 'GET',
},
});
inspector.Network.dataReceived([params])#
params<Object>
This feature is only available with the --experimental-network-inspection flag enabled.
Broadcasts the Network.dataReceived event to connected frontends, or buffers the data if
Network.streamResourceContent command was not invoked for the given request yet.
Also enables Network.getResponseBody command to retrieve the response data.
inspector.Network.dataSent([params])#
params<Object>
This feature is only available with the --experimental-network-inspection flag enabled.
Enables Network.getRequestPostData command to retrieve the request data.
inspector.Network.requestWillBeSent([params])#
params<Object>
This feature is only available with the --experimental-network-inspection flag enabled.
Broadcasts the Network.requestWillBeSent event to connected frontends. This event indicates that
the application is about to send an HTTP request.
inspector.Network.responseReceived([params])#
params<Object>
This feature is only available with the --experimental-network-inspection flag enabled.
Broadcasts the Network.responseReceived event to connected frontends. This event indicates that
HTTP response is available.
inspector.Network.loadingFinished([params])#
params<Object>
This feature is only available with the --experimental-network-inspection flag enabled.
Broadcasts the Network.loadingFinished event to connected frontends. This event indicates that
HTTP request has finished loading.
inspector.Network.loadingFailed([params])#
params<Object>
This feature is only available with the --experimental-network-inspection flag enabled.
Broadcasts the Network.loadingFailed event to connected frontends. This event indicates that
HTTP request has failed to load.
inspector.Network.webSocketCreated([params])#
params<Object>
This feature is only available with the --experimental-network-inspection flag enabled.
Broadcasts the Network.webSocketCreated event to connected frontends. This event indicates that
a WebSocket connection has been initiated.
inspector.Network.webSocketHandshakeResponseReceived([params])#
params<Object>
This feature is only available with the --experimental-network-inspection flag enabled.
Broadcasts the Network.webSocketHandshakeResponseReceived event to connected frontends.
This event indicates that the WebSocket handshake response has been received.
inspector.Network.webSocketClosed([params])#
params<Object>
This feature is only available with the --experimental-network-inspection flag enabled.
Broadcasts the Network.webSocketClosed event to connected frontends.
This event indicates that a WebSocket connection has been closed.
inspector.NetworkResources.put#
Stability: 1.1 - Active Development
This feature is only available with the --experimental-inspector-network-resource flag enabled.
The inspector.NetworkResources.put method is used to provide a response for a loadNetworkResource request issued via the Chrome DevTools Protocol (CDP). This is typically triggered when a source map is specified by URL, and a DevTools frontend—such as Chrome—requests the resource to retrieve the source map.
This method allows developers to predefine the resource content to be served in response to such CDP requests.
const inspector = require('node:inspector');
// By preemptively calling put to register the resource, a source map can be resolved when
// a loadNetworkResource request is made from the frontend.
async function setNetworkResources() {
const mapUrl = 'http://localhost:3000/dist/app.js.map';
const tsUrl = 'http://localhost:3000/src/app.ts';
const distAppJsMap = await fetch(mapUrl).then((res) => res.text());
const srcAppTs = await fetch(tsUrl).then((res) => res.text());
inspector.NetworkResources.put(mapUrl, distAppJsMap);
inspector.NetworkResources.put(tsUrl, srcAppTs);
};
setNetworkResources().then(() => {
require('./dist/app');
});
For more details, see the official CDP documentation: Network.loadNetworkResource
inspector.DOMStorage.domStorageItemAdded#
params<Object>
This feature is only available with the
--experimental-storage-inspection flag enabled.
Broadcasts the DOMStorage.domStorageItemAdded event to connected frontends.
This event indicates that a new item has been added to the storage.
inspector.DOMStorage.domStorageItemRemoved#
params<Object>
This feature is only available with the
--experimental-storage-inspection flag enabled.
Broadcasts the DOMStorage.domStorageItemRemoved event to connected frontends.
This event indicates that an item has been removed from the storage.
inspector.DOMStorage.domStorageItemUpdated#
params<Object>
This feature is only available with the
--experimental-storage-inspection flag enabled.
Broadcasts the DOMStorage.domStorageItemUpdated event to connected frontends.
This event indicates that a storage item has been updated.
inspector.DOMStorage.domStorageItemsCleared#
params<Object>
This feature is only available with the
--experimental-storage-inspection flag enabled.
Broadcasts the DOMStorage.domStorageItemsCleared event to connected
frontends. This event indicates that all items have been cleared from the
storage.
inspector.DOMStorage.registerStorage#
This feature is only available with the
--experimental-storage-inspection flag enabled.
Support of breakpoints#
The Chrome DevTools Protocol Debugger domain allows an
inspector.Session to attach to a program and set breakpoints to step through
the codes.
However, setting breakpoints with a same-thread inspector.Session, which is
connected by session.connect(), should be avoided as the program being
attached and paused is exactly the debugger itself. Instead, try connect to the
main thread by session.connectToMainThread() and set breakpoints in a
worker thread, or connect with a Debugger program over WebSocket
connection.
Internationalization support#
Node.js has many features that make it easier to write internationalized programs. Some of them are:
- Locale-sensitive or Unicode-aware functions in the ECMAScript Language Specification:
- All functionality described in the ECMAScript Internationalization API
Specification (aka ECMA-402):
Intlobject- Locale-sensitive methods like
String.prototype.localeCompare()andDate.prototype.toLocaleString()
- The WHATWG URL parser's internationalized domain names (IDNs) support
require('node:buffer').transcode()- More accurate REPL line editing
require('node:util').TextDecoderRegExpUnicode Property Escapes
Node.js and the underlying V8 engine use International Components for Unicode (ICU) to implement these features in native C/C++ code. The full ICU data set is provided by Node.js by default. However, due to the size of the ICU data file, several options are provided for customizing the ICU data set either when building or running Node.js.
Options for building Node.js#
To control how ICU is used in Node.js, four configure options are available
during compilation. Additional details on how to compile Node.js are documented
in BUILDING.md.
--with-intl=none/--without-intl--with-intl=system-icu--with-intl=small-icu--with-intl=full-icu(default)
An overview of available Node.js and JavaScript features for each configure
option:
| Feature | none |
system-icu |
small-icu |
full-icu |
|---|---|---|---|---|
String.prototype.normalize() |
none (function is no-op) | full | full | full |
String.prototype.to*Case() |
full | full | full | full |
Intl |
none (object does not exist) | partial/full (depends on OS) | partial (English-only) | full |
String.prototype.localeCompare() |
partial (not locale-aware) | full | full | full |
String.prototype.toLocale*Case() |
partial (not locale-aware) | full | full | full |
Number.prototype.toLocaleString() |
partial (not locale-aware) | partial/full (depends on OS) | partial (English-only) | full |
Date.prototype.toLocale*String() |
partial (not locale-aware) | partial/full (depends on OS) | partial (English-only) | full |
| Legacy URL Parser | partial (no IDN support) | full | full | full |
| WHATWG URL Parser | partial (no IDN support) | full | full | full |
require('node:buffer').transcode() |
none (function does not exist) | full | full | full |
| REPL | partial (inaccurate line editing) | full | full | full |
require('node:util').TextDecoder |
partial (basic encodings support) | partial/full (depends on OS) | partial (Unicode-only) | full |
RegExp Unicode Property Escapes |
none (invalid RegExp error) |
full | full | full |
The "(not locale-aware)" designation denotes that the function carries out its
operation just like the non-Locale version of the function, if one
exists. For example, under none mode, Date.prototype.toLocaleString()'s
operation is identical to that of Date.prototype.toString().
Disable all internationalization features (none)#
If this option is chosen, ICU is disabled and most internationalization
features mentioned above will be unavailable in the resulting node binary.
Build with a pre-installed ICU (system-icu)#
Node.js can link against an ICU build already installed on the system. In fact, most Linux distributions already come with ICU installed, and this option would make it possible to reuse the same set of data used by other components in the OS.
Functionalities that only require the ICU library itself, such as
String.prototype.normalize() and the WHATWG URL parser, are fully
supported under system-icu. Features that require ICU locale data in
addition, such as Intl.DateTimeFormat may be fully or partially
supported, depending on the completeness of the ICU data installed on the
system.
Embed a limited set of ICU data (small-icu)#
This option makes the resulting binary link against the ICU library statically,
and includes a subset of ICU data (typically only the English locale) within
the node executable.
Functionalities that only require the ICU library itself, such as
String.prototype.normalize() and the WHATWG URL parser, are fully
supported under small-icu. Features that require ICU locale data in addition,
such as Intl.DateTimeFormat, generally only work with the English locale:
const january = new Date(9e8);
const english = new Intl.DateTimeFormat('en', { month: 'long' });
const spanish = new Intl.DateTimeFormat('es', { month: 'long' });
console.log(english.format(january));
// Prints "January"
console.log(spanish.format(january));
// Prints either "M01" or "January" on small-icu, depending on the user’s default locale
// Should print "enero"
This mode provides a balance between features and binary size.
Providing ICU data at runtime#
If the small-icu option is used, one can still provide additional locale data
at runtime so that the JS methods would work for all ICU locales. Assuming the
data file is stored at /runtime/directory/with/dat/file, it can be made
available to ICU through either:
-
The
--with-icu-default-data-dirconfigure option:./configure --with-icu-default-data-dir=/runtime/directory/with/dat/file --with-intl=small-icuThis only embeds the default data directory path into the binary. The actual data file is going to be loaded at runtime from this directory path.
-
The
NODE_ICU_DATAenvironment variable:env NODE_ICU_DATA=/runtime/directory/with/dat/file node -
The
--icu-data-dirCLI parameter:node --icu-data-dir=/runtime/directory/with/dat/file
When more than one of them is specified, the --icu-data-dir CLI parameter has
the highest precedence, then the NODE_ICU_DATA environment variable, then
the --with-icu-default-data-dir configure option.
ICU is able to automatically find and load a variety of data formats, but the
data must be appropriate for the ICU version, and the file correctly named.
The most common name for the data file is icudtX[bl].dat, where X denotes
the intended ICU version, and b or l indicates the system's endianness.
Node.js would fail to load if the expected data file cannot be read from the
specified directory. The name of the data file corresponding to the current
Node.js version can be computed with:
`icudt${process.versions.icu.split('.')[0]}${os.endianness()[0].toLowerCase()}.dat`;
Check "ICU Data" article in the ICU User Guide for other supported formats and more details on ICU data in general.
The full-icu npm module can greatly simplify ICU data installation by
detecting the ICU version of the running node executable and downloading the
appropriate data file. After installing the module through npm i full-icu,
the data file will be available at ./node_modules/full-icu. This path can be
then passed either to NODE_ICU_DATA or --icu-data-dir as shown above to
enable full Intl support.
Embed the entire ICU (full-icu)#
This option makes the resulting binary link against ICU statically and include
a full set of ICU data. A binary created this way has no further external
dependencies and supports all locales, but might be rather large. This is
the default behavior if no --with-intl flag is passed. The official binaries
are also built in this mode.
Detecting internationalization support#
To verify that ICU is enabled at all (system-icu, small-icu, or
full-icu), simply checking the existence of Intl should suffice:
const hasICU = typeof Intl === 'object';
Alternatively, checking for process.versions.icu, a property defined only
when ICU is enabled, works too:
const hasICU = typeof process.versions.icu === 'string';
To check for support for a non-English locale (i.e. full-icu or
system-icu), Intl.DateTimeFormat can be a good distinguishing factor:
const hasFullICU = (() => {
try {
const january = new Date(9e8);
const spanish = new Intl.DateTimeFormat('es', { month: 'long' });
return spanish.format(january) === 'enero';
} catch (err) {
return false;
}
})();
For more verbose tests for Intl support, the following resources may be found
to be helpful:
Iterable Streams#
Stability: 1 - Experimental – Enable this API with the --experimental-stream-iter CLI flag.
The node:stream/iter module provides a streaming API built on iterables
rather than the event-driven Readable/Writable/Transform class hierarchy,
or the Web Streams ReadableStream/WritableStream/TransformStream interfaces.
Streams are represented as <AsyncIterable> (async) or <Iterable> (sync). There
are no base classes to extend -- any
object implementing the iterable protocol can participate. Transforms are plain
functions or objects with a transform method.
Data flows in batches (<Uint8Array>[] per iteration) to amortize the cost
of async operations.
import { from, pull, text } from 'node:stream/iter'; import { compressGzip, decompressGzip } from 'node:zlib/iter'; // Compress and decompress a string const compressed = pull(from('Hello, world!'), compressGzip()); const result = await text(pull(compressed, decompressGzip())); console.log(result); // 'Hello, world!'const { from, pull, text } = require('node:stream/iter'); const { compressGzip, decompressGzip } = require('node:zlib/iter'); async function run() { // Compress and decompress a string const compressed = pull(from('Hello, world!'), compressGzip()); const result = await text(pull(compressed, decompressGzip())); console.log(result); // 'Hello, world!' } run().catch(console.error);
import { open } from 'node:fs/promises'; import { text, pipeTo } from 'node:stream/iter'; import { compressGzip, decompressGzip } from 'node:zlib/iter'; // Read a file, compress, write to another file const src = await open('input.txt', 'r'); const dst = await open('output.gz', 'w'); await pipeTo(src.pull(), compressGzip(), dst.writer({ autoClose: true })); await src.close(); // Read it back const gz = await open('output.gz', 'r'); console.log(await text(gz.pull(decompressGzip(), { autoClose: true })));const { open } = require('node:fs/promises'); const { text, pipeTo } = require('node:stream/iter'); const { compressGzip, decompressGzip } = require('node:zlib/iter'); async function run() { // Read a file, compress, write to another file const src = await open('input.txt', 'r'); const dst = await open('output.gz', 'w'); await pipeTo(src.pull(), compressGzip(), dst.writer({ autoClose: true })); await src.close(); // Read it back const gz = await open('output.gz', 'r'); console.log(await text(gz.pull(decompressGzip(), { autoClose: true }))); } run().catch(console.error);
Concepts#
Byte streams#
All data in this API is represented as <Uint8Array> bytes. Strings
are automatically UTF-8 encoded when passed to from(), push(), or
pipeTo(). This removes ambiguity around encodings and enables zero-copy
transfers between streams and native code.
Batching#
Each iteration yields a batch -- an <Array> of <Uint8Array> chunks
(<Uint8Array>[]). Batching amortizes the cost of await and <Promise> creation
across multiple chunks. A consumer that processes one chunk at a time can
simply iterate the inner array:
for await (const batch of source) { for (const chunk of batch) { handle(chunk); } }async function run() { for await (const batch of source) { for (const chunk of batch) { handle(chunk); } } }
Transforms#
Transforms come in two forms:
-
Stateless -- a function
(chunks, options) => resultcalled once per batch. ReceivesUint8Array[](ornullas the flush signal) and anoptionsobject. Returns<Uint8Array>[] |<null>|<Iterable>. -
Stateful -- an object
{ transform(source, options) }wheretransformis a generator (sync or async) that receives the entire upstream iterable and anoptionsobject, and yields output. This form is used for compression, encryption, and any transform that needs to buffer across batches.
Both forms receive an options parameter with the following property:
options.signal<AbortSignal>An AbortSignal that fires when the pipeline is cancelled, encounters an error, or the consumer stops reading. Transforms can checksignal.abortedor listen for the'abort'event to perform early cleanup.
The flush signal (null) is sent after the source ends, giving transforms
a chance to emit trailing data (e.g., compression footers).
// Stateless: uppercase transform
const upper = (chunks) => {
if (chunks === null) return null; // flush
return chunks.map((c) => new TextEncoder().encode(
new TextDecoder().decode(c).toUpperCase(),
));
};
// Stateful: line splitter
const lines = {
transform: async function*(source) {
let partial = '';
for await (const chunks of source) {
if (chunks === null) {
if (partial) yield [new TextEncoder().encode(partial)];
continue;
}
for (const chunk of chunks) {
const str = partial + new TextDecoder().decode(chunk);
const parts = str.split('\n');
partial = parts.pop();
for (const line of parts) {
yield [new TextEncoder().encode(`${line}\n`)];
}
}
}
},
};
Pull vs. push#
The API supports two models:
-
Pull -- data flows on demand.
pull()andpullSync()create lazy pipelines that only read from the source when the consumer iterates. -
Push -- data is written explicitly.
push()creates a writer/readable pair with backpressure. The writer pushes data in; the readable is consumed as an async iterable.
Backpressure#
Pull streams have natural backpressure -- the consumer drives the pace, so
the source is never read faster than the consumer can process. Push streams
need explicit backpressure because the producer and consumer run
independently. The budget and backpressure options on push(),
broadcast(), and share() control how this works.
The two-buffer model#
Push streams use a two-part buffering system. Think of it like a bucket (buffer) being filled through a hose (pending writes), with a float valve that closes when the bucket is full:
budget (e.g., 16384)
|
Producer v
| +---------+
v | |
[ write() ] ----+ +--->| buffer |---> Consumer pulls
[ write() ] | | | (bucket)| for await (...)
[ write() ] v | +---------+
+--------+ ^
| pending| |
| writes | float valve
| (hose) | (backpressure)
+--------+
^
|
'strict' mode limits this too!
-
Buffer (the bucket) -- data ready for the consumer, capped at
budgetbytes. When the consumer pulls, it drains all buffered data at once into a single batch. -
Pending writes (the hose) -- writes waiting for buffer space. After the consumer drains, pending writes are promoted into the now-empty buffer and their promises settle.
How each policy uses these buffers:
| Policy | Buffer limit | Pending writes limit |
|---|---|---|
'strict' |
budget |
1 |
'unbounded' |
budget |
Unbounded |
'drop-oldest' |
budget |
N/A (never waits) |
'drop-newest' |
budget |
N/A (never waits) |
Strict (default)#
Strict mode catches "fire-and-forget" patterns where the producer calls
write() without awaiting, which would cause unbounded memory growth.
It limits the buffer to budget bytes and the pending writes queue
to a single entry.
If you properly await each write, you can only ever have one pending write at a time (yours), so you never hit the pending writes limit. Unawaited writes accumulate in the pending queue and throw once it overflows:
import { push, text } from 'node:stream/iter'; const { writer, readable } = push({ budget: 16384 }); // Consumer must run concurrently -- without it, the first write // that fills the buffer blocks the producer forever. const consuming = text(readable); // GOOD: awaited writes. The producer waits for the consumer to // make room when the buffer is full. for (const item of dataset) { await writer.write(item); } await writer.end(); console.log(await consuming);const { push, text } = require('node:stream/iter'); async function run() { const { writer, readable } = push({ budget: 16384 }); // Consumer must run concurrently -- without it, the first write // that fills the buffer blocks the producer forever. const consuming = text(readable); // GOOD: awaited writes. The producer waits for the consumer to // make room when the buffer is full. for (const item of dataset) { await writer.write(item); } await writer.end(); console.log(await consuming); } run().catch(console.error);
Forgetting to await will eventually throw:
// BAD: fire-and-forget. Strict mode throws once both buffers fill.
for (const item of dataset) {
writer.write(item); // Not awaited -- queues without bound
}
// --> throws "Backpressure violation: too many pending writes"
Unbounded#
Unbounded mode caps buffered bytes at budget but places no limit on the
pending writes queue. Awaited writes block until the consumer makes room,
just like strict mode. The difference is that unawaited writes silently
queue forever instead of throwing -- a potential memory leak if the
producer forgets to await.
This is the mode that existing Node.js classic streams and Web Streams default to. Use it when you control the producer and know it awaits properly, or when migrating code from those APIs.
import { push, text } from 'node:stream/iter'; const { writer, readable } = push({ budget: 16384, backpressure: 'unbounded', }); const consuming = text(readable); // Safe -- awaited writes block until the consumer reads. for (const item of dataset) { await writer.write(item); } await writer.end(); console.log(await consuming);const { push, text } = require('node:stream/iter'); async function run() { const { writer, readable } = push({ budget: 16384, backpressure: 'unbounded', }); const consuming = text(readable); // Safe -- awaited writes block until the consumer reads. for (const item of dataset) { await writer.write(item); } await writer.end(); console.log(await consuming); } run().catch(console.error);
Drop-oldest#
Writes never wait. When the slots buffer is full, the oldest buffered chunk is evicted to make room for the incoming write. The consumer always sees the most recent data. Useful for live feeds, telemetry, or any scenario where stale data is less valuable than current data.
import { push } from 'node:stream/iter'; // Keep only the most recent ~16 KB of readings const { writer, readable } = push({ budget: 16384, backpressure: 'drop-oldest', });const { push } = require('node:stream/iter'); // Keep only the most recent ~16 KB of readings const { writer, readable } = push({ budget: 16384, backpressure: 'drop-oldest', });
Drop-newest#
Writes never wait. When the slots buffer is full, the incoming write is silently discarded. The consumer processes what is already buffered without being overwhelmed by new data. Useful for rate-limiting or shedding load under pressure.
import { push } from 'node:stream/iter'; // Accept up to 16 KB of buffered data; discard anything beyond that const { writer, readable } = push({ budget: 16384, backpressure: 'drop-newest', });const { push } = require('node:stream/iter'); // Accept up to 16 KB of buffered data; discard anything beyond that const { writer, readable } = push({ budget: 16384, backpressure: 'drop-newest', });
Writer interface#
A writer is any object conforming to the Writer interface. Only write() is
required; all other methods are optional.
Writer arguments use Web IDL conversion semantics. A non-Uint8Array chunk is
converted to a USVString and then UTF-8 encoded. writev() and
writevSync() accept any iterable object whose values can be converted to
chunks. Writer option dictionaries treat null as an empty dictionary and
ignore unknown members.
Each async method has a synchronous *Sync counterpart designed for a
try-fallback pattern: attempt the fast synchronous path first, and fall back
to the async version only when the synchronous call indicates it could not
complete:
if (!writer.writeSync(chunk)) await writer.write(chunk);
if (!writer.writevSync(chunks)) await writer.writev(chunks);
if (writer.endSync() < 0) await writer.end();
writer.fail(err); // Always synchronous, no fallback needed
writer.canWrite#
Returns true if the slots buffer has physical capacity (buffered data is
below the configured byte budget), false if the budget is exhausted, or
null if the writer is closed or the consumer has disconnected.
This reports physical capacity independently of the backpressure policy. With
'drop-oldest' or 'drop-newest', writes still complete when this is false
by evicting buffered data or discarding the incoming data, respectively.
This is a hint, not a guarantee: the state can change between the check and
the write. Use ondrain() to wait for capacity rather than polling.
writer.end([options])#
options<Object>signal<AbortSignal>Cancel just this operation. The signal cancels only the pendingend()call; it does not fail the writer itself.
- Returns:
<Promise>Fulfills with the total number of bytes written.
Signals that no more data will be written. Writes already waiting for buffer
space remain ordered before the end of the stream, while later writes fail. If
data is outstanding, the returned promise fulfills after the consumer pulls
done: true beyond the final batch. If no data is buffered or pending, the
writer closes immediately.
writer.endSync()#
- Returns:
<number>Total bytes written, or-1if ending cannot complete synchronously.
Synchronous variant of writer.end(). A return value of -1 only indicates
that the operation could not complete synchronously; no assumption can be made
about whether closing has started or why it could not complete. Use the
try-fallback pattern to await completion:
const result = writer.endSync();
if (result < 0) {
writer.end();
}
writer.fail([reason])#
reason<any>
Put the writer into a terminal error state. If the writer is already closed
or errored, this is a no-op. Unlike write() and end(), fail() is
unconditionally synchronous because failing a writer is a pure state
transition with no async work to perform. The reason is stored and propagated
without modification. If omitted, the reason is undefined.
writer[Symbol.asyncDispose]()#
If the writer is open, calls writer.fail(). If the writer is closing after
end() or endSync(), waits for buffered data to drain. If the writer is
already closed or errored, resolves immediately.
writer.write(chunk[, options])#
chunk<Uint8Array>|<string>options<Object>signal<AbortSignal>Cancel just this write operation. The signal cancels only the pendingwrite()call; it does not fail the writer itself.
- Returns:
<Promise>Fulfills withundefinedwhen buffer space is available.
Write a chunk.
writer.writeSync(chunk)#
chunk<Uint8Array>|<string>- Returns:
<boolean>trueif the write was accepted,falseif the buffer is full.
Synchronous write. Does not block; returns false if backpressure is active.
writer.writev(chunks[, options])#
chunks<Iterable>of<Uint8Array>|<string>valuesoptions<Object>signal<AbortSignal>Cancel just this write operation. The signal cancels only the pendingwritev()call; it does not fail the writer itself.
- Returns:
<Promise>
Write multiple chunks as a single batch.
writer.writevSync(chunks)#
chunks<Iterable>of<Uint8Array>|<string>values- Returns:
<boolean>trueif the write was accepted,falseif the buffer is full.
Synchronous batch write.
The stream/iter module#
Most functions are available both as named exports and as properties of the
Stream namespace object. The classic stream adapters (fromReadable(),
fromWritable(), toReadable(), toReadableSync(), and toWritable()) and
the static helper objects (Broadcast, Share, and SyncShare) are named
exports only.
// Named exports
import { from, pull, bytes, Stream } from 'node:stream/iter';
// Namespace access
Stream.from('hello');
Options dictionaries defined by the Iterable Streams API use Web IDL
conversion semantics. null is treated as an empty dictionary, unknown
members are ignored, and known members are converted to their declared types
before the operation runs. Conversion failures use Node.js error codes such as
ERR_INVALID_ARG_TYPE, ERR_INVALID_ARG_VALUE, and ERR_OUT_OF_RANGE.
// Named exports
const { from, pull, bytes, Stream } = require('node:stream/iter');
// Namespace access
Stream.from('hello');
Including the node: prefix on the module specifier is optional.
Sources#
from(input)#
input<string>|<ArrayBuffer>|<ArrayBufferView>|<Iterable>|<AsyncIterable>|<Object>Must not benullorundefined.- Returns:
<AsyncIterable>whose chunks fulfill with<Uint8Array>[].
Create an async byte stream from the given input. Strings are UTF-8 encoded.
ArrayBuffer and ArrayBufferView values are wrapped as Uint8Array. Arrays
and iterables in input are recursively flattened and normalized. Flattened
values may be split across implementation-defined bounded batches.
Objects implementing Symbol.for('Stream.toAsyncStreamable') or
Symbol.for('Stream.toStreamable') are converted via those protocols. The
toAsyncStreamable protocol takes precedence over toStreamable, which takes
precedence over the iteration protocols (Symbol.asyncIterator,
Symbol.iterator).
import { Buffer } from 'node:buffer'; import { from, text } from 'node:stream/iter'; console.log(await text(from('hello'))); // 'hello' console.log(await text(from(Buffer.from('hello')))); // 'hello'const { Buffer } = require('node:buffer'); const { from, text } = require('node:stream/iter'); async function run() { console.log(await text(from('hello'))); // 'hello' console.log(await text(from(Buffer.from('hello')))); // 'hello' } run().catch(console.error);
fromSync(input)#
input<string>|<ArrayBuffer>|<ArrayBufferView>|<Iterable>|<Object>Must not benullorundefined.- Returns:
<Iterable>whose chunks return<Uint8Array>[]
Synchronous version of from(). Returns a sync iterable. Cannot accept
async iterables or promises. Objects implementing
Symbol.for('Stream.toStreamable') are converted via that protocol (takes
precedence over Symbol.iterator). The toAsyncStreamable protocol is
ignored entirely.
import { fromSync, textSync } from 'node:stream/iter'; console.log(textSync(fromSync('hello'))); // 'hello'const { fromSync, textSync } = require('node:stream/iter'); console.log(textSync(fromSync('hello'))); // 'hello'
Pipelines#
pipeTo(source[, ...transforms], writer[, options])#
source<AsyncIterable>|<Iterable>The data source....transforms<Function>|<Object>Zero or more transforms to apply.writer<Object>Destination withwrite(chunk)method.options<Object>signal<AbortSignal>Abort the pipeline. Aborting fails the destination writer unlesspreventFailistrue.preventClose<boolean>Iftrue, do not callwriter.end()when the source ends. Default:false.preventFail<boolean>Iftrue, do not callwriter.fail()on error. Default:false.
- Returns:
<Promise>Fulfills with the total number of bytes written.
Pipe a source through transforms into a writer. If the writer has a
writev(chunks) method, entire batches are passed in a single call (enabling
scatter/gather I/O).
If the writer implements the optional *Sync methods (writeSync, writevSync,
endSync), pipeTo() will attempt to use the synchronous methods
first as a fast path, and fall back to the async versions only when the sync
methods indicate they cannot complete (e.g., backpressure or waiting for the
next tick). fail() is always called synchronously.
import { from, pipeTo } from 'node:stream/iter'; import { compressGzip } from 'node:zlib/iter'; import { open } from 'node:fs/promises'; const fh = await open('output.gz', 'w'); const totalBytes = await pipeTo( from('Hello, world!'), compressGzip(), fh.writer({ autoClose: true }), );const { from, pipeTo } = require('node:stream/iter'); const { compressGzip } = require('node:zlib/iter'); const { open } = require('node:fs/promises'); async function run() { const fh = await open('output.gz', 'w'); const totalBytes = await pipeTo( from('Hello, world!'), compressGzip(), fh.writer({ autoClose: true }), ); } run().catch(console.error);
pipeToSync(source[, ...transforms], writer[, options])#
source<Iterable>The sync data source....transforms<Function>|<Object>Zero or more sync transforms.writer<Object>Destination withwrite(chunk)method.options<Object>- Returns:
<number>Total bytes written.
Synchronous version of pipeTo(). The source, all transforms, and the
writer must be synchronous. Cannot accept async iterables or promises.
The writer must have the *Sync methods (writeSync, writevSync,
endSync) and fail() for this to work.
pull(source[, ...transforms][, options])#
source<AsyncIterable>|<Iterable>The data source....transforms<Function>|<Object>Zero or more transforms to apply.options<Object>signal<AbortSignal>Abort the pipeline.
- Returns:
<AsyncIterable>whose chunks fulfill with<Uint8Array>[]
Create a lazy async pipeline. Source conversion and streamable protocol
dispatch occur when pull() is called, but data is not read from source
until the returned iterable is consumed. A signal that is already aborted is
thrown synchronously after source conversion. Transforms are applied in order.
import { from, pull, text } from 'node:stream/iter'; const asciiUpper = (chunks) => { if (chunks === null) return null; return chunks.map((c) => { for (let i = 0; i < c.length; i++) { c[i] -= (c[i] >= 97 && c[i] <= 122) * 32; } return c; }); }; const result = pull(from('hello'), asciiUpper); console.log(await text(result)); // 'HELLO'const { from, pull, text } = require('node:stream/iter'); const asciiUpper = (chunks) => { if (chunks === null) return null; return chunks.map((c) => { for (let i = 0; i < c.length; i++) { c[i] -= (c[i] >= 97 && c[i] <= 122) * 32; } return c; }); }; async function run() { const result = pull(from('hello'), asciiUpper); console.log(await text(result)); // 'HELLO' } run().catch(console.error);
Using an AbortSignal:
import { pull } from 'node:stream/iter'; const ac = new AbortController(); const result = pull(source, transform, { signal: ac.signal }); ac.abort(); // Pipeline throws AbortError on next iterationconst { pull } = require('node:stream/iter'); const ac = new AbortController(); const result = pull(source, transform, { signal: ac.signal }); ac.abort(); // Pipeline throws AbortError on next iteration
pullSync(source[, ...transforms])#
source<Iterable>The sync data source....transforms<Function>|<Object>Zero or more sync transforms.- Returns:
<Iterable>whose chunks return<Uint8Array>[]
Synchronous version of pull(). Source conversion and streamable protocol
dispatch occur when pullSync() is called. All transforms must be synchronous.
Push streams#
push([...transforms][, options])#
...transforms<Function>|<Object>Optional transforms applied to the readable side.options<Object>budget<number>Maximum number of buffered bytes before backpressure is applied. Must be >= 16384. Default:16384.backpressure<string>Backpressure policy:'strict','unbounded','drop-oldest', or'drop-newest'. Default:'strict'.signal<AbortSignal>Abort the stream. The signal remains active while buffered data drains afterwriter.end(); aborting during that time fails the writer and rejects the pendingend()promise.
- Returns:
<Object>writer<Writable>The writer side.readable<AsyncIterable>whose chunks fulfill with<Uint8Array>[]
Create a push stream with backpressure. The writer pushes data in; the readable side is consumed as an async iterable.
import { push, text } from 'node:stream/iter'; const { writer, readable } = push(); // Producer and consumer must run concurrently. With strict backpressure // (the default), awaited writes block until the consumer reads. const producing = (async () => { await writer.write('hello'); await writer.write(' world'); await writer.end(); })(); console.log(await text(readable)); // 'hello world' await producing;const { push, text } = require('node:stream/iter'); async function run() { const { writer, readable } = push(); // Producer and consumer must run concurrently. With strict backpressure // (the default), awaited writes block until the consumer reads. const producing = (async () => { await writer.write('hello'); await writer.write(' world'); await writer.end(); })(); console.log(await text(readable)); // 'hello world' await producing; } run().catch(console.error);
The writer returned by push() conforms to the [Writer interface][].
Duplex channels#
duplex([options])#
options<Object>budget<number>Buffer size in bytes for both directions. Must be >= 16384. Default:16384.backpressure<string>Policy for both directions. Default:'strict'.signal<AbortSignal>Cancellation signal for both channels.a<Object>Options specific to the A-to-B direction. Overrides shared options.b<Object>Options specific to the B-to-A direction. Overrides shared options.
- Returns:
<Array>A pair[channelA, channelB]of duplex channels.
Create a pair of connected duplex channels for bidirectional communication,
similar to socketpair(). Data written to one channel's writer appears in
the other channel's readable.
Each channel has:
writer— a [Writer interface][] object for sending data to the peer.readable— an<AsyncIterable>for reading data from the peer.close()— close this end of the channel (idempotent).[Symbol.asyncDispose]()— async dispose support forawait using.
import { duplex, text } from 'node:stream/iter'; const [client, server] = duplex(); // Server echoes back const serving = (async () => { for await (const chunks of server.readable) { await server.writer.writev(chunks); } await server.writer.end(); })(); await client.writer.write('hello'); await client.writer.end(); console.log(await text(client.readable)); // 'hello' await serving;const { duplex, text } = require('node:stream/iter'); async function run() { const [client, server] = duplex(); // Server echoes back const serving = (async () => { for await (const chunks of server.readable) { await server.writer.writev(chunks); } await server.writer.end(); })(); await client.writer.write('hello'); await client.writer.end(); console.log(await text(client.readable)); // 'hello' await serving; } run().catch(console.error);
Consumers#
array(source[, options])#
source<AsyncIterable>|<Iterable>whose chunks must be<Uint8Array>[]options<Object>signal<AbortSignal>limit<number>Maximum number of bytes to consume. If the total bytes collected exceeds limit, anERR_OUT_OF_RANGEerror is thrown
- Returns:
<Promise>Fulfills with an array ofUint8Arrayobjects.
Collect all chunks as an array of Uint8Array values (without concatenating).
arrayBuffer(source[, options])#
source<AsyncIterable>|<Iterable>whose chunks must be<Uint8Array>[]options<Object>signal<AbortSignal>limit<number>Maximum number of bytes to consume. If the total bytes collected exceeds limit, anERR_OUT_OF_RANGEerror is thrown
- Returns:
<Promise>Fulfills with anArrayBufferobject.
Collect all bytes into an ArrayBuffer.
arrayBufferSync(source[, options])#
source<Iterable>whose chunks must be<Uint8Array>[]options<Object>limit<number>Maximum number of bytes to consume. If the total bytes collected exceeds limit, anERR_OUT_OF_RANGEerror is thrown
- Returns:
<ArrayBuffer>
Synchronous version of arrayBuffer().
arraySync(source[, options])#
source<Iterable>whose chunks must be<Uint8Array>[]options<Object>limit<number>Maximum number of bytes to consume. If the total bytes collected exceeds limit, anERR_OUT_OF_RANGEerror is thrown
- Returns:
<Uint8Array>[]
Synchronous version of array().
bytes(source[, options])#
source<AsyncIterable>|<Iterable>whose chunks must be<Uint8Array>[]options<Object>signal<AbortSignal>limit<number>Maximum number of bytes to consume. If the total bytes collected exceeds limit, anERR_OUT_OF_RANGEerror is thrown
- Returns:
<Promise>Fulfills with anUint8Arrayobject.
Collect all bytes from a stream into a single Uint8Array.
import { from, bytes } from 'node:stream/iter'; const data = await bytes(from('hello')); console.log(data); // Uint8Array(5) [ 104, 101, 108, 108, 111 ]const { from, bytes } = require('node:stream/iter'); async function run() { const data = await bytes(from('hello')); console.log(data); // Uint8Array(5) [ 104, 101, 108, 108, 111 ] } run().catch(console.error);
bytesSync(source[, options])#
source<Iterable>whose chunks must be<Uint8Array>[]options<Object>limit<number>Maximum number of bytes to consume. If the total bytes collected exceeds limit, anERR_OUT_OF_RANGEerror is thrown
- Returns:
<Uint8Array>
Synchronous version of bytes().
text(source[, options])#
source<AsyncIterable>|<Iterable>whose chunks must be<Uint8Array>[]options<Object>encoding<string>Text encoding. Default:'utf-8'.signal<AbortSignal>limit<number>Maximum number of bytes to consume. If the total bytes collected exceeds limit, anERR_OUT_OF_RANGEerror is thrown
- Returns:
<Promise>Fulfills with astring.
Collect all bytes and decode as text.
import { from, text } from 'node:stream/iter'; console.log(await text(from('hello'))); // 'hello'const { from, text } = require('node:stream/iter'); async function run() { console.log(await text(from('hello'))); // 'hello' } run().catch(console.error);
textSync(source[, options])#
source<Iterable>whose chunks must be<Uint8Array>[]options<Object>- Returns:
<string>
Synchronous version of text().
Utilities#
ondrain(drainable)#
Wait for a drainable writer to regain physical buffer capacity. Returns null
if the object does not implement the drainable protocol, or a promise that
fulfills with true when buffered data falls below the byte budget.
For writers using 'drop-oldest' or 'drop-newest', this waits for physical
capacity even though writes do not block. This allows producers to avoid data
loss by waiting before writing.
import { push, ondrain, text } from 'node:stream/iter'; const { writer, readable } = push({ budget: 16384 }); const chunk = new Uint8Array(8192); // 8 KB writer.writeSync(chunk); writer.writeSync(chunk); // 16 KB total -- buffer full // Start consuming so the buffer can actually drain const consuming = text(readable); // Buffer is full -- wait for drain const canWrite = await ondrain(writer); if (canWrite) { await writer.write('c'); } await writer.end(); await consuming;const { push, ondrain, text } = require('node:stream/iter'); async function run() { const { writer, readable } = push({ budget: 16384 }); const chunk = new Uint8Array(8192); // 8 KB writer.writeSync(chunk); writer.writeSync(chunk); // 16 KB total -- buffer full // Start consuming so the buffer can actually drain const consuming = text(readable); // Buffer is full -- wait for drain const canWrite = await ondrain(writer); if (canWrite) { await writer.write('c'); } await writer.end(); await consuming; } run().catch(console.error);
merge(...sources[, options])#
...sources<AsyncIterable>|<Iterable>whose chunks must be<Uint8Array>[]options<Object>signal<AbortSignal>
- Returns:
<AsyncIterable>whose chunks fulfill with<Uint8Array>[]
Merge multiple async iterables by yielding batches in temporal order (whichever source produces data first). All sources are consumed concurrently.
import { from, merge, text } from 'node:stream/iter'; const merged = merge(from('hello '), from('world')); console.log(await text(merged)); // Order depends on timingconst { from, merge, text } = require('node:stream/iter'); async function run() { const merged = merge(from('hello '), from('world')); console.log(await text(merged)); // Order depends on timing } run().catch(console.error);
tap(callback)#
callback<Function>(chunks) => voidCalled with each batch and withnullwhen the source ends.- Returns:
<Function>A stateless transform.
Create a pass-through transform that observes batches without modifying them. Useful for logging, metrics, or debugging.
import { from, pull, text, tap } from 'node:stream/iter'; const result = pull( from('hello'), tap((chunks) => { if (chunks !== null) console.log('Batch size:', chunks.length); }), ); console.log(await text(result));const { from, pull, text, tap } = require('node:stream/iter'); async function run() { const result = pull( from('hello'), tap((chunks) => { if (chunks !== null) console.log('Batch size:', chunks.length); }), ); console.log(await text(result)); } run().catch(console.error);
tap() intentionally does not prevent in-place modification of the
chunks by the tapping callback; but return values are ignored.
tapSync(callback)#
callback<Function>- Returns:
<Function>
Synchronous version of tap().
Multi-consumer#
broadcast([options])#
options<Object>budget<number>Buffer size in bytes. Must be >= 16384. Default:65536.backpressure<string>'strict','unbounded','drop-oldest', or'drop-newest'. Default:'strict'.signal<AbortSignal>
- Returns:
<Object>writer<Writable>broadcast<BroadcastChannel>
Create a push-model multi-consumer broadcast channel. A single writer pushes data to multiple consumers. Each consumer has an independent cursor into a shared buffer.
import { broadcast, text } from 'node:stream/iter'; const { writer, broadcast: bc } = broadcast(); // Create consumers before writing const c1 = bc.push(); // Consumer 1 const c2 = bc.push(); // Consumer 2 // Producer and consumers must run concurrently. Awaited writes // block when the buffer fills until consumers read. const producing = (async () => { await writer.write('hello'); await writer.end(); })(); const [r1, r2] = await Promise.all([text(c1), text(c2)]); console.log(r1); // 'hello' console.log(r2); // 'hello' await producing;const { broadcast, text } = require('node:stream/iter'); async function run() { const { writer, broadcast: bc } = broadcast(); // Create consumers before writing const c1 = bc.push(); // Consumer 1 const c2 = bc.push(); // Consumer 2 // Producer and consumers must run concurrently. Awaited writes // block when the buffer fills until consumers read. const producing = (async () => { await writer.write('hello'); await writer.end(); })(); const [r1, r2] = await Promise.all([text(c1), text(c2)]); console.log(r1); // 'hello' console.log(r2); // 'hello' await producing; } run().catch(console.error);
broadcast.cancel([reason])#
reason<any>
Cancel the broadcast. If reason is provided, all consumers reject with that
exact reason. If it is omitted, consumers complete normally.
broadcast.consumerCount#
The number of active consumers.
broadcast.push([...transforms][, options])#
...transforms<Function>|<Object>options<Object>signal<AbortSignal>
- Returns:
<AsyncIterable>whose chunks fulfill with<Uint8Array>[]
Create a new consumer. Optional transforms are applied to this consumer's view of the data.
broadcast[Symbol.dispose]()#
Alias for broadcast.cancel().
Broadcast.from(input[, options])#
input<AsyncIterable>|<Iterable>|<BroadcastChannel>options<Object>Same asbroadcast().- Returns:
<BroadcastChannel>|<Object>AbroadcastProtocolinput returns its<BroadcastChannel>directly. Other inputs return{ writer, broadcast }.
Create a <BroadcastChannel> from an existing source. The source is consumed
automatically and pushed to all subscribers.
share(source[, options])#
source<AsyncIterable>The source to share.options<Object>budget<number>Buffer size in bytes. Must be >= 16384. Default:65536.backpressure<string>'strict','unbounded','drop-oldest', or'drop-newest'. Default:'strict'.signal<AbortSignal>
- Returns:
<Share>
Create a pull-model multi-consumer shared stream. Unlike broadcast(), the
source is only read when a consumer pulls. Multiple consumers share a single
buffer.
import { from, share, text } from 'node:stream/iter'; const shared = share(from('hello')); const c1 = shared.pull(); const c2 = shared.pull(); // Consume concurrently to avoid deadlock with small buffers. const [r1, r2] = await Promise.all([text(c1), text(c2)]); console.log(r1); // 'hello' console.log(r2); // 'hello'const { from, share, text } = require('node:stream/iter'); async function run() { const shared = share(from('hello')); const c1 = shared.pull(); const c2 = shared.pull(); // Consume concurrently to avoid deadlock with small buffers. const [r1, r2] = await Promise.all([text(c1), text(c2)]); console.log(r1); // 'hello' console.log(r2); // 'hello' } run().catch(console.error);
Class: Share#
Static method: Share.from(input[, options])#
input<AsyncIterable>|<Shareable>options<Object>Same asshare().- Returns:
<Share>
Create a <Share> from an existing source.
share.cancel([reason])#
reason<any>
Cancel the share. If reason is provided, all consumers reject with that exact
reason. If it is omitted, consumers complete normally.
share.consumerCount#
The number of active consumers.
share.pull([...transforms][, options])#
...transforms<Function>|<Object>options<Object>signal<AbortSignal>
- Returns:
<AsyncIterable>whose chunks fulfill with<Uint8Array>[]
Create a new consumer of the shared source.
share[Symbol.dispose]()#
Alias for share.cancel().
Interface: Shareable#
sharable[Symbol.for('Stream.shareProtocol')]#
<Function>that returns a<Share>.
Interface: SyncShareable#
sharable[Symbol.for('Stream.shareSyncProtocol')]#
<Function>that returns a<SyncShare>.
shareSync(source[, options])#
source<Iterable>The sync source to share.options<Object>- Returns:
<SyncShare>
Synchronous version of share().
Because there is no way to wait in a synchronous context, 'unbounded' is not
supported and throws ERR_INVALID_ARG_VALUE. With 'drop-newest', a consumer
that reaches the end of the buffer while the budget is exhausted discards a
single entry from the source and then returns { done: true } without a
value; the consumer is not detached, so it can resume once the slowest
consumer advances and releases budget.
Class: SyncShare#
Static method: SyncShare.fromSync(input[, options])#
input<Iterable>|<SyncShareable>options<Object>- Returns:
<SyncShare>
share.cancel([reason])#
reason<any>
Cancel the share. If reason is provided, all consumers throw that exact
reason. If it is omitted, consumers complete normally.
share.consumerCount#
The number of active consumers.
share.pull([...transforms])#
...transforms<Function>|<Object>- Returns:
<Iterable>whose chunks return<Uint8Array>[]
Create a new consumer of the shared source.
share[Symbol.dispose]()#
Alias for share.cancel().
Compression and decompression transforms#
Compression and decompression transforms for use with pull(), pullSync(),
pipeTo(), and pipeToSync() are available via the node:zlib/iter
module. See the node:zlib/iter documentation for details.
Classic stream interop#
These utility functions bridge between classic
stream.Readable/stream.Writable streams and the stream/iter
API.
Both fromReadable() and fromWritable() accept duck-typed objects -- they
do not require the input to extend stream.Readable or stream.Writable
directly. The minimum contract is described below for each function.
fromReadable(readable)#
Stability: 1 - Experimental
readable<stream.Readable>|<Object>A classic Readable stream or a compatible object withread(),pipe(),destroy(),on(), andremoveListener()methods.- Returns:
<AsyncIterable>whose chunks fulfill with<Uint8Array>[]
Converts a classic Readable stream (or duck-typed equivalent) into a
stream/iter async iterable source that can be passed to from(),
pull(), text(), etc.
If the object implements the toAsyncStreamable protocol (as
stream.Readable does), that protocol is used. Otherwise, the function
duck-types on read(), pipe(), destroy(), on(), and removeListener()
(EventEmitter) and wraps the stream with a batched async iterator.
The result is cached per instance -- calling fromReadable() twice with the
same stream returns the same iterable.
For object-mode or encoded Readable streams, chunks are automatically
normalized to Uint8Array.
import { Readable } from 'node:stream'; import { fromReadable, text } from 'node:stream/iter'; const readable = new Readable({ read() { this.push('hello world'); this.push(null); }, }); const result = await text(fromReadable(readable)); console.log(result); // 'hello world'const { Readable } = require('node:stream'); const { fromReadable, text } = require('node:stream/iter'); const readable = new Readable({ read() { this.push('hello world'); this.push(null); }, }); async function run() { const result = await text(fromReadable(readable)); console.log(result); // 'hello world' } run();
fromWritable(writable[, options])#
Stability: 1 - Experimental
writable<stream.Writable>|<Object>A classic Writable stream or a compatible object withwrite(),end(),destroy(),on(), andremoveListener()methods.options<Object>backpressure<string>Backpressure policy. Default:'strict'.'strict'-- one write may wait while the buffer is full. Further writes are rejected until it is accepted or canceled.'unbounded'-- writes are queued while the buffer is full. Recommended for use withpipeTo().'drop-newest'-- writes are silently discarded when the buffer is full.'drop-oldest'-- not supported. ThrowsERR_INVALID_ARG_VALUE.
- Returns:
<Object>A stream/iter Writer adapter.
Creates a stream/iter Writer adapter from a classic Writable stream (or
duck-typed equivalent). The adapter can be passed to pipeTo() as a
destination.
Since all writes on a classic Writable are fundamentally asynchronous,
the synchronous Writer methods (writeSync, writevSync, endSync) always
return false or -1, deferring to the async path. A queued write() or
writev() can be canceled with its options.signal before it reaches the
classic Writable.
If writer.fail(reason) receives a non-Error reason, the classic Writable is
destroyed with an ERR_FALSY_VALUE_REJECTION or ERR_OPERATION_FAILED error.
Its reason property contains the original value, which remains the Writer's
stored failure reason.
The result is cached per instance and backpressure policy -- calling
fromWritable() twice with the same stream and backpressure option returns
the same Writer.
For duck-typed streams that do not expose writableHighWaterMark,
writableLength, or similar properties, sensible defaults are used.
Object-mode writables (if detectable) are rejected since the Writer
interface is bytes-only.
import { Writable } from 'node:stream'; import { from, fromWritable, pipeTo } from 'node:stream/iter'; const writable = new Writable({ write(chunk, encoding, cb) { console.log(chunk.toString()); cb(); }, }); await pipeTo(from('hello world'), fromWritable(writable, { backpressure: 'unbounded' }));const { Writable } = require('node:stream'); const { from, fromWritable, pipeTo } = require('node:stream/iter'); async function run() { const writable = new Writable({ write(chunk, encoding, cb) { console.log(chunk.toString()); cb(); }, }); await pipeTo(from('hello world'), fromWritable(writable, { backpressure: 'unbounded' })); } run();
toReadable(source[, options])#
Stability: 1 - Experimental
source<AsyncIterable>whose chunks must fulfill with<Uint8Array>[] the return value ofpull()orfrom().options<Object>highWaterMark<number>The internal buffer size in bytes before backpressure is applied. Default:65536(64 KB).signal<AbortSignal>An optional signal to abort the readable.
- Returns:
<stream.Readable>
Creates a byte-mode stream.Readable from the source
(the native batch format used by the stream/iter API). Each Uint8Array in a
yielded batch is pushed as a separate chunk into the Readable.
Classic streams cannot represent arbitrary values as emitted errors. A
non-Error reason is wrapped in an ERR_FALSY_VALUE_REJECTION or
ERR_OPERATION_FAILED error whose reason property contains the original
value.
import { createWriteStream } from 'node:fs'; import { from, pull, toReadable } from 'node:stream/iter'; import { compressGzip } from 'node:zlib/iter'; const source = pull(from('hello world'), compressGzip()); const readable = toReadable(source); readable.pipe(createWriteStream('output.gz'));const { createWriteStream } = require('node:fs'); const { from, pull, toReadable } = require('node:stream/iter'); const { compressGzip } = require('node:zlib/iter'); const source = pull(from('hello world'), compressGzip()); const readable = toReadable(source); readable.pipe(createWriteStream('output.gz'));
toReadableSync(source[, options])#
Stability: 1 - Experimental
source<Iterable>whose chunks must return<Uint8Array>[], such as the return value ofpullSync()orfromSync().options<Object>highWaterMark<number>The internal buffer size in bytes before backpressure is applied. Default:65536(64 KB).
- Returns:
<stream.Readable>
Creates a byte-mode stream.Readable from the source.
The _read() method pulls from the iterator
synchronously, so data is available immediately via readable.read().
import { fromSync, toReadableSync } from 'node:stream/iter'; const source = fromSync('hello world'); const readable = toReadableSync(source); console.log(readable.read().toString()); // 'hello world'const { fromSync, toReadableSync } = require('node:stream/iter'); const source = fromSync('hello world'); const readable = toReadableSync(source); console.log(readable.read().toString()); // 'hello world'
toWritable(writer)#
Stability: 1 - Experimental
writer<Object>A stream/iter Writer. Only thewrite()method is required;end(),fail(),writeSync(),writevSync(),endSync(), andwritev()are optional.- Returns:
<stream.Writable>
Creates a classic stream.Writable backed by a stream/iter Writer.
Each _write() / _writev() call attempts the Writer's synchronous method
first (writeSync / writevSync), falling back to the async method if the
sync path returns false. Similarly, _final() tries endSync()
before end(). When the sync path succeeds, the callback is deferred via
queueMicrotask to preserve the async resolution contract.
Classic stream callbacks cannot represent arbitrary values as errors. A
non-Error reason is wrapped in an ERR_FALSY_VALUE_REJECTION or
ERR_OPERATION_FAILED error before it is passed to the callback. The error's
reason property contains the original value.
Destroying the Writable before successful completion calls writer.fail().
If fail() is unavailable, Symbol.dispose or Symbol.asyncDispose is used
when implemented by the Writer.
The Writable uses the default classic stream highWaterMark. Classic stream
backpressure bounds writes waiting to reach the underlying Writer, while the
Writer controls completion of the active _write() or _writev() operation.
import { push, toWritable } from 'node:stream/iter'; const { writer, readable } = push(); const writable = toWritable(writer); writable.write('hello'); writable.end();const { push, toWritable } = require('node:stream/iter'); const { writer, readable } = push(); const writable = toWritable(writer); writable.write('hello'); writable.end();
Protocol symbols#
These well-known symbols allow third-party objects to participate in the
streaming protocol without importing from node:stream/iter directly.
Stream.broadcastProtocol#
- Value:
Symbol.for('Stream.broadcastProtocol')
The value must be a function. When called by Broadcast.from(), it receives
the options passed to Broadcast.from() and must return an object conforming
to the <BroadcastChannel> interface. The implementation is fully custom -- it can
manage consumers, buffering, and backpressure however it wants.
import { broadcast as createBroadcast, Broadcast, text, } from 'node:stream/iter'; // This example defers to the built-in Broadcast, but a custom // implementation could use any mechanism. class MessageBus { #broadcast; #writer; constructor() { const { writer, broadcast } = createBroadcast(); this.#writer = writer; this.#broadcast = broadcast; } [Symbol.for('Stream.broadcastProtocol')](options) { return this.#broadcast; } send(data) { this.#writer.write(new TextEncoder().encode(data)); } close() { this.#writer.end(); } } const bus = new MessageBus(); const broadcast = Broadcast.from(bus); const consumer = broadcast.push(); bus.send('hello'); bus.close(); console.log(await text(consumer)); // 'hello'const { broadcast: createBroadcast, Broadcast, text, } = require('node:stream/iter'); // This example defers to the built-in Broadcast, but a custom // implementation could use any mechanism. class MessageBus { #broadcast; #writer; constructor() { const { writer, broadcast } = createBroadcast(); this.#writer = writer; this.#broadcast = broadcast; } [Symbol.for('Stream.broadcastProtocol')](options) { return this.#broadcast; } send(data) { this.#writer.write(new TextEncoder().encode(data)); } close() { this.#writer.end(); } } const bus = new MessageBus(); const broadcast = Broadcast.from(bus); const consumer = broadcast.push(); bus.send('hello'); bus.close(); text(consumer).then(console.log); // 'hello'
Stream.drainableProtocol#
- Value:
Symbol.for('Stream.drainableProtocol')
Implement to make a writer compatible with ondrain(). The method should
return null if no backpressure, or a promise that fulfills with a truthy value
when backpressure clears.
import { ondrain } from 'node:stream/iter'; class CustomWriter { #queue = []; #drain = null; #closed = false; [Symbol.for('Stream.drainableProtocol')]() { if (this.#closed) return null; if (this.#queue.length < 3) return Promise.resolve(true); this.#drain ??= Promise.withResolvers(); return this.#drain.promise; } write(chunk) { this.#queue.push(chunk); } flush() { this.#queue.length = 0; this.#drain?.resolve(true); this.#drain = null; } close() { this.#closed = true; } } const writer = new CustomWriter(); const ready = ondrain(writer); console.log(ready); // Promise { true } -- no backpressureconst { ondrain } = require('node:stream/iter'); class CustomWriter { #queue = []; #drain = null; #closed = false; [Symbol.for('Stream.drainableProtocol')]() { if (this.#closed) return null; if (this.#queue.length < 3) return Promise.resolve(true); this.#drain ??= Promise.withResolvers(); return this.#drain.promise; } write(chunk) { this.#queue.push(chunk); } flush() { this.#queue.length = 0; this.#drain?.resolve(true); this.#drain = null; } close() { this.#closed = true; } } const writer = new CustomWriter(); const ready = ondrain(writer); console.log(ready); // Promise { true } -- no backpressure
Stream.shareProtocol#
- Value:
Symbol.for('Stream.shareProtocol')
The value must be a function. When called by Share.from(), it receives the
options passed to Share.from() and must return an object conforming to the
<Share> interface. The implementation is fully custom -- it can manage the shared
source, consumers, buffering, and backpressure however it wants.
import { share, Share, text } from 'node:stream/iter'; // This example defers to the built-in share(), but a custom // implementation could use any mechanism. class DataPool { #share; constructor(source) { this.#share = share(source); } [Symbol.for('Stream.shareProtocol')](options) { return this.#share; } } const pool = new DataPool( (async function* () { yield 'hello'; })(), ); const shared = Share.from(pool); const consumer = shared.pull(); console.log(await text(consumer)); // 'hello'const { share, Share, text } = require('node:stream/iter'); // This example defers to the built-in share(), but a custom // implementation could use any mechanism. class DataPool { #share; constructor(source) { this.#share = share(source); } [Symbol.for('Stream.shareProtocol')](options) { return this.#share; } } const pool = new DataPool( (async function* () { yield 'hello'; })(), ); const shared = Share.from(pool); const consumer = shared.pull(); text(consumer).then(console.log); // 'hello'
Stream.shareSyncProtocol#
- Value:
Symbol.for('Stream.shareSyncProtocol')
The value must be a function. When called by SyncShare.fromSync(), it receives
the options passed to SyncShare.fromSync() and must return an object conforming
to the <SyncShare> interface. The implementation is fully custom -- it can manage
the shared source, consumers, and buffering however it wants.
import { shareSync, SyncShare, textSync } from 'node:stream/iter'; // This example defers to the built-in shareSync(), but a custom // implementation could use any mechanism. class SyncDataPool { #share; constructor(source) { this.#share = shareSync(source); } [Symbol.for('Stream.shareSyncProtocol')](options) { return this.#share; } } const encoder = new TextEncoder(); const pool = new SyncDataPool( function* () { yield [encoder.encode('hello')]; }(), ); const shared = SyncShare.fromSync(pool); const consumer = shared.pull(); console.log(textSync(consumer)); // 'hello'const { shareSync, SyncShare, textSync } = require('node:stream/iter'); // This example defers to the built-in shareSync(), but a custom // implementation could use any mechanism. class SyncDataPool { #share; constructor(source) { this.#share = shareSync(source); } [Symbol.for('Stream.shareSyncProtocol')](options) { return this.#share; } } const encoder = new TextEncoder(); const pool = new SyncDataPool( function* () { yield [encoder.encode('hello')]; }(), ); const shared = SyncShare.fromSync(pool); const consumer = shared.pull(); console.log(textSync(consumer)); // 'hello'
Stream.toAsyncStreamable#
- Value:
Symbol.for('Stream.toAsyncStreamable')
The value must be a function that converts the object into a streamable value.
When the object is passed to from(), this method is called to produce the
actual data. It may return any value that resolves to a string, Uint8Array,
AsyncIterable, Iterable, or another streamable object.
import { from, text } from 'node:stream/iter'; class Greeting { #name; constructor(name) { this.#name = name; } [Symbol.for('Stream.toAsyncStreamable')]() { return `hello ${this.#name}`; } } const stream = from(new Greeting('world')); console.log(await text(stream)); // 'hello world'const { from, text } = require('node:stream/iter'); class Greeting { #name; constructor(name) { this.#name = name; } [Symbol.for('Stream.toAsyncStreamable')]() { return `hello ${this.#name}`; } } const stream = from(new Greeting('world')); text(stream).then(console.log); // 'hello world'
Stream.toStreamable#
- Value:
Symbol.for('Stream.toStreamable')
The value must be a function that synchronously converts the object into a
streamable value. When the object is passed to fromSync(), this method is
called to produce the actual data. It must synchronously return a streamable
value: a string, Uint8Array, or Iterable.
import { fromSync, textSync } from 'node:stream/iter'; class Greeting { #name; constructor(name) { this.#name = name; } [Symbol.for('Stream.toStreamable')]() { return `hello ${this.#name}`; } } const stream = fromSync(new Greeting('world')); console.log(textSync(stream)); // 'hello world'const { fromSync, textSync } = require('node:stream/iter'); class Greeting { #name; constructor(name) { this.#name = name; } [Symbol.for('Stream.toStreamable')]() { return `hello ${this.#name}`; } } const stream = fromSync(new Greeting('world')); console.log(textSync(stream)); // 'hello world'
Modules: node:module API#
Stability: 2 - Stable
The node:module module provides utilities for interacting with the Node.js
module system.
It can be accessed using:
import module from 'node:module';
Class: Module#
module objects in CommonJS modules are instances of this class.
See the CommonJS documentation for the module object.
module.builtinModules#
- Type:
<string>[]
A list of the names of all modules provided by Node.js.
import { builtinModules } from 'node:module';
console.log(builtinModules.filter((name) => name.startsWith('path')));
// Prints: [ 'path', 'path/posix', 'path/win32' ]
To test whether a module name corresponds to a builtin module, use
module.isBuiltin().
module.createRequire(filename)#
filename<string>|<URL>Filename to be used to construct the require function. Must be a file URL object, file URL string, or absolute path string.- Returns:
<require>Require function
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);
// sibling-module.js is a CommonJS module.
const siblingModule = require('./sibling-module');
module.findPackageJSON(specifier[, base])#
Stability: 1.1 - Active Development
specifier<string>|<URL>The specifier for the module whosepackage.jsonto retrieve. When passing a bare specifier, thepackage.jsonat the root of the package is returned. When passing a relative specifier or an absolute specifier, the closest parentpackage.jsonis returned.base<string>|<URL>The absolute location (file:URL string or FS path) of the containing module. For CJS, use__filename(not__dirname!); for ESM, useimport.meta.url. You do not need to pass it ifspecifieris anabsolute specifier.- Returns:
<string>|<undefined>A path if thepackage.jsonis found. Whenspecifieris a package, the package's rootpackage.json; when a relative or unresolved, the closestpackage.jsonto thespecifier.
Caveat: Do not use this to try to determine module format. There are many things affecting that determination; the
typefield of package.json is the least definitive (ex file extension supersedes it, and a loader hook supersedes that).
Caveat: This currently leverages only the built-in default resolver; if
resolvecustomization hooks are registered, they will not affect the resolution. This may change in the future.
// /path/to/project/packages/bar/bar.js import { findPackageJSON } from 'node:module'; findPackageJSON('..', import.meta.url); // '/path/to/project/package.json' // Same result when passing an absolute specifier instead: findPackageJSON(new URL('../', import.meta.url)); findPackageJSON(import.meta.resolve('../')); findPackageJSON('some-package', import.meta.url); // '/path/to/project/packages/bar/node_modules/some-package/package.json' // When passing an absolute specifier, you might get a different result if the // resolved module is inside a subfolder that has nested `package.json`. findPackageJSON(import.meta.resolve('some-package')); // '/path/to/project/packages/bar/node_modules/some-package/some-subfolder/package.json' findPackageJSON('@foo/qux', import.meta.url); // '/path/to/project/packages/qux/package.json'// /path/to/project/packages/bar/bar.js const { findPackageJSON } = require('node:module'); const { pathToFileURL } = require('node:url'); const path = require('node:path'); findPackageJSON('..', __filename); // '/path/to/project/package.json' // Same result when passing an absolute specifier instead: findPackageJSON(pathToFileURL(path.join(__dirname, '..'))); findPackageJSON('some-package', __filename); // '/path/to/project/packages/bar/node_modules/some-package/package.json' // When passing an absolute specifier, you might get a different result if the // resolved module is inside a subfolder that has nested `package.json`. findPackageJSON(pathToFileURL(require.resolve('some-package'))); // '/path/to/project/packages/bar/node_modules/some-package/some-subfolder/package.json' findPackageJSON('@foo/qux', __filename); // '/path/to/project/packages/qux/package.json'
module.isBuiltin(moduleName)#
moduleName<string>name of the module- Returns:
<boolean>returns true if the module is builtin else returns false
import { isBuiltin } from 'node:module';
isBuiltin('node:fs'); // true
isBuiltin('fs'); // true
isBuiltin('wss'); // false
module.register(specifier[, parentURL][, options])#
Stability: 0 - Deprecated: Use module.registerHooks() instead.
specifier<string>|<URL>Customization hooks to be registered; this should be the same string that would be passed toimport(), except that if it is relative, it is resolved relative toparentURL.parentURL<string>|<URL>If you want to resolvespecifierrelative to a base URL, such asimport.meta.url, you can pass that URL here. Default:'data:'options<Object>parentURL<string>|<URL>If you want to resolvespecifierrelative to a base URL, such asimport.meta.url, you can pass that URL here. This property is ignored if theparentURLis supplied as the second argument. Default:'data:'data<any>Any arbitrary, cloneable JavaScript value to pass into theinitializehook.transferList<Object>[] transferable objects to be passed into theinitializehook.
Register a module that exports hooks that customize Node.js module resolution and loading behavior. See Customization hooks.
This feature requires --allow-worker if used with the Permission Model.
module.registerHooks(options)#
Stability: 1.2 - Release candidate
options<Object>load<Function>|<undefined>See load hook. Default:undefined.resolve<Function>|<undefined>See resolve hook. Default:undefined.
- Returns:
<Object>An object with the following property:deregister()<Function>Remove the registered hooks so that they are no longer called. Hooks are otherwise retained for the lifetime of the running process.[Symbol.dispose]<Function>The same asderegister.
Register hooks that customize Node.js module resolution and loading behavior. See Customization hooks. The returned object can be used to deregister the hooks.
module.stripTypeScriptTypes(code[, options])#
Stability: 1.2 - Release candidate
code<string>The code to strip type annotations from.options<Object>- Returns:
<string>The code with type annotations stripped.
module.stripTypeScriptTypes() removes type annotations from TypeScript code. It
can be used to strip type annotations from TypeScript code before running it
with vm.runInContext() or vm.compileFunction().
By default, it will throw an error if the code contains TypeScript features
that require transformation, such as enums. See type-stripping for more information.
WARNING: The output of this function should not be considered stable across Node.js versions, due to changes in the TypeScript parser.
import { stripTypeScriptTypes } from 'node:module'; const code = 'const a: number = 1;'; const strippedCode = stripTypeScriptTypes(code); console.log(strippedCode); // Prints: const a = 1;const { stripTypeScriptTypes } = require('node:module'); const code = 'const a: number = 1;'; const strippedCode = stripTypeScriptTypes(code); console.log(strippedCode); // Prints: const a = 1;
If sourceUrl is provided, it will be used appended as a comment at the end of the output:
import { stripTypeScriptTypes } from 'node:module'; const code = 'const a: number = 1;'; const strippedCode = stripTypeScriptTypes(code, { mode: 'strip', sourceUrl: 'source.ts' }); console.log(strippedCode); // Prints: const a = 1\n\n//# sourceURL=source.ts;const { stripTypeScriptTypes } = require('node:module'); const code = 'const a: number = 1;'; const strippedCode = stripTypeScriptTypes(code, { mode: 'strip', sourceUrl: 'source.ts' }); console.log(strippedCode); // Prints: const a = 1\n\n//# sourceURL=source.ts;
module.syncBuiltinESMExports()#
The module.syncBuiltinESMExports() method updates all the live bindings for
builtin ES Modules to match the properties of the CommonJS exports. It
does not add or remove exported names from the ES Modules.
const fs = require('node:fs');
const assert = require('node:assert');
const { syncBuiltinESMExports } = require('node:module');
fs.readFile = newAPI;
delete fs.readFileSync;
function newAPI() {
// ...
}
fs.newAPI = newAPI;
syncBuiltinESMExports();
import('node:fs').then((esmFS) => {
// It syncs the existing readFile property with the new value
assert.strictEqual(esmFS.readFile, newAPI);
// readFileSync has been deleted from the required fs
assert.strictEqual('readFileSync' in fs, false);
// syncBuiltinESMExports() does not remove readFileSync from esmFS
assert.strictEqual('readFileSync' in esmFS, true);
// syncBuiltinESMExports() does not add names
assert.strictEqual(esmFS.newAPI, undefined);
});
Module compile cache#
The module compile cache can be enabled either using the module.enableCompileCache()
method or the NODE_COMPILE_CACHE=dir environment variable. After it is enabled,
whenever Node.js compiles a CommonJS, an ECMAScript Module, or a TypeScript module, it will
use on-disk V8 code cache persisted in the specified directory to speed up the compilation.
This may slow down the first load of a module graph, but subsequent loads of the same module
graph may get a significant speedup if the contents of the modules do not change.
To clean up the generated compile cache on disk, simply remove the cache directory. The cache
directory will be recreated the next time the same directory is used for compile cache
storage. To avoid filling up the disk with stale cache, it is recommended to use a directory
under the os.tmpdir(). If the compile cache is enabled by a call to
module.enableCompileCache() without specifying the directory, Node.js will use
the NODE_COMPILE_CACHE=dir environment variable if it's set, or defaults
to path.join(os.tmpdir(), 'node-compile-cache') otherwise. To locate the compile cache
directory used by a running Node.js instance, use module.getCompileCacheDir().
The enabled module compile cache can be disabled by the NODE_DISABLE_COMPILE_CACHE=1
environment variable. This can be useful when the compile cache leads to unexpected or
undesired behaviors (e.g. less precise test coverage).
At the moment, when the compile cache is enabled and a module is loaded afresh, the
code cache is generated from the compiled code immediately, but will only be written
to disk when the Node.js instance is about to exit. This is subject to change. The
module.flushCompileCache() method can be used to ensure the accumulated code cache
is flushed to disk in case the application wants to spawn other Node.js instances
and let them share the cache long before the parent exits.
The compile cache layout on disk is an implementation detail and should not be relied upon. The compile cache generated is typically only reusable in the same version of Node.js, and should be not assumed to be compatible across different versions of Node.js.
Portability of the compile cache#
By default, caches are invalidated when the absolute paths of the modules being cached are changed. To keep the cache working after moving the project directory, enable portable compile cache. This allows previously compiled modules to be reused across different directory locations as long as the layout relative to the cache directory remains the same. This would be done on a best-effort basis. If Node.js cannot compute the location of a module relative to the cache directory, the module will not be cached.
A portable cache is also not split by user: on platforms with uids the cache subdirectory of a non-portable cache is suffixed with the uid of the user who created it, so it is only found by that user, while a portable cache uses the same subdirectory for every user. This lets a cache generated once (for example at build time, then shipped read-only with an application) be read by whoever runs the code; a user who cannot write to the directory still reads it, and a failed write only means the module is compiled again.
There are two ways to enable the portable mode:
-
Using the portable option in
module.enableCompileCache():// Non-portable cache (default): cache breaks if project is moved module.enableCompileCache({ directory: '/path/to/cache/storage/dir' }); // Portable cache: cache works after the project is moved module.enableCompileCache({ directory: '/path/to/cache/storage/dir', portable: true }); -
Setting the environment variable:
NODE_COMPILE_CACHE_PORTABLE=1
Read-only compile cache#
A cache that was generated ahead of time, for example at build time to be
shipped inside an application package, can be enabled with readOnly: true
(or NODE_COMPILE_CACHE_READONLY=1). Node.js then loads whatever entries
the directory holds and never writes to it: modules without a usable entry are
compiled as usual but not persisted, module.flushCompileCache() is a
no-op, and the directory is not created if it is missing.
Limitations of the compile cache#
Currently when using the compile cache with V8 JavaScript code coverage, the coverage being collected by V8 may be less precise in functions that are deserialized from the code cache. It's recommended to turn this off when running tests to generate precise coverage.
Compilation cache generated by one version of Node.js can not be reused by a different version of Node.js. Cache generated by different versions of Node.js will be stored separately if the same base directory is used to persist the cache, so they can co-exist.
module.constants.compileCacheStatus#
The following constants are returned as the status field in the object returned by
module.enableCompileCache() to indicate the result of the attempt to enable the
module compile cache.
| Constant | Description |
|---|---|
ENABLED |
Node.js has enabled the compile cache successfully. The directory used to store the
compile cache will be returned in the directory field in the
returned object.
|
ALREADY_ENABLED |
The compile cache has already been enabled before, either by a previous call to
module.enableCompileCache(), or by the NODE_COMPILE_CACHE=dir
environment variable. The directory used to store the
compile cache will be returned in the directory field in the
returned object.
|
FAILED |
Node.js fails to enable the compile cache. This can be caused by the lack of
permission to use the specified directory, or various kinds of file system errors.
The detail of the failure will be returned in the message field in the
returned object.
|
DISABLED |
Node.js cannot enable the compile cache because the environment variable
NODE_DISABLE_COMPILE_CACHE=1 has been set.
|
module.enableCompileCache([options])#
options<string>|<Object>Optional. If a string is passed, it is considered to beoptions.directory.directory<string>Optional. Directory to store the compile cache. If not specified, the directory specified by theNODE_COMPILE_CACHE=direnvironment variable will be used if it's set, orpath.join(os.tmpdir(), 'node-compile-cache')otherwise.portable<boolean>Optional. Iftrue, enables portable compile cache so that the cache can be reused even if the project directory is moved. This is a best-effort feature. If not specified, it will depend on whether the environment variableNODE_COMPILE_CACHE_PORTABLE=1is set.readOnly<boolean>Optional. Iftrue, existing cache entries indirectoryare used but nothing is ever written to it, and the directory is not created when it does not exist (enabling then fails). Meant for caches generated ahead of time and shipped with an application. If not specified, it will depend on whether the environment variableNODE_COMPILE_CACHE_READONLY=1is set.
- Returns:
<Object>status<integer>One of themodule.constants.compileCacheStatusmessage<string>|<undefined>If Node.js cannot enable the compile cache, this contains the error message. Only set ifstatusismodule.constants.compileCacheStatus.FAILED.directory<string>|<undefined>If the compile cache is enabled, this contains the directory where the compile cache is stored. Only set ifstatusismodule.constants.compileCacheStatus.ENABLEDormodule.constants.compileCacheStatus.ALREADY_ENABLED.
Enable module compile cache in the current Node.js instance.
For general use cases, it's recommended to call module.enableCompileCache() without
specifying the options.directory, so that the directory can be overridden by the
NODE_COMPILE_CACHE environment variable when necessary.
Since compile cache is supposed to be an optimization that is not mission critical, this
method is designed to not throw any exception when the compile cache cannot be enabled.
Instead, it will return an object containing an error message in the message field to
aid debugging. If compile cache is enabled successfully, the directory field in the
returned object contains the path to the directory where the compile cache is stored. The
status field in the returned object would be one of the module.constants.compileCacheStatus
values to indicate the result of the attempt to enable the module compile cache.
This method only affects the current Node.js instance. To enable it in child worker threads,
either call this method in child worker threads too, or set the
process.env.NODE_COMPILE_CACHE value to compile cache directory so the behavior can
be inherited into the child workers. The directory can be obtained either from the
directory field returned by this method, or with module.getCompileCacheDir().
module.flushCompileCache()#
Flush the module compile cache accumulated from modules already loaded in the current Node.js instance to disk. This returns after all the flushing file system operations come to an end, no matter they succeed or not. If there are any errors, this will fail silently, since compile cache misses should not interfere with the actual operation of the application.
module.getCompileCacheDir()#
- Returns:
<string>|<undefined>Path to the module compile cache directory if it is enabled, orundefinedotherwise.
Customization Hooks#
Node.js currently supports two types of module customization hooks:
module.registerHooks(options): takes synchronous hook functions that are run directly on the thread where the modules are loaded.module.register(specifier[, parentURL][, options]): takes specifier to a module that exports asynchronous hook functions. The functions are run on a separate loader thread.
The asynchronous hooks incur extra overhead from inter-thread communication,
and have several caveats especially
when customizing CommonJS modules in the module graph.
In most cases, it's recommended to use synchronous hooks via module.registerHooks()
for simplicity.
Synchronous customization hooks#
Stability: 1.2 - Release candidate
Registration of synchronous customization hooks#
To register synchronous customization hooks, use module.registerHooks(), which
takes synchronous hook functions directly in-line.
// register-hooks.js import { registerHooks } from 'node:module'; registerHooks({ resolve(specifier, context, nextResolve) { /* implementation */ }, load(url, context, nextLoad) { /* implementation */ }, });// register-hooks.js const { registerHooks } = require('node:module'); registerHooks({ resolve(specifier, context, nextResolve) { /* implementation */ }, load(url, context, nextLoad) { /* implementation */ }, });
Registering hooks before application code runs with flags#
The hooks can be registered before the application code is run by using the
--import or --require flag:
node --import ./register-hooks.js ./my-app.js
node --require ./register-hooks.js ./my-app.js
The specifier passed to --import or --require can also come from a package:
node --import some-package/register ./my-app.js
node --require some-package/register ./my-app.js
Where some-package has an "exports" field defining the /register
export to map to a file that calls registerHooks(), like the
register-hooks.js examples above.
Using --import or --require ensures that the hooks are registered before any
application code is loaded, including the entry point of the application and for
any worker threads by default as well.
Registering hooks before application code runs programmatically#
Alternatively, registerHooks() can be called from the entry point.
If the entry point needs to load other modules and the loading process needs to be
customized, load them using either require() or dynamic import() after the hooks
are registered. Do not use static import statements to load modules that need to be
customized in the same module that registers the hooks, because static import statements
are evaluated before any code in the importer module is run, including the call to
registerHooks(), regardless of where the static import statements appear in the importer
module.
import { registerHooks } from 'node:module'; registerHooks({ /* implementation of synchronous hooks */ }); // If loaded using static import, the hooks would not be applied when loading // my-app.mjs, because statically imported modules are all executed before its // importer regardless of where the static import appears. // import './my-app.mjs'; // my-app.mjs must be loaded dynamically to ensure the hooks are applied. await import('./my-app.mjs');const { registerHooks } = require('node:module'); registerHooks({ /* implementation of synchronous hooks */ }); import('./my-app.mjs'); // Or, if my-app.mjs does not have top-level await or it's a CommonJS module, // require() can also be used: // require('./my-app.mjs');
Registering hooks before application code runs with a data: URL#
Alternatively, inline JavaScript code can be embedded in data: URLs to register
the hooks before the application code runs. For example,
node --import 'data:text/javascript,import {registerHooks} from "node:module"; registerHooks(/* hooks code */);' ./my-app.js
Convention of hooks and chaining#
Hooks are part of a chain, even if that chain consists of only one custom (user-provided) hook and the default hook, which is always present.
Hook functions nest: each one must always return a plain object, and chaining happens
as a result of each function calling next<hookName>(), which is a reference to
the subsequent loader's hook (in LIFO order).
It's possible to call registerHooks() more than once:
// entrypoint.mjs import { registerHooks } from 'node:module'; const hook1 = { /* implementation of hooks */ }; const hook2 = { /* implementation of hooks */ }; // hook2 runs before hook1. registerHooks(hook1); registerHooks(hook2);// entrypoint.cjs const { registerHooks } = require('node:module'); const hook1 = { /* implementation of hooks */ }; const hook2 = { /* implementation of hooks */ }; // hook2 runs before hook1. registerHooks(hook1); registerHooks(hook2);
In this example, the registered hooks will form chains. These chains run
last-in, first-out (LIFO). If both hook1 and hook2 define a resolve
hook, they will be called like so (note the right-to-left,
starting with hook2.resolve, then hook1.resolve, then the Node.js default):
Node.js default resolve ← hook1.resolve ← hook2.resolve
The same applies to all the other hooks.
A hook that returns a value lacking a required property triggers an exception. A
hook that returns without calling next<hookName>() and without returning
shortCircuit: true also triggers an exception. These errors are to help
prevent unintentional breaks in the chain. Return shortCircuit: true from a
hook to signal that the chain is intentionally ending at your hook.
If a hook should be applied when loading other hook modules, the other hook modules should be loaded after the hook is registered.
Deregistration of synchronous customization hooks#
The object returned by registerHooks() has a deregister() method that can be
used to remove the hooks from the chain. Once deregister() is called, the hooks
will no longer be invoked during module resolution or loading.
This is currently only available for synchronous hooks registered via registerHooks(), not for asynchronous
hooks registered via module.register().
import { registerHooks } from 'node:module'; const hooks = registerHooks({ resolve(specifier, context, nextResolve) { console.log('resolve hook called for', specifier); return nextResolve(specifier, context); }, load(url, context, nextLoad) { return nextLoad(url, context); }, }); // At this point, the hooks are active and will be called for // any subsequent import() or require() calls. await import('./my-module.mjs'); // Later, remove the hooks from the chain. hooks.deregister(); // Subsequent loads will no longer trigger the hooks. await import('./another-module.mjs');const { registerHooks } = require('node:module'); const hooks = registerHooks({ resolve(specifier, context, nextResolve) { console.log('resolve hook called for', specifier); return nextResolve(specifier, context); }, load(url, context, nextLoad) { return nextLoad(url, context); }, }); // At this point, the hooks are active and will be called for // any subsequent require() calls. require('./my-module.cjs'); // Later, remove the hooks from the chain. hooks.deregister(); // Subsequent loads will no longer trigger the hooks. require('./another-module.cjs');
Hook functions accepted by module.registerHooks()#
The module.registerHooks() method accepts the following synchronous hook functions.
function resolve(specifier, context, nextResolve) {
// Take an `import` or `require` specifier and resolve it to a URL.
}
function load(url, context, nextLoad) {
// Take a resolved URL and return the source code to be evaluated.
}
Synchronous hooks are run in the same thread and the same realm where the modules are loaded, the code in the hook function can pass values to the modules being referenced directly via global variables or other shared states.
Unlike the asynchronous hooks, the synchronous hooks are not inherited into child worker
threads by default, though if the hooks are registered using a file preloaded by
--import or --require, child worker threads can inherit the preloaded scripts
via process.execArgv inheritance. See the documentation of Worker for details.
Synchronous resolve(specifier, context, nextResolve)#
specifier<string>context<Object>conditions<string>[] Export conditions of the relevantpackage.jsonimportAttributes<Object>An object whose key-value pairs represent the attributes for the module to importparentURL<string>|<undefined>The module importing this one, or undefined if this is the Node.js entry point
nextResolve<Function>The subsequentresolvehook in the chain, or the Node.js defaultresolvehook after the last user-suppliedresolvehookspecifier<string>context<Object>|<undefined>When omitted, the defaults are provided. When provided, defaults are merged in with preference to the provided properties.
- Returns:
<Object>format<string>|<null>|<undefined>A hint to theloadhook (it might be ignored). It can be a module format (such as'commonjs'or'module') or an arbitrary value like'css'or'yaml'.importAttributes<Object>|<undefined>The import attributes to use when caching the module (optional; if excluded the input will be used)shortCircuit<undefined>|<boolean>A signal that this hook intends to terminate the chain ofresolvehooks. Default:falseurl<string>The absolute URL to which this input resolves
The resolve hook chain is responsible for telling Node.js where to find and
how to cache a given import statement or expression, or require call. It can
optionally return a format (such as 'module') as a hint to the load hook. If
a format is specified, the load hook is ultimately responsible for providing
the final format value (and it is free to ignore the hint provided by
resolve); if resolve provides a format, a custom load hook is required
even if only to pass the value to the Node.js default load hook.
Import type attributes are part of the cache key for saving loaded modules into
the internal module cache. The resolve hook is responsible for returning an
importAttributes object if the module should be cached with different
attributes than were present in the source code.
The conditions property in context is an array of conditions that will be used
to match package exports conditions for this resolution
request. They can be used for looking up conditional mappings elsewhere or to
modify the list when calling the default resolution logic.
The current package exports conditions are always in
the context.conditions array passed into the hook. To guarantee default
Node.js module specifier resolution behavior when calling defaultResolve, the
context.conditions array passed to it must include all elements of the
context.conditions array originally passed into the resolve hook.
import { registerHooks } from 'node:module';
function resolve(specifier, context, nextResolve) {
// When calling `defaultResolve`, the arguments can be modified. For example,
// to change the specifier or to add applicable export conditions.
if (specifier.includes('foo')) {
specifier = specifier.replace('foo', 'bar');
return nextResolve(specifier, {
...context,
conditions: [...context.conditions, 'another-condition'],
});
}
// The hook can also skip default resolution and provide a custom URL.
if (specifier === 'special-module') {
return {
url: 'file:///path/to/special-module.mjs',
format: 'module',
shortCircuit: true, // This is mandatory if nextResolve() is not called.
};
}
// If no customization is needed, defer to the next hook in the chain which would be the
// Node.js default resolve if this is the last user-specified loader.
return nextResolve(specifier);
}
registerHooks({ resolve });
Synchronous load(url, context, nextLoad)#
url<string>The URL returned by theresolvechaincontext<Object>conditions<string>[] Export conditions of the relevantpackage.jsonformat<string>|<null>|<undefined>The format optionally supplied by theresolvehook chain. This can be any string value as an input; input values do not need to conform to the list of acceptable return values described below.importAttributes<Object>
nextLoad<Function>The subsequentloadhook in the chain, or the Node.js defaultloadhook after the last user-suppliedloadhookurl<string>context<Object>|<undefined>When omitted, defaults are provided. When provided, defaults are merged in with preference to the provided properties. In the defaultnextLoad, if the module pointed to byurldoes not have explicit module type information,context.formatis mandatory.
- Returns:
<Object>format<string>One of the acceptable module formats listed below.shortCircuit<undefined>|<boolean>A signal that this hook intends to terminate the chain ofloadhooks. Default:falsesource<string>|<ArrayBuffer>|<TypedArray>The source for Node.js to evaluate
The load hook provides a way to define a custom method for retrieving the
source code of a resolved URL. This would allow a loader to potentially avoid
reading files from disk. It could also be used to map an unrecognized format to
a supported one, for example yaml to module.
import { registerHooks } from 'node:module';
import { Buffer } from 'node:buffer';
function load(url, context, nextLoad) {
// The hook can skip default loading and provide a custom source code.
if (url === 'special-module') {
return {
source: 'export const special = 42;',
format: 'module',
shortCircuit: true, // This is mandatory if nextLoad() is not called.
};
}
// It's possible to modify the source code loaded by the next - possibly default - step,
// for example, replacing 'foo' with 'bar' in the source code of the module.
const result = nextLoad(url, context);
const source = typeof result.source === 'string' ?
result.source : Buffer.from(result.source).toString('utf8');
return {
source: source.replace(/foo/g, 'bar'),
...result,
};
}
registerHooks({ load });
In a more advanced scenario, this can also be used to transform an unsupported source to a supported one (see Examples below).
Accepted final formats returned by load#
The final value of format must be one of the following:
format |
Description | Acceptable types for source returned by load |
|---|---|---|
'addon' |
Load a Node.js addon | <null> |
'builtin' |
Load a Node.js builtin module | <null> |
'commonjs-typescript' |
Load a Node.js CommonJS module with TypeScript syntax | <string> | <ArrayBuffer> | <TypedArray> | <null> | <undefined> |
'commonjs' |
Load a Node.js CommonJS module | <string> | <ArrayBuffer> | <TypedArray> | <null> | <undefined> |
'json' |
Load a JSON file | <string> | <ArrayBuffer> | <TypedArray> |
'module-typescript' |
Load an ES module with TypeScript syntax | <string> | <ArrayBuffer> | <TypedArray> |
'module' |
Load an ES module | <string> | <ArrayBuffer> | <TypedArray> |
'wasm' |
Load a WebAssembly module | <ArrayBuffer> | <TypedArray> |
The value of source is ignored for format 'builtin' because currently it is
not possible to replace the value of a Node.js builtin (core) module.
These types all correspond to classes defined in ECMAScript.
- The specific
<ArrayBuffer>object is a<SharedArrayBuffer>. - The specific
<TypedArray>object is a<Uint8Array>.
If the source value of a text-based format (i.e., 'json', 'module')
is not a string, it is converted to a string using util.TextDecoder.
Asynchronous customization hooks#
Stability: 1.1 - Active Development
Caveats of asynchronous customization hooks#
The asynchronous customization hooks have many caveats and it is uncertain if their
issues can be resolved. Users are encouraged to use the synchronous customization hooks
via module.registerHooks() instead to avoid these caveats.
- Asynchronous hooks run on a separate thread, so the hook functions cannot directly mutate the global state of the modules being customized. It's typical to use message channels and atomics to pass data between the two or to affect control flows. See Communication with asynchronous module customization hooks.
- Asynchronous hooks do not affect all
require()calls in the module graph.- Custom
requirefunctions created usingmodule.createRequire()are not affected. - If the asynchronous
loadhook does not override thesourcefor CommonJS modules that go through it, the child modules loaded by those CommonJS modules via built-inrequire()would not be affected by the asynchronous hooks either.
- Custom
- There are several caveats that the asynchronous hooks need to handle when
customizing CommonJS modules. See asynchronous
resolvehook and asynchronousloadhook for details. - When
require()calls inside CommonJS modules are customized by asynchronous hooks, Node.js may need to load the source code of the CommonJS module multiple times to maintain compatibility with existing CommonJS monkey-patching. If the module code changes between loads, this may lead to unexpected behaviors.- As a side effect, if both asynchronous hooks and synchronous hooks are registered and the
asynchronous hooks choose to customize the CommonJS module, the synchronous hooks may be
invoked multiple times for the
require()calls in that CommonJS module.
- As a side effect, if both asynchronous hooks and synchronous hooks are registered and the
asynchronous hooks choose to customize the CommonJS module, the synchronous hooks may be
invoked multiple times for the
Registration of asynchronous customization hooks#
Asynchronous customization hooks are registered using module.register() which takes
a path or URL to another module that exports the asynchronous hook functions.
Similar to registerHooks(), register() can be called in a module preloaded by --import or
--require, or called directly within the entry point.
// Use module.register() to register asynchronous hooks in a dedicated thread. import { register } from 'node:module'; register('./hooks.mjs', import.meta.url); // If my-app.mjs is loaded statically here as `import './my-app.mjs'`, since ESM // dependencies are evaluated before the module that imports them, // it's loaded _before_ the hooks are registered above and won't be affected. // To ensure the hooks are applied, dynamic import() must be used to load ESM // after the hooks are registered. import('./my-app.mjs');const { register } = require('node:module'); const { pathToFileURL } = require('node:url'); // Use module.register() to register asynchronous hooks in a dedicated thread. register('./hooks.mjs', pathToFileURL(__filename)); import('./my-app.mjs');
In hooks.mjs:
// hooks.mjs
export async function resolve(specifier, context, nextResolve) {
/* implementation */
}
export async function load(url, context, nextLoad) {
/* implementation */
}
Unlike synchronous hooks, the asynchronous hooks would not run for these modules loaded in the file
that calls register():
// register-hooks.js import { register, createRequire } from 'node:module'; register('./hooks.mjs', import.meta.url); // Asynchronous hooks does not affect modules loaded via custom require() // functions created by module.createRequire(). const userRequire = createRequire(import.meta.filename); userRequire('./my-app-2.cjs'); // Hooks won't affect this// register-hooks.js const { register, createRequire } = require('node:module'); const { pathToFileURL } = require('node:url'); register('./hooks.mjs', pathToFileURL(__filename)); // Asynchronous hooks does not affect modules loaded via built-in require() // in the module calling `register()` require('./my-app-2.cjs'); // Hooks won't affect this // .. or custom require() functions created by module.createRequire(). const userRequire = createRequire(__filename); userRequire('./my-app-3.cjs'); // Hooks won't affect this
Asynchronous hooks can also be registered using a data: URL with the --import flag:
node --import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register("my-instrumentation", pathToFileURL("./"));' ./my-app.js
Chaining of asynchronous customization hooks#
Chaining of register() work similarly to registerHooks(). If synchronous and asynchronous
hooks are mixed, the synchronous hooks are always run first before the asynchronous
hooks start running, that is, in the last synchronous hook being run, its next
hook includes invocation of the asynchronous hooks.
// entrypoint.mjs import { register } from 'node:module'; register('./foo.mjs', import.meta.url); register('./bar.mjs', import.meta.url); await import('./my-app.mjs');// entrypoint.cjs const { register } = require('node:module'); const { pathToFileURL } = require('node:url'); const parentURL = pathToFileURL(__filename); register('./foo.mjs', parentURL); register('./bar.mjs', parentURL); import('./my-app.mjs');
If foo.mjs and bar.mjs define a resolve hook, they will be called like so
(note the right-to-left, starting with ./bar.mjs, then ./foo.mjs, then the Node.js default):
Node.js default ← ./foo.mjs ← ./bar.mjs
When using the asynchronous hooks, the registered hooks also affect subsequent
register calls, which takes care of loading hook modules. In the example above,
bar.mjs will be resolved and loaded via the hooks registered by foo.mjs
(because foo's hooks will have already been added to the chain). This allows
for things like writing hooks in non-JavaScript languages, so long as
earlier registered hooks transpile into JavaScript.
The register() method cannot be called from the thread running the hook module that
exports the asynchronous hooks or its dependencies.
Communication with asynchronous module customization hooks#
Asynchronous hooks run on a dedicated thread, separate from the main thread that runs application code. This means mutating global variables won't affect the other thread(s), and message channels must be used to communicate between the threads.
The register method can be used to pass data to an initialize hook. The
data passed to the hook may include transferable objects like ports.
import { register } from 'node:module'; import { MessageChannel } from 'node:worker_threads'; // This example demonstrates how a message channel can be used to // communicate with the hooks, by sending `port2` to the hooks. const { port1, port2 } = new MessageChannel(); port1.on('message', (msg) => { console.log(msg); }); port1.unref(); register('./my-hooks.mjs', { parentURL: import.meta.url, data: { number: 1, port: port2 }, transferList: [port2], });const { register } = require('node:module'); const { pathToFileURL } = require('node:url'); const { MessageChannel } = require('node:worker_threads'); // This example showcases how a message channel can be used to // communicate with the hooks, by sending `port2` to the hooks. const { port1, port2 } = new MessageChannel(); port1.on('message', (msg) => { console.log(msg); }); port1.unref(); register('./my-hooks.mjs', { parentURL: pathToFileURL(__filename), data: { number: 1, port: port2 }, transferList: [port2], });
Asynchronous hooks accepted by module.register()#
The register method can be used to register a module that exports a set of
hooks. The hooks are functions that are called by Node.js to customize the
module resolution and loading process. The exported functions must have specific
names and signatures, and they must be exported as named exports.
export async function initialize({ number, port }) {
// Receives data from `register`.
}
export async function resolve(specifier, context, nextResolve) {
// Take an `import` or `require` specifier and resolve it to a URL.
}
export async function load(url, context, nextLoad) {
// Take a resolved URL and return the source code to be evaluated.
}
Asynchronous hooks are run in a separate thread, isolated from the main thread where
application code runs. That means it is a different realm. The hooks thread
may be terminated by the main thread at any time, so do not depend on
asynchronous operations (like console.log) to complete. They are inherited into
child workers by default.
initialize()#
data<any>The data fromregister(loader, import.meta.url, { data }).
The initialize hook is only accepted by register. registerHooks() does
not support nor need it since initialization done for synchronous hooks can be run
directly before the call to registerHooks().
The initialize hook provides a way to define a custom function that runs in
the hooks thread when the hooks module is initialized. Initialization happens
when the hooks module is registered via register.
This hook can receive data from a register invocation, including
ports and other transferable objects. The return value of initialize can be a
<Promise>, in which case it will be awaited before the main application thread
execution resumes.
Module customization code:
// path-to-my-hooks.js
export async function initialize({ number, port }) {
port.postMessage(`increment: ${number + 1}`);
}
Caller code:
import assert from 'node:assert'; import { register } from 'node:module'; import { MessageChannel } from 'node:worker_threads'; // This example showcases how a message channel can be used to communicate // between the main (application) thread and the hooks running on the hooks // thread, by sending `port2` to the `initialize` hook. const { port1, port2 } = new MessageChannel(); port1.on('message', (msg) => { assert.strictEqual(msg, 'increment: 2'); }); port1.unref(); register('./path-to-my-hooks.js', { parentURL: import.meta.url, data: { number: 1, port: port2 }, transferList: [port2], });const assert = require('node:assert'); const { register } = require('node:module'); const { pathToFileURL } = require('node:url'); const { MessageChannel } = require('node:worker_threads'); // This example showcases how a message channel can be used to communicate // between the main (application) thread and the hooks running on the hooks // thread, by sending `port2` to the `initialize` hook. const { port1, port2 } = new MessageChannel(); port1.on('message', (msg) => { assert.strictEqual(msg, 'increment: 2'); }); port1.unref(); register('./path-to-my-hooks.js', { parentURL: pathToFileURL(__filename), data: { number: 1, port: port2 }, transferList: [port2], });
Asynchronous resolve(specifier, context, nextResolve)#
specifier<string>context<Object>conditions<string>[] Export conditions of the relevantpackage.jsonimportAttributes<Object>An object whose key-value pairs represent the attributes for the module to importparentURL<string>|<undefined>The module importing this one, or undefined if this is the Node.js entry point
nextResolve<Function>The subsequentresolvehook in the chain, or the Node.js defaultresolvehook after the last user-suppliedresolvehookspecifier<string>context<Object>|<undefined>When omitted, the defaults are provided. When provided, defaults are merged in with preference to the provided properties.
- Returns:
<Object>|<Promise>The asynchronous version takes either an object containing the following properties, or aPromisethat will resolve to such an object.format<string>|<null>|<undefined>A hint to theloadhook (it might be ignored). It can be a module format (such as'commonjs'or'module') or an arbitrary value like'css'or'yaml'.importAttributes<Object>|<undefined>The import attributes to use when caching the module (optional; if excluded the input will be used)shortCircuit<undefined>|<boolean>A signal that this hook intends to terminate the chain ofresolvehooks. Default:falseurl<string>The absolute URL to which this input resolves
The asynchronous version works similarly to the synchronous version, only that the
nextResolve function returns a Promise, and the resolve hook itself can return a Promise.
Warning In the case of the asynchronous version, despite support for returning promises and async functions, calls to
resolvemay still block the main thread which can impact performance.
Warning The
resolvehook invoked forrequire()calls inside CommonJS modules customized by asynchronous hooks does not receive the original specifier passed torequire(). Instead, it receives a URL already fully resolved using the default CommonJS resolution.
Warning In the CommonJS modules that are customized by the asynchronous customization hooks,
require.resolve()andrequire()will use"import"export condition instead of"require", which may cause unexpected behaviors when loading dual packages.
export async function resolve(specifier, context, nextResolve) {
// When calling `defaultResolve`, the arguments can be modified. For example,
// to change the specifier or add conditions.
if (specifier.includes('foo')) {
specifier = specifier.replace('foo', 'bar');
return nextResolve(specifier, {
...context,
conditions: [...context.conditions, 'another-condition'],
});
}
// The hook can also skips default resolution and provide a custom URL.
if (specifier === 'special-module') {
return {
url: 'file:///path/to/special-module.mjs',
format: 'module',
shortCircuit: true, // This is mandatory if not calling nextResolve().
};
}
// If no customization is needed, defer to the next hook in the chain which would be the
// Node.js default resolve if this is the last user-specified loader.
return nextResolve(specifier);
}
Asynchronous load(url, context, nextLoad)#
url<string>The URL returned by theresolvechaincontext<Object>conditions<string>[] Export conditions of the relevantpackage.jsonformat<string>|<null>|<undefined>The format optionally supplied by theresolvehook chain. This can be any string value as an input; input values do not need to conform to the list of acceptable return values described below.importAttributes<Object>
nextLoad<Function>The subsequentloadhook in the chain, or the Node.js defaultloadhook after the last user-suppliedloadhookurl<string>context<Object>|<undefined>When omitted, defaults are provided. When provided, defaults are merged in with preference to the provided properties. In the defaultnextLoad, if the module pointed to byurldoes not have explicit module type information,context.formatis mandatory.
- Returns:
<Promise>The asynchronous version takes either an object containing the following properties, or aPromisethat will resolve to such an object.format<string>shortCircuit<undefined>|<boolean>A signal that this hook intends to terminate the chain ofloadhooks. Default:falsesource<string>|<ArrayBuffer>|<TypedArray>The source for Node.js to evaluate
Warning: The asynchronous
loadhook and namespaced exports from CommonJS modules are incompatible. Attempting to use them together will result in an empty object from the import. This may be addressed in the future. This does not apply to the synchronousloadhook, in which case exports can be used as usual.
The asynchronous version works similarly to the synchronous version, though
when using the asynchronous load hook, omitting vs providing a source for
'commonjs' has very different effects:
- When a
sourceis provided, allrequirecalls from this module will be processed by the ESM loader with registeredresolveandloadhooks; allrequire.resolvecalls from this module will be processed by the ESM loader with registeredresolvehooks; only a subset of the CommonJS API will be available (e.g. norequire.extensions, norequire.cache, norequire.resolve.paths) and monkey-patching on the CommonJS module loader will not apply. - If
sourceis undefined ornull, it will be handled by the CommonJS module loader andrequire/require.resolvecalls will not go through the registered hooks. This behavior for nullishsourceis temporary — in the future, nullishsourcewill not be supported.
These caveats do not apply to the synchronous load hook, in which case
the complete set of CommonJS APIs available to the customized CommonJS
modules, and require/require.resolve always go through the registered
hooks.
The Node.js internal asynchronous load implementation, which is the value of next for the
last hook in the load chain, returns null for source when format is
'commonjs' for backward compatibility. Here is an example hook that would
opt-in to using the non-default behavior:
import { readFile } from 'node:fs/promises';
// Asynchronous version accepted by module.register(). This fix is not needed
// for the synchronous version accepted by module.registerHooks().
export async function load(url, context, nextLoad) {
const result = await nextLoad(url, context);
if (result.format === 'commonjs') {
result.source ??= await readFile(new URL(result.responseURL ?? url));
}
return result;
}
This doesn't apply to the synchronous load hook either, in which case the
source returned contains source code loaded by the next hook, regardless
of module format.
Examples#
The various module customization hooks can be used together to accomplish wide-ranging customizations of the Node.js code loading and evaluation behaviors.
Import from HTTPS#
The hook below registers hooks to enable rudimentary support for such specifiers. While this may seem like a significant improvement to Node.js core functionality, there are substantial downsides to actually using these hooks: performance is much slower than loading files from disk, there is no caching, and there is no security.
// https-hooks.mjs
import { get } from 'node:https';
export function load(url, context, nextLoad) {
// For JavaScript to be loaded over the network, we need to fetch and
// return it.
if (url.startsWith('https://')) {
return new Promise((resolve, reject) => {
get(url, (res) => {
let data = '';
res.setEncoding('utf8');
res.on('data', (chunk) => data += chunk);
res.on('end', () => resolve({
// This example assumes all network-provided JavaScript is ES module
// code.
format: 'module',
shortCircuit: true,
source: data,
}));
}).on('error', (err) => reject(err));
});
}
// Let Node.js handle all other URLs.
return nextLoad(url);
}
// main.mjs
import { VERSION } from 'https://coffeescript.org/browser-compiler-modern/coffeescript.js';
console.log(VERSION);
With the preceding hooks module, running
node --import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register(pathToFileURL("./https-hooks.mjs"));' ./main.mjs
prints the current version of CoffeeScript per the module at the URL in
main.mjs.
Transpilation#
Sources that are in formats Node.js doesn't understand can be converted into
JavaScript using the load hook.
This is less performant than transpiling source files before running Node.js; transpiler hooks should only be used for development and testing purposes.
Asynchronous version#
// coffeescript-hooks.mjs
import { readFile } from 'node:fs/promises';
import { findPackageJSON } from 'node:module';
import coffeescript from 'coffeescript';
const extensionsRegex = /\.(coffee|litcoffee|coffee\.md)$/;
export async function load(url, context, nextLoad) {
if (extensionsRegex.test(url)) {
// CoffeeScript files can be either CommonJS or ES modules. Use a custom format
// to tell Node.js not to detect its module type.
const { source: rawSource } = await nextLoad(url, { ...context, format: 'coffee' });
// This hook converts CoffeeScript source code into JavaScript source code
// for all imported CoffeeScript files.
const transformedSource = coffeescript.compile(rawSource.toString(), url);
// To determine how Node.js would interpret the transpilation result,
// search up the file system for the nearest parent package.json file
// and read its "type" field.
return {
format: await getPackageType(url),
shortCircuit: true,
source: transformedSource,
};
}
// Let Node.js handle all other URLs.
return nextLoad(url, context);
}
async function getPackageType(url) {
// `url` is only a file path during the first iteration when passed the
// resolved url from the load() hook
// an actual file path from load() will contain a file extension as it's
// required by the spec
// this simple truthy check for whether `url` contains a file extension will
// work for most projects but does not cover some edge-cases (such as
// extensionless files or a url ending in a trailing space)
const pJson = findPackageJSON(url);
return readFile(pJson, 'utf8')
.then(JSON.parse)
.then((json) => json?.type)
.catch(() => undefined);
}
Synchronous version#
// coffeescript-sync-hooks.mjs
import { readFileSync } from 'node:fs';
import { registerHooks, findPackageJSON } from 'node:module';
import coffeescript from 'coffeescript';
const extensionsRegex = /\.(coffee|litcoffee|coffee\.md)$/;
function load(url, context, nextLoad) {
if (extensionsRegex.test(url)) {
const { source: rawSource } = nextLoad(url, { ...context, format: 'coffee' });
const transformedSource = coffeescript.compile(rawSource.toString(), url);
return {
format: getPackageType(url),
shortCircuit: true,
source: transformedSource,
};
}
return nextLoad(url, context);
}
function getPackageType(url) {
const pJson = findPackageJSON(url);
if (!pJson) {
return undefined;
}
try {
const file = readFileSync(pJson, 'utf-8');
return JSON.parse(file)?.type;
} catch {
return undefined;
}
}
registerHooks({ load });
Running hooks#
# main.coffee
import { scream } from './scream.coffee'
console.log scream 'hello, world'
import { version } from 'node:process'
console.log "Brought to you by Node.js version #{version}"
# scream.coffee
export scream = (str) -> str.toUpperCase()
For the sake of running the example, add a package.json file containing the
module type of the CoffeeScript files.
{
"type": "module"
}
This is only for running the example. In real world loaders, getPackageType() must be
able to return an format known to Node.js even in the absence of an explicit type in a
package.json, or otherwise the nextLoad call would throw ERR_UNKNOWN_FILE_EXTENSION
(if undefined) or ERR_UNKNOWN_MODULE_FORMAT (if it's not a known format listed in
the load hook documentation).
With the preceding hooks modules, running
node --import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register(pathToFileURL("./coffeescript-hooks.mjs"));' ./main.coffee
or node --import ./coffeescript-sync-hooks.mjs ./main.coffee
causes main.coffee to be turned into JavaScript after its source code is
loaded from disk but before Node.js executes it; and so on for any .coffee,
.litcoffee or .coffee.md files referenced via import statements of any
loaded file.
Import maps#
The previous two examples defined load hooks. This is an example of a
resolve hook. This hooks module reads an import-map.json file that defines
which specifiers to override to other URLs (this is a very simplistic
implementation of a small subset of the "import maps" specification).
Asynchronous version#
// import-map-hooks.js
import fs from 'node:fs/promises';
const { imports } = JSON.parse(await fs.readFile('import-map.json'));
export async function resolve(specifier, context, nextResolve) {
if (Object.hasOwn(imports, specifier)) {
return nextResolve(imports[specifier], context);
}
return nextResolve(specifier, context);
}
Synchronous version#
// import-map-sync-hooks.js
import fs from 'node:fs/promises';
import module from 'node:module';
const { imports } = JSON.parse(fs.readFileSync('import-map.json', 'utf-8'));
function resolve(specifier, context, nextResolve) {
if (Object.hasOwn(imports, specifier)) {
return nextResolve(imports[specifier], context);
}
return nextResolve(specifier, context);
}
module.registerHooks({ resolve });
Using the hooks#
With these files:
// main.js
import 'a-module';
// import-map.json
{
"imports": {
"a-module": "./some-module.js"
}
}
// some-module.js
console.log('some module!');
Running node --import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register(pathToFileURL("./import-map-hooks.js"));' main.js
or node --import ./import-map-sync-hooks.js main.js
should print some module!.
Source Map Support#
Stability: 1 - Experimental
Node.js supports TC39 ECMA-426 Source Map format (it was called Source map revision 3 format).
The APIs in this section are helpers for interacting with the source map cache. This cache is populated when source map parsing is enabled and source map include directives are found in a modules' footer.
To enable source map parsing, Node.js must be run with the flag
--enable-source-maps, or with code coverage enabled by setting
NODE_V8_COVERAGE=dir, or be enabled programmatically via
module.setSourceMapsSupport().
// module.mjs // In an ECMAScript module import { findSourceMap, SourceMap } from 'node:module';// module.cjs // In a CommonJS module const { findSourceMap, SourceMap } = require('node:module');
module.getSourceMapsSupport()#
- Returns:
<Object>
This method returns whether the Source Map v3 support for stack traces is enabled.
module.findSourceMap(path)#
path<string>- Returns:
<module.SourceMap>|<undefined>Returnsmodule.SourceMapif a source map is found,undefinedotherwise.
path is the resolved path for the file for which a corresponding source map
should be fetched.
module.setSourceMapsSupport(enabled[, options])#
This function enables or disables the Source Map v3 support for stack traces.
It provides same features as launching Node.js process with commandline options
--enable-source-maps, with additional options to alter the support for files
in node_modules or generated codes.
Only source maps in JavaScript files that are loaded after source maps has been
enabled will be parsed and loaded. Preferably, use the commandline options
--enable-source-maps to avoid losing track of source maps of modules loaded
before this API call.
Class: module.SourceMap#
new SourceMap(payload[, { lineLengths }])#
Creates a new sourceMap instance.
payload is an object with keys matching the Source map format:
file<string>version<number>sources<string>[]sourcesContent<string>[]names<string>[]mappings<string>sourceRoot<string>
lineLengths is an optional array of the length of each line in the
generated code.
sourceMap.payload#
- Returns:
<Object>
Getter for the payload used to construct the SourceMap instance.
sourceMap.findEntry(lineOffset, columnOffset)#
lineOffset<number>The zero-indexed line number offset in the generated sourcecolumnOffset<number>The zero-indexed column number offset in the generated source- Returns:
<Object>
Given a line offset and column offset in the generated source file, returns an object representing the SourceMap range in the original file if found, or an empty object if not.
The object returned contains the following keys:
generatedLine<number>The line offset of the start of the range in the generated sourcegeneratedColumn<number>The column offset of start of the range in the generated sourceoriginalSource<string>The file name of the original source, as reported in the SourceMaporiginalLine<number>The line offset of the start of the range in the original sourceoriginalColumn<number>The column offset of start of the range in the original sourcename<string>
The returned value represents the raw range as it appears in the SourceMap, based on zero-indexed offsets, not 1-indexed line and column numbers as they appear in Error messages and CallSite objects.
To get the corresponding 1-indexed line and column numbers from a
lineNumber and columnNumber as they are reported by Error stacks
and CallSite objects, use sourceMap.findOrigin(lineNumber, columnNumber)
sourceMap.findOrigin(lineNumber, columnNumber)#
lineNumber<number>The 1-indexed line number of the call site in the generated sourcecolumnNumber<number>The 1-indexed column number of the call site in the generated source- Returns:
<Object>
Given a 1-indexed lineNumber and columnNumber from a call site in
the generated source, find the corresponding call site location
in the original source.
If the lineNumber and columnNumber provided are not found in any
source map, then an empty object is returned. Otherwise, the
returned object contains the following keys:
name<string>|<undefined>The name of the range in the source map, if one was providedfileName<string>The file name of the original source, as reported in the SourceMaplineNumber<number>The 1-indexed lineNumber of the corresponding call site in the original sourcecolumnNumber<number>The 1-indexed columnNumber of the corresponding call site in the original source
Modules: CommonJS modules#
Stability: 2 - Stable
CommonJS modules are the original way to package JavaScript code for Node.js. Node.js also supports the ECMAScript modules standard used by browsers and other JavaScript runtimes.
In Node.js, each file is treated as a separate module. For
example, consider a file named foo.js:
const circle = require('./circle.js');
console.log(`The area of a circle of radius 4 is ${circle.area(4)}`);
On the first line, foo.js loads the module circle.js that is in the same
directory as foo.js.
Here are the contents of circle.js:
const { PI } = Math;
exports.area = (r) => PI * r ** 2;
exports.circumference = (r) => 2 * PI * r;
The module circle.js has exported the functions area() and
circumference(). Functions and objects are added to the root of a module
by specifying additional properties on the special exports object.
Variables local to the module will be private, because the module is wrapped
in a function by Node.js (see module wrapper).
In this example, the variable PI is private to circle.js.
The module.exports property can be assigned a new value (such as a function
or object).
In the following code, bar.js makes use of the square module, which exports
a Square class:
const Square = require('./square.js');
const mySquare = new Square(2);
console.log(`The area of mySquare is ${mySquare.area()}`);
The square module is defined in square.js:
// Assigning to exports will not modify module, must use module.exports
module.exports = class Square {
constructor(width) {
this.width = width;
}
area() {
return this.width ** 2;
}
};
The CommonJS module system is implemented in the module core module.
Enabling#
Node.js has two module systems: CommonJS modules and ECMAScript modules.
By default, Node.js will treat the following as CommonJS modules:
-
Files with a
.cjsextension. -
Files with a
.jsextension or without an extension, when the nearest parentpackage.jsonfile contains a top-level field"type"with a value of"commonjs". -
Files with a
.jsextension or without an extension, when the nearest parentpackage.jsonfile doesn't contain a top-level field"type"or there is nopackage.jsonin any parent folder; unless the file contains syntax that errors unless it is evaluated as an ES module. Package authors should include the"type"field, even in packages where all sources are CommonJS. Being explicit about thetypeof the package will make things easier for build tools and loaders to determine how the files in the package should be interpreted. -
Files with an extension that is not
.mjs,.cjs,.json,.node, or.js, when the nearest parentpackage.jsonfile contains a top-level field"type"with a value of"module".
See Determining module system for more details.
Calling require() always use the CommonJS module loader. Calling import()
always use the ECMAScript module loader.
Accessing the main module#
When a file is run directly from Node.js, require.main is set to its
module. That means that it is possible to determine whether a file has been
run directly by testing require.main === module.
For a file foo.js, this will be true if run via node foo.js, but
false if run by require('./foo').
When the entry point is not a CommonJS module, require.main is undefined,
and the main module is out of reach.
Package manager tips#
The semantics of the Node.js require() function were designed to be general
enough to support reasonable directory structures. Package manager programs
such as dpkg, rpm, and npm will hopefully find it possible to build
native packages from Node.js modules without modification.
In the following, we give a suggested directory structure that could work:
Let's say that we wanted to have the folder at
/usr/lib/node/<some-package>/<some-version> hold the contents of a
specific version of a package.
Packages can depend on one another. In order to install package foo, it
may be necessary to install a specific version of package bar. The bar
package may itself have dependencies, and in some cases, these may even collide
or form cyclic dependencies.
Because Node.js looks up the realpath of any modules it loads (that is, it
resolves symlinks) and then looks for their dependencies in node_modules folders,
this situation can be resolved with the following architecture:
/usr/lib/node/foo/1.2.3/: Contents of thefoopackage, version 1.2.3./usr/lib/node/bar/4.3.2/: Contents of thebarpackage thatfoodepends on./usr/lib/node/foo/1.2.3/node_modules/bar: Symbolic link to/usr/lib/node/bar/4.3.2/./usr/lib/node/bar/4.3.2/node_modules/*: Symbolic links to the packages thatbardepends on.
Thus, even if a cycle is encountered, or if there are dependency conflicts, every module will be able to get a version of its dependency that it can use.
When the code in the foo package does require('bar'), it will get the
version that is symlinked into /usr/lib/node/foo/1.2.3/node_modules/bar.
Then, when the code in the bar package calls require('quux'), it'll get
the version that is symlinked into
/usr/lib/node/bar/4.3.2/node_modules/quux.
Furthermore, to make the module lookup process even more optimal, rather
than putting packages directly in /usr/lib/node, we could put them in
/usr/lib/node_modules/<name>/<version>. Then Node.js will not bother
looking for missing dependencies in /usr/node_modules or /node_modules.
In order to make modules available to the Node.js REPL, it might be useful to
also add the /usr/lib/node_modules folder to the $NODE_PATH environment
variable. Since the module lookups using node_modules folders are all
relative, and based on the real path of the files making the calls to
require(), the packages themselves can be anywhere.
Loading ECMAScript modules using require()#
The .mjs extension is reserved for ECMAScript Modules.
See Determining module system section for more info
regarding which files are parsed as ECMAScript modules.
require() only supports loading ECMAScript modules that meet the following requirements:
- The module is fully synchronous (contains no top-level
await); and - One of these conditions are met:
- The file has a
.mjsextension. - The file has a
.jsextension, and the closestpackage.jsoncontains"type": "module" - The file has a
.jsextension, the closestpackage.jsondoes not contain"type": "commonjs", and the module contains ES module syntax.
- The file has a
If the ES Module being loaded meets the requirements, require() can load it and
return the module namespace object. In this case it is similar to dynamic
import() but is run synchronously and returns the name space object
directly.
With the following ES Modules:
// distance.mjs
export function distance(a, b) { return Math.sqrt((b.x - a.x) ** 2 + (b.y - a.y) ** 2); }
// point.mjs
export default class Point {
constructor(x, y) { this.x = x; this.y = y; }
}
A CommonJS module can load them with require():
const distance = require('./distance.mjs');
console.log(distance);
// [Module: null prototype] {
// distance: [Function: distance]
// }
const point = require('./point.mjs');
console.log(point);
// [Module: null prototype] {
// default: [class Point],
// __esModule: true,
// }
For interoperability with existing tools that convert ES Modules into CommonJS,
which could then load real ES Modules through require(), the returned namespace
would contain a __esModule: true property if it has a default export so that
consuming code generated by tools can recognize the default exports in real
ES Modules. If the namespace already defines __esModule, this would not be added.
This property is experimental and can change in the future. It should only be used
by tools converting ES modules into CommonJS modules, following existing ecosystem
conventions. Code authored directly in CommonJS should avoid depending on it.
The result returned by require() is the module namespace object, which places
the default export in the .default property, similar to the results returned by import().
To customize what should be returned by require(esm) directly, the ES Module can export the
desired value using the string name "module.exports".
// point.mjs export default class Point { constructor(x, y) { this.x = x; this.y = y; } } // `distance` is lost to CommonJS consumers of this module, unless it's // added to `Point` as a static property. export function distance(a, b) { return Math.sqrt((b.x - a.x) ** 2 + (b.y - a.y) ** 2); } export { Point as 'module.exports' };const Point = require('./point.mjs'); console.log(Point); // [class Point] // Named exports are lost when 'module.exports' is used const { distance } = require('./point.mjs'); console.log(distance); // undefined
Notice in the example above, when the module.exports export name is used, named exports
will be lost to CommonJS consumers. To allow CommonJS consumers to continue accessing
named exports, the module can make sure that the default export is an object with the
named exports attached to it as properties. For example with the example above,
distance can be attached to the default export, the Point class, as a static method.
export function distance(a, b) { return Math.sqrt((b.x - a.x) ** 2 + (b.y - a.y) ** 2); } export default class Point { constructor(x, y) { this.x = x; this.y = y; } static distance = distance; } export { Point as 'module.exports' };const Point = require('./point.mjs'); console.log(Point); // [class Point] const { distance } = require('./point.mjs'); console.log(distance); // [Function: distance]
If the module being require()'d contains top-level await, or the module
graph it imports contains top-level await,
ERR_REQUIRE_ASYNC_MODULE will be thrown. In this case, users should
load the asynchronous module using import().
If --experimental-print-required-tla is enabled and the error is uncaught,
Node.js will try to locate the top-level awaits in the require()'d module graph
and print the locations in the stderr.
If support for loading ES modules using require() results in unexpected
breakage, it can be disabled using --no-require-module.
To print where this feature is used, use --trace-require-module.
This feature can be detected by checking if
process.features.require_module is true.
All together#
To get the exact filename that will be loaded when require() is called, use
the require.resolve() function.
Putting together all of the above, here is the high-level algorithm
in pseudocode of what require() does:
require(X) from module at path Y
1. If X is a core module,
a. return the core module
b. STOP
2. If X begins with '/'
a. set Y to the file system root
3. If X is equal to '.', or X begins with './', '/' or '../'
a. LOAD_AS_FILE(Y + X)
b. LOAD_AS_DIRECTORY(Y + X)
c. THROW "not found"
4. If X begins with '#'
a. LOAD_PACKAGE_IMPORTS(X, dirname(Y))
5. LOAD_PACKAGE_SELF(X, dirname(Y))
6. If a package map PACKAGE_MAP exists,
a. Find the package ID for the package owning Y
1. Let PARENT_PACKAGE_ID be FIND_PACKAGE_ID(dirname(Y), PACKAGE_MAP)
b. LOAD_PACKAGE_MAP(X, PARENT_PACKAGE_ID, PACKAGE_MAP)
7. LOAD_NODE_MODULES(X, dirname(Y))
8. THROW "not found"
MAYBE_DETECT_AND_LOAD(X)
1. If X parses as a CommonJS module, load X as a CommonJS module. STOP.
2. Else, if the source code of X can be parsed as ECMAScript module using
DETECT_MODULE_SYNTAX defined in the ESM resolver,
a. Load X as an ECMAScript module. STOP.
3. THROW the SyntaxError from attempting to parse X as CommonJS in 1. STOP.
LOAD_AS_FILE(X)
1. If X is a file, load X as its file extension format. STOP
2. If X.js is a file,
a. Find the closest package scope SCOPE to X.
b. If no scope was found
1. MAYBE_DETECT_AND_LOAD(X.js)
c. If the SCOPE/package.json contains "type" field,
1. If the "type" field is "module", load X.js as an ECMAScript module. STOP.
2. If the "type" field is "commonjs", load X.js as a CommonJS module. STOP.
d. MAYBE_DETECT_AND_LOAD(X.js)
3. If X.json is a file, load X.json to a JavaScript Object. STOP
4. If X.node is a file, load X.node as binary addon. STOP
LOAD_INDEX(X)
1. If X/index.js is a file
a. Find the closest package scope SCOPE to X.
b. If no scope was found, load X/index.js as a CommonJS module. STOP.
c. If the SCOPE/package.json contains "type" field,
1. If the "type" field is "module", load X/index.js as an ECMAScript module. STOP.
2. Else, load X/index.js as a CommonJS module. STOP.
2. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP
3. If X/index.node is a file, load X/index.node as binary addon. STOP
LOAD_AS_DIRECTORY(X)
1. If X/package.json is a file,
a. Parse X/package.json, and look for "main" field.
b. If "main" is a falsy value, GOTO 2.
c. let M = X + (json main field)
d. LOAD_AS_FILE(M)
e. LOAD_INDEX(M)
f. LOAD_INDEX(X) DEPRECATED
g. THROW "not found"
2. LOAD_INDEX(X)
LOAD_NODE_MODULES(X, START)
1. Try to interpret X as a combination of NAME and SUBPATH where the name
may have a @scope/ prefix and the subpath begins with a slash (`/`).
2. let DIRS = NODE_MODULES_PATHS(START)
3. for each DIR in DIRS:
a. LOAD_PACKAGE_EXPORTS(SUBPATH, DIR/NAME)
b. LOAD_AS_FILE(DIR/X)
c. LOAD_AS_DIRECTORY(DIR/X)
NODE_MODULES_PATHS(START)
1. let PARTS = path split(START)
2. let I = count of PARTS - 1
3. let DIRS = []
4. while I >= 0,
a. if PARTS[I] = "node_modules", GOTO d.
b. DIR = path join(PARTS[0 .. I] + "node_modules")
c. DIRS = DIRS + DIR
d. let I = I - 1
5. return DIRS + GLOBAL_FOLDERS
FIND_PACKAGE_ID(PATH, PACKAGE_MAP)
1. Find the PACKAGE_ID for the entry whose "path" is a parent directory of PATH
2. If multiple entries are found, THROW "ambiguous resolution"
3. If no entry was found, THROW "external file".
4. return PACKAGE_ID
LOAD_PACKAGE_MAP(X, PARENT_PACKAGE_ID, PACKAGE_MAP)
1. Try to interpret X as a combination of NAME and SUBPATH where the name
may have a @scope/ prefix and the subpath begins with a slash (`/`).
2. Find the package map entry for key PARENT_PACKAGE_ID
3. Look up NAME in the entry's "dependencies" map.
4. If NAME is not found, THROW "not found".
5. Let TARGET be PACKAGE_MAP.packages[dependencies[name]]
6. Let PACKAGE_PATH be the resolved path of TARGET.
7. LOAD_PACKAGE_EXPORTS(SUBPATH, PACKAGE_PATH)
8. LOAD_AS_FILE(PACKAGE_PATH/SUBPATH)
9. LOAD_AS_DIRECTORY(PACKAGE_PATH/SUBPATH)
10. THROW "not found"
LOAD_PACKAGE_IMPORTS(X, DIR)
1. Find the closest package scope SCOPE to DIR.
2. If no scope was found, return.
3. If the SCOPE/package.json "imports" is null or undefined, return.
4. If `--no-require-module` is not enabled
a. let CONDITIONS = ["node", "require", "module-sync"]
b. Else, let CONDITIONS = ["node", "require"]
5. let MATCH = PACKAGE_IMPORTS_RESOLVE(X, pathToFileURL(SCOPE),
CONDITIONS) defined in the ESM resolver.
6. RESOLVE_ESM_MATCH(MATCH).
LOAD_PACKAGE_EXPORTS(SUBPATH, PACKAGE_DIR)
1. Parse PACKAGE_DIR/package.json, and look for "exports" field.
2. If "exports" is null or undefined, return.
3. If `--no-require-module` is not enabled
a. let CONDITIONS = ["node", "require", "module-sync"]
b. Else, let CONDITIONS = ["node", "require"]
4. let MATCH = PACKAGE_EXPORTS_RESOLVE(pathToFileURL(PACKAGE_DIR), "." + SUBPATH,
`package.json` "exports", CONDITIONS) defined in the ESM resolver.
5. RESOLVE_ESM_MATCH(MATCH)
LOAD_PACKAGE_SELF(X, DIR)
1. Find the closest package scope SCOPE to DIR.
2. If no scope was found, return.
3. If the SCOPE/package.json "exports" is null or undefined, return.
4. If the SCOPE/package.json "name" is not the first segment of X, return.
5. let MATCH = PACKAGE_EXPORTS_RESOLVE(pathToFileURL(SCOPE),
"." + X.slice("name".length), `package.json` "exports", ["node", "require"])
defined in the ESM resolver.
6. RESOLVE_ESM_MATCH(MATCH)
RESOLVE_ESM_MATCH(MATCH)
1. let RESOLVED_PATH = fileURLToPath(MATCH)
2. If the file at RESOLVED_PATH exists, load RESOLVED_PATH as its extension
format. STOP
3. THROW "not found"
The "ESM resolver" is defined in the ESM documentation.
Caching#
Modules are cached after the first time they are loaded. This means (among other
things) that every call to require('foo') will get exactly the same object
returned, if it would resolve to the same file.
Provided require.cache is not modified, multiple calls to require('foo')
will not cause the module code to be executed multiple times. This is an
important feature. With it, "partially done" objects can be returned, thus
allowing transitive dependencies to be loaded even when they would cause cycles.
To have a module execute code multiple times, export a function, and call that function.
Module caching caveats#
Modules are cached based on their resolved filename. Since modules may resolve
to a different filename based on the location of the calling module (loading
from node_modules folders), it is not a guarantee that require('foo') will
always return the exact same object, if it would resolve to different files.
Additionally, on case-insensitive file systems or operating systems, different
resolved filenames can point to the same file, but the cache will still treat
them as different modules and will reload the file multiple times. For example,
require('./foo') and require('./FOO') return two different objects,
irrespective of whether or not ./foo and ./FOO are the same file.
Built-in modules#
Node.js has several modules compiled into the binary. These modules are described in greater detail elsewhere in this documentation.
The built-in modules are defined within the Node.js source and are located in the
lib/ folder.
Built-in modules can be identified using the node: prefix, in which case
it bypasses the require cache. For instance, require('node:http') will
always return the built in HTTP module, even if there is require.cache entry
by that name.
Some built-in modules are always preferentially loaded if their identifier is
passed to require(). For instance, require('http') will always
return the built-in HTTP module, even if there is a file by that name.
The list of all the built-in modules can be retrieved from module.builtinModules.
The modules being all listed without the node: prefix, except those that mandate such
prefix (as explained in the next section).
Built-in modules with mandatory node: prefix#
When being loaded by require(), some built-in modules must be requested with the
node: prefix. This requirement exists to prevent newly introduced built-in
modules from having a conflict with user land packages that already have
taken the name. Currently the built-in modules that requires the node: prefix are:
The list of these modules is exposed in module.builtinModules, including the prefix.
Cycles#
When there are circular require() calls, a module might not have finished
executing when it is returned.
Consider this situation:
a.js:
console.log('a starting');
exports.done = false;
const b = require('./b.js');
console.log('in a, b.done = %j', b.done);
exports.done = true;
console.log('a done');
b.js:
console.log('b starting');
exports.done = false;
const a = require('./a.js');
console.log('in b, a.done = %j', a.done);
exports.done = true;
console.log('b done');
main.js:
console.log('main starting');
const a = require('./a.js');
const b = require('./b.js');
console.log('in main, a.done = %j, b.done = %j', a.done, b.done);
When main.js loads a.js, then a.js in turn loads b.js. At that
point, b.js tries to load a.js. In order to prevent an infinite
loop, an unfinished copy of the a.js exports object is returned to the
b.js module. b.js then finishes loading, and its exports object is
provided to the a.js module.
By the time main.js has loaded both modules, they're both finished.
The output of this program would thus be:
$ node main.js
main starting
a starting
b starting
in b, a.done = false
b done
in a, b.done = true
a done
in main, a.done = true, b.done = true
Careful planning is required to allow cyclic module dependencies to work correctly within an application.
File modules#
If the exact filename is not found, then Node.js will attempt to load the
required filename with the added extensions: .js, .json, and finally
.node. When loading a file that has a different extension (e.g. .cjs), its
full name must be passed to require(), including its file extension (e.g.
require('./file.cjs')).
.json files are parsed as JSON text files, .node files are interpreted as
compiled addon modules loaded with process.dlopen(). Files using any other
extension (or no extension at all) are parsed as JavaScript text files. Refer to
the Determining module system section to understand what parse goal will be
used.
A required module prefixed with '/' is an absolute path to the file. For
example, require('/home/marco/foo.js') will load the file at
/home/marco/foo.js.
A required module prefixed with './' is relative to the file calling
require(). That is, circle.js must be in the same directory as foo.js for
require('./circle') to find it.
Without a leading '/', './', or '../' to indicate a file, the module must
either be a core module or is loaded from a node_modules folder.
If the given path does not exist, require() will throw a
MODULE_NOT_FOUND error.
Folders as modules#
Stability: 3 - Legacy: Use subpath exports or subpath imports instead.
There are three ways in which a folder may be passed to require() as
an argument.
The first is to create a package.json file in the root of the folder,
which specifies a main module. An example package.json file might
look like this:
{ "name" : "some-library",
"main" : "./lib/some-library.js" }
If this was in a folder at ./some-library, then
require('./some-library') would attempt to load
./some-library/lib/some-library.js.
If there is no package.json file present in the directory, or if the
"main" entry is missing or cannot be resolved, then Node.js
will attempt to load an index.js or index.node file out of that
directory. For example, if there was no package.json file in the previous
example, then require('./some-library') would attempt to load:
./some-library/index.js./some-library/index.node
If these attempts fail, then Node.js will report the entire module as missing with the default error:
Error: Cannot find module 'some-library'
In all three above cases, an import('./some-library') call would result in a
ERR_UNSUPPORTED_DIR_IMPORT error. Using package subpath exports or
subpath imports can provide the same containment organization benefits as
folders as modules, and work for both require and import.
Loading from node_modules folders#
If the module identifier passed to require() is not a
built-in module, and does not begin with '/', '../', or
'./', then Node.js starts at the directory of the current module, and
adds /node_modules, and attempts to load the module from that location.
Node.js will not append node_modules to a path already ending in
node_modules.
If it is not found there, then it moves to the parent directory, and so on, until the root of the file system is reached.
For example, if the file at '/home/ry/projects/foo.js' called
require('bar.js'), then Node.js would look in the following locations, in
this order:
/home/ry/projects/node_modules/bar.js/home/ry/node_modules/bar.js/home/node_modules/bar.js/node_modules/bar.js
This allows programs to localize their dependencies, so that they do not clash.
It is possible to require specific files or sub modules distributed with a
module by including a path suffix after the module name. For instance
require('example-module/path/to/file') would resolve path/to/file
relative to where example-module is located. The suffixed path follows the
same module resolution semantics.
Loading from the global folders#
If the NODE_PATH environment variable is set to a colon-delimited list
of absolute paths, then Node.js will search those paths for modules if they
are not found elsewhere.
On Windows, NODE_PATH is delimited by semicolons (;) instead of colons.
NODE_PATH was originally created to support loading modules from
varying paths before the current module resolution algorithm was defined.
NODE_PATH is still supported, but is less necessary now that the Node.js
ecosystem has settled on a convention for locating dependent modules.
Sometimes deployments that rely on NODE_PATH show surprising behavior
when people are unaware that NODE_PATH must be set. Sometimes a
module's dependencies change, causing a different version (or even a
different module) to be loaded as the NODE_PATH is searched.
Additionally, Node.js will search in the following list of GLOBAL_FOLDERS:
- 1:
$HOME/.node_modules - 2:
$HOME/.node_libraries - 3:
$PREFIX/lib/node
Where $HOME is the user's home directory, and $PREFIX is the Node.js
configured node_prefix.
These are mostly for historic reasons.
It is strongly encouraged to place dependencies in the local node_modules
folder. These will be loaded faster, and more reliably.
The module wrapper#
Before a module's code is executed, Node.js will wrap it with a function wrapper that looks like the following:
(function(exports, require, module, __filename, __dirname) {
// Module code actually lives in here
});
By doing this, Node.js achieves a few things:
- It keeps top-level variables (defined with
var,const, orlet) scoped to the module rather than the global object. - It helps to provide some global-looking variables that are actually specific
to the module, such as:
- The
moduleandexportsobjects that the implementor can use to export values from the module. - The convenience variables
__filenameand__dirname, containing the module's absolute filename and directory path.
- The
The module scope#
__dirname#
- Type:
<string>
The directory name of the current module. This is the same as the
path.dirname() of the __filename.
Example: running node example.js from /Users/mjr
console.log(__dirname);
// Prints: /Users/mjr
console.log(path.dirname(__filename));
// Prints: /Users/mjr
__filename#
- Type:
<string>
The file name of the current module. This is the current module file's absolute path with symlinks resolved.
For a main program this is not necessarily the same as the file name used in the command line.
See __dirname for the directory name of the current module.
Examples:
Running node example.js from /Users/mjr
console.log(__filename);
// Prints: /Users/mjr/example.js
console.log(__dirname);
// Prints: /Users/mjr
Given two modules: a and b, where b is a dependency of
a and there is a directory structure of:
/Users/mjr/app/a.js/Users/mjr/app/node_modules/b/b.js
References to __filename within b.js will return
/Users/mjr/app/node_modules/b/b.js while references to __filename within
a.js will return /Users/mjr/app/a.js.
exports#
- Type:
<Object>
A reference to the module.exports that is shorter to type.
See the section about the exports shortcut for details on when to use
exports and when to use module.exports.
module#
- Type:
<module>
A reference to the current module, see the section about the
module object. In particular, module.exports is used for defining what
a module exports and makes available through require().
require(id)#
Used to import modules, JSON, and local files. Modules can be imported
from node_modules. Local modules and JSON files can be imported using
a relative path (e.g. ./, ./foo, ./bar/baz, ../foo) that will be
resolved against the directory named by __dirname (if defined) or
the current working directory. The relative paths of POSIX style are resolved
in an OS independent fashion, meaning that the examples above will work on
Windows in the same way they would on Unix systems.
// Importing a local module with a path relative to the `__dirname` or current
// working directory. (On Windows, this would resolve to .\path\myLocalModule.)
const myLocalModule = require('./path/myLocalModule');
// Importing a JSON file:
const jsonData = require('./path/filename.json');
// Importing a module from node_modules or Node.js built-in module:
const crypto = require('node:crypto');
require.cache#
- Type:
<Object>
Modules are cached in this object when they are required. By deleting a key
value from this object, the next require will reload the module.
This does not apply to native addons, for which reloading will result in an
error.
Adding or replacing entries is also possible. This cache is checked before
built-in modules and if a name matching a built-in module is added to the cache,
only node:-prefixed require calls are going to receive the built-in module.
Use with care!
const assert = require('node:assert');
const realFs = require('node:fs');
const fakeFs = {};
require.cache.fs = { exports: fakeFs };
assert.strictEqual(require('fs'), fakeFs);
assert.strictEqual(require('node:fs'), realFs);
require.extensions#
Stability: 0 - Deprecated
- Type:
<Object>
Instruct require on how to handle certain file extensions.
Process files with the extension .sjs as .js:
require.extensions['.sjs'] = require.extensions['.js'];
Deprecated. In the past, this list has been used to load non-JavaScript modules into Node.js by compiling them on-demand. However, in practice, there are much better ways to do this, such as loading modules via some other Node.js program, or compiling them to JavaScript ahead of time.
Avoid using require.extensions. Use could cause subtle bugs and resolving the
extensions gets slower with each registered extension.
require.main#
- Type:
<module>|<undefined>
The Module object representing the entry script loaded when the Node.js
process launched, or undefined if the entry point of the program is not a
CommonJS module.
See "Accessing the main module".
In entry.js script:
console.log(require.main);
node entry.js
Module {
id: '.',
path: '/absolute/path/to',
exports: {},
filename: '/absolute/path/to/entry.js',
loaded: false,
children: [],
paths:
[ '/absolute/path/to/node_modules',
'/absolute/path/node_modules',
'/absolute/node_modules',
'/node_modules' ] }
require.resolve(request[, options])#
request<string>The module path to resolve.options<Object>paths<string>[] Paths to resolve module location from. If present, these paths are used instead of the default resolution paths, with the exception of GLOBAL_FOLDERS like$HOME/.node_modules, which are always included. Each of these paths is used as a starting point for the module resolution algorithm, meaning that thenode_moduleshierarchy is checked from this location.
- Returns:
<string>
Use the internal require() machinery to look up the location of a module,
but rather than loading the module, just return the resolved filename.
If the module can not be found, a MODULE_NOT_FOUND error is thrown.
require.resolve.paths(request)#
request<string>The module path whose lookup paths are being retrieved.- Returns:
<string>[] |<null>
Returns an array containing the paths searched during resolution of request or
null if the request string references a core module, for example http or
fs.
The module object#
- Type:
<Object>
In each module, the module free variable is a reference to the object
representing the current module. For convenience, module.exports is
also accessible via the exports module-global. module is not actually
a global but rather local to each module.
module.children#
- Type:
<module>[]
The module objects required for the first time by this one.
module.exports#
- Type:
<Object>
The module.exports object is created by the Module system. Sometimes this is
not acceptable; many want their module to be an instance of some class. To do
this, assign the desired export object to module.exports. Assigning
the desired object to exports will simply rebind the local exports variable,
which is probably not what is desired.
For example, suppose we were making a module called a.js:
const EventEmitter = require('node:events');
module.exports = new EventEmitter();
// Do some work, and after some time emit
// the 'ready' event from the module itself.
setTimeout(() => {
module.exports.emit('ready');
}, 1000);
Then in another file we could do:
const a = require('./a');
a.on('ready', () => {
console.log('module "a" is ready');
});
Assignment to module.exports must be done immediately. It cannot be
done in any callbacks. This does not work:
x.js:
setTimeout(() => {
module.exports = { a: 'hello' };
}, 0);
y.js:
const x = require('./x');
console.log(x.a);
exports shortcut#
The exports variable is available within a module's file-level scope, and is
assigned the value of module.exports before the module is evaluated.
It allows a shortcut, so that module.exports.f = ... can be written more
succinctly as exports.f = .... However, be aware that like any variable, if a
new value is assigned to exports, it is no longer bound to module.exports:
module.exports.hello = true; // Exported from require of module
exports = { hello: false }; // Not exported, only available in the module
When the module.exports property is being completely replaced by a new
object, it is common to also reassign exports:
module.exports = exports = function Constructor() {
// ... etc.
};
To illustrate the behavior, imagine this hypothetical implementation of
require(), which is quite similar to what is actually done by require():
function require(/* ... */) {
const module = { exports: {} };
((module, exports) => {
// Module code here. In this example, define a function.
function someFunc() {}
exports = someFunc;
// At this point, exports is no longer a shortcut to module.exports, and
// this module will still export an empty default object.
module.exports = someFunc;
// At this point, the module will now export someFunc, instead of the
// default object.
})(module, module.exports);
return module.exports;
}
module.filename#
- Type:
<string>
The fully resolved filename of the module.
module.id#
- Type:
<string>
The identifier for the module. Typically this is the fully resolved filename.
module.isPreloading#
- Type:
<boolean>trueif the module is running during the Node.js preload phase.
module.loaded#
- Type:
<boolean>
Whether or not the module is done loading, or is in the process of loading.
module.parent#
Stability: 0 - Deprecated: Please use require.main and
module.children instead.
- Type:
<module>|<null>|<undefined>
The module that first required this one, or null if the current module is the
entry point of the current process, or undefined if the module was loaded by
something that is not a CommonJS module (E.G.: REPL or import).
module.path#
- Type:
<string>
The directory name of the module. This is usually the same as the
path.dirname() of the module.id.
module.paths#
- Type:
<string>[]
The search paths for the module.
module.require(id)#
The module.require() method provides a way to load a module as if
require() was called from the original module.
In order to do this, it is necessary to get a reference to the module object.
Since require() returns the module.exports, and the module is typically
only available within a specific module's code, it must be explicitly exported
in order to be used.
The Module object#
This section was moved to
Modules: module core module.
Source map v3 support#
This section was moved to
Modules: module core module.
Modules: ECMAScript modules#
Stability: 2 - Stable
Introduction#
ECMAScript modules are the official standard format to package JavaScript
code for reuse. Modules are defined using a variety of import and
export statements.
The following example of an ES module exports a function:
// addTwo.mjs
function addTwo(num) {
return num + 2;
}
export { addTwo };
The following example of an ES module imports the function from addTwo.mjs:
// app.mjs
import { addTwo } from './addTwo.mjs';
// Prints: 6
console.log(addTwo(4));
Node.js fully supports ECMAScript modules as they are currently specified and provides interoperability between them and its original module format, CommonJS.
Enabling#
Node.js has two module systems: CommonJS modules and ECMAScript modules.
Authors can tell Node.js to interpret JavaScript as an ES module via the .mjs
file extension, the package.json "type" field with a value "module",
or the --input-type flag with a value of "module". These are explicit
markers of code being intended to run as an ES module.
Inversely, authors can explicitly tell Node.js to interpret JavaScript as
CommonJS via the .cjs file extension, the package.json "type" field
with a value "commonjs", or the --input-type flag with a value of
"commonjs".
When code lacks explicit markers for either module system, Node.js will inspect the source code of a module to look for ES module syntax. If such syntax is found, Node.js will run the code as an ES module; otherwise it will run the module as CommonJS. See Determining module system for more details.
Packages#
This section was moved to Modules: Packages.
import Specifiers#
Terminology#
The specifier of an import statement is the string after the from keyword,
e.g. 'node:path' in import { sep } from 'node:path'. Specifiers are also
used in export from statements, and as the argument to an import()
expression.
There are three types of specifiers:
-
Relative specifiers like
'./startup.js'or'../config.mjs'. They refer to a path relative to the location of the importing file. The file extension is always necessary for these. -
Bare specifiers like
'some-package'or'some-package/shuffle'. They can refer to the main entry point of a package by the package name, or a specific feature module within a package prefixed by the package name as per the examples respectively. Including the file extension is only necessary for packages without an"exports"field. -
Absolute specifiers like
'file:///opt/nodejs/config.js'. They refer directly and explicitly to a full path.
Bare specifier resolutions are handled by the Node.js module resolution and loading algorithm. All other specifier resolutions are always only resolved with the standard relative URL resolution semantics.
Like in CommonJS, module files within packages can be accessed by appending a
path to the package name unless the package's package.json contains an
"exports" field, in which case files within packages can only be accessed
via the paths defined in "exports".
For details on these package resolution rules that apply to bare specifiers in the Node.js module resolution, see the packages documentation.
Mandatory file extensions#
A file extension must be provided when using the import keyword to resolve
relative or absolute specifiers. Directory indexes (e.g. './startup/index.js')
must also be fully specified.
This behavior matches how import behaves in browser environments, assuming a
typically configured server.
URLs#
ES modules are resolved and cached as URLs. This means that special characters
must be percent-encoded, such as # with %23 and ? with %3F.
file:, node:, and data: URL schemes are supported. A specifier like
'https://example.com/app.js' is not supported natively in Node.js unless using
a custom HTTPS loader.
file: URLs#
Modules are loaded multiple times if the import specifier used to resolve
them has a different query or fragment.
import './foo.mjs?query=1'; // loads ./foo.mjs with query of "?query=1"
import './foo.mjs?query=2'; // loads ./foo.mjs with query of "?query=2"
The volume root may be referenced via /, //, or file:///. Given the
differences between URL and path resolution (such as percent encoding
details), it is recommended to use url.pathToFileURL when importing a path.
data: imports#
data: URLs are supported for importing with the following MIME types:
text/javascriptfor ES modulesapplication/jsonfor JSONapplication/wasmfor Wasm
import 'data:text/javascript,console.log("hello!");';
import _ from 'data:application/json,"world!"' with { type: 'json' };
data: URLs only resolve bare specifiers for builtin modules
and absolute specifiers. Resolving
relative specifiers does not work because data: is not a
special scheme. For example, attempting to load ./foo
from data:text/javascript,import "./foo"; fails to resolve because there
is no concept of relative resolution for data: URLs.
node: imports#
node: URLs are supported as an alternative means to load Node.js builtin
modules. This URL scheme allows for builtin modules to be referenced by valid
absolute URL strings.
import fs from 'node:fs/promises';
Import attributes#
Import attributes are an inline syntax for module import statements to pass on more information alongside the module specifier.
import fooData from './foo.json' with { type: 'json' };
const { default: barData } =
await import('./bar.json', { with: { type: 'json' } });
Node.js only supports the type attribute, for which it supports the following values:
Attribute type |
Needed for |
|---|---|
'json' |
JSON modules |
'text' |
Text modules |
The type: 'json' attribute is mandatory when importing JSON modules.
The type: 'text' attribute is mandatory when importing text modules.
Built-in modules#
Built-in modules provide named exports of their public API. A
default export is also provided which is the value of the CommonJS exports.
The default export can be used for, among other things, modifying the named
exports. Named exports of built-in modules are updated only by calling
module.syncBuiltinESMExports().
import EventEmitter from 'node:events';
const e = new EventEmitter();
import { readFile } from 'node:fs';
readFile('./foo.txt', (err, source) => {
if (err) {
console.error(err);
} else {
console.log(source);
}
});
import fs, { readFileSync } from 'node:fs';
import { syncBuiltinESMExports } from 'node:module';
import { Buffer } from 'node:buffer';
fs.readFileSync = () => Buffer.from('Hello, ESM');
syncBuiltinESMExports();
fs.readFileSync === readFileSync;
When importing built-in modules, all the named exports (i.e. properties of the module exports object) are populated even if they are not individually accessed. This can make initial imports of built-in modules slightly slower compared to loading them with
require()orprocess.getBuiltinModule(), where the module exports object is evaluated immediately, but some of its properties may only be initialized when first accessed individually.
import() expressions#
Dynamic import() provides an asynchronous way to import modules. It is
supported in both CommonJS and ES modules, and can be used to load both CommonJS
and ES modules.
import.meta#
- Type:
<Object>
The import.meta meta property is an Object that contains the following
properties. It is only supported in ES modules.
import.meta.dirname#
- Type:
<string>The directory name of the current module.
This is the same as the path.dirname() of the import.meta.filename.
Caveat: only present on
file:modules.
import.meta.filename#
- Type:
<string>The full absolute path and filename of the current module, with symlinks resolved.
This is the same as the url.fileURLToPath() of the import.meta.url.
Caveat only local modules support this property. Modules not using the
file:protocol will not provide it.
import.meta.url#
- Type:
<string>The absolutefile:URL of the module.
This is defined exactly the same as it is in browsers providing the URL of the current module file.
This enables useful patterns such as relative file loading:
import { readFileSync } from 'node:fs';
const buffer = readFileSync(new URL('./data.proto', import.meta.url));
import.meta.main#
Stability: 1.0 - Early development
- Type:
<boolean>truewhen the current module is the entry point of the current process;falseotherwise.
Equivalent to require.main === module in CommonJS.
Analogous to Python's __name__ == "__main__".
export function foo() {
return 'Hello, world';
}
function main() {
const message = foo();
console.log(message);
}
if (import.meta.main) main();
// `foo` can be imported from another module without possible side-effects from `main`
import.meta.resolve(specifier)#
Stability: 1.2 - Release candidate
specifier<string>The module specifier to resolve relative to the current module.- Returns:
<string>The absolute URL string that the specifier would resolve to.
import.meta.resolve is a module-relative resolution function scoped to
each module, returning the URL string.
const dependencyAsset = import.meta.resolve('component-lib/asset.css');
// file:///app/node_modules/component-lib/asset.css
import.meta.resolve('./dep.js');
// file:///app/dep.js
All features of the Node.js module resolution are supported. Dependency resolutions are subject to the permitted exports resolutions within the package.
Caveats:
- This can result in synchronous file-system operations, which
can impact performance similarly to
require.resolve. - This feature is not available within custom loaders (it would create a deadlock).
Non-standard API:
When using the --experimental-import-meta-resolve flag, that function accepts
a second argument:
Interoperability with CommonJS#
import statements#
An import statement can reference an ES module or a CommonJS module.
import statements are permitted only in ES modules, but dynamic import()
expressions are supported in CommonJS for loading ES modules.
When importing CommonJS modules, the
module.exports object is provided as the default export. Named exports may be
available, provided by static analysis as a convenience for better ecosystem
compatibility.
require#
The CommonJS module require currently only supports loading synchronous ES
modules (that is, ES modules that do not use top-level await).
See Loading ECMAScript modules using require() for details.
CommonJS Namespaces#
CommonJS modules consist of a module.exports object which can be of any type.
To support this, when importing CommonJS from an ECMAScript module, a namespace
wrapper for the CommonJS module is constructed, which always provides a
default export key pointing to the CommonJS module.exports value.
In addition, a heuristic static analysis is performed against the source text of
the CommonJS module to get a best-effort static list of exports to provide on
the namespace from values on module.exports. This is necessary since these
namespaces must be constructed prior to the evaluation of the CJS module.
These CommonJS namespace objects also provide the default export as a
'module.exports' named export, in order to unambiguously indicate that their
representation in CommonJS uses this value, and not the namespace value. This
mirrors the semantics of the handling of the 'module.exports' export name in
require(esm) interop support.
When importing a CommonJS module, it can be reliably imported using the ES module default import or its corresponding sugar syntax:
import { default as cjs } from 'cjs';
// Identical to the above
import cjsSugar from 'cjs';
console.log(cjs);
console.log(cjs === cjsSugar);
// Prints:
// <module.exports>
// true
This Module Namespace Exotic Object can be directly observed either when using
import * as m from 'cjs' or a dynamic import:
import * as m from 'cjs';
console.log(m);
console.log(m === await import('cjs'));
// Prints:
// [Module] { default: <module.exports>, 'module.exports': <module.exports> }
// true
For better compatibility with existing usage in the JS ecosystem, Node.js in addition attempts to determine the CommonJS named exports of every imported CommonJS module to provide them as separate ES module exports using a static analysis process.
For example, consider a CommonJS module written:
// cjs.cjs
exports.name = 'exported';
The preceding module supports named imports in ES modules:
import { name } from './cjs.cjs';
console.log(name);
// Prints: 'exported'
import cjs from './cjs.cjs';
console.log(cjs);
// Prints: { name: 'exported' }
import * as m from './cjs.cjs';
console.log(m);
// Prints:
// [Module] {
// default: { name: 'exported' },
// 'module.exports': { name: 'exported' },
// name: 'exported'
// }
As can be seen from the last example of the Module Namespace Exotic Object being
logged, the name export is copied off of the module.exports object and set
directly on the ES module namespace when the module is imported.
Live binding updates or new exports added to module.exports are not detected
for these named exports.
The detection of named exports is based on common syntax patterns but does not always correctly detect named exports. In these cases, using the default import form described above can be a better option.
Named exports detection covers many common export patterns, reexport patterns and build tool and transpiler outputs. See merve for the exact semantics implemented.
Differences between ES modules and CommonJS#
No require, exports, or module.exports#
In most cases, the ES module import can be used to load CommonJS modules.
If needed, a require function can be constructed within an ES module using
module.createRequire().
No __filename or __dirname#
These CommonJS variables are not available in ES modules.
__filename and __dirname use cases can be replicated via
import.meta.filename and import.meta.dirname.
No Addon Loading#
Addons are not currently supported with ES module imports.
They can instead be loaded with module.createRequire() or
process.dlopen.
No require.main#
To replace require.main === module, there is the import.meta.main API.
No require.resolve#
Relative resolution can be handled via new URL('./local', import.meta.url).
For a complete require.resolve replacement, there is the
import.meta.resolve API.
Alternatively module.createRequire() can be used.
No NODE_PATH#
NODE_PATH is not part of resolving import specifiers. Please use symlinks
if this behavior is desired.
No require.extensions#
require.extensions is not used by import. Module customization hooks can
provide a replacement.
No require.cache#
require.cache is not used by import as the ES module loader has its own
separate cache.
JSON modules#
JSON files can be referenced by import:
import packageConfig from './package.json' with { type: 'json' };
The with { type: 'json' } syntax is mandatory; see Import Attributes.
The imported JSON only exposes a default export. There is no support for named
exports. A cache entry is created in the CommonJS cache to avoid duplication.
The same object is returned in CommonJS if the JSON module has already been
imported from the same path.
Text modules#
Stability: 1.0 - Early development
Text modules are available behind the --experimental-import-text flag.
Text files can be referenced by import:
import message from './message.txt' with { type: 'text' };
The with { type: 'text' } syntax is mandatory; see Import Attributes.
The imported text only exposes a default export whose value is the module
source as a string.
Wasm modules#
Importing both WebAssembly module instances and WebAssembly source phase imports is supported.
Both of these integrations are in line with the ES Module Integration Proposal for WebAssembly.
Wasm Source Phase Imports#
Stability: 1.2 - Release candidate
The Source Phase Imports proposal allows the import source keyword
combination to import a WebAssembly.Module object directly, instead of getting
a module instance already instantiated with its dependencies.
This is useful when needing custom instantiations for Wasm, while still resolving and loading it through the ES module integration.
For example, to create multiple instances of a module, or to pass custom imports
into a new instance of library.wasm:
import source libraryModule from './library.wasm';
const instance1 = await WebAssembly.instantiate(libraryModule, importObject1);
const instance2 = await WebAssembly.instantiate(libraryModule, importObject2);
In addition to the static source phase, there is also a dynamic variant of the
source phase via the import.source dynamic phase import syntax:
const dynamicLibrary = await import.source('./library.wasm');
const instance = await WebAssembly.instantiate(dynamicLibrary, importObject);
JavaScript String Builtins#
Stability: 1.2 - Release candidate
When importing WebAssembly modules, the
WebAssembly JS String Builtins Proposal is automatically enabled through the
ESM Integration. This allows WebAssembly modules to directly use efficient
compile-time string builtins from the wasm:js-string namespace.
For example, the following Wasm module exports a string getLength function using
the wasm:js-string length builtin:
(module
;; Compile-time import of the string length builtin.
(import "wasm:js-string" "length" (func $string_length (param externref) (result i32)))
;; Define getLength, taking a JS value parameter assumed to be a string,
;; calling string length on it and returning the result.
(func $getLength (param $str externref) (result i32)
local.get $str
call $string_length
)
;; Export the getLength function.
(export "getLength" (func $get_length))
)
import { getLength } from './string-len.wasm';
getLength('foo'); // Returns 3.
Wasm builtins are compile-time imports that are linked during module compilation
rather than during instantiation. They do not behave like normal module graph
imports and they cannot be inspected via WebAssembly.Module.imports(mod)
or virtualized unless recompiling the module using the direct
WebAssembly.compile API with string builtins disabled.
String constants may also be imported from the wasm:js/string-constants builtin
import URL, allowing static JS string globals to be defined:
(module
(import "wasm:js/string-constants" "hello" (global $hello externref))
)
Importing a module in the source phase before it has been instantiated will also use the compile-time builtins automatically:
import source mod from './string-len.wasm';
const { exports: { getLength } } = await WebAssembly.instantiate(mod, {});
getLength('foo'); // Also returns 3.
Wasm Instance Phase Imports#
Stability: 1.1 - Active development
Instance imports allow any .wasm files to be imported as normal modules,
supporting their module imports in turn.
For example, an index.js containing:
import * as M from './library.wasm';
console.log(M);
executed under:
node index.mjs
would provide the exports interface for the instantiation of library.wasm.
Reserved Wasm Namespaces#
When importing WebAssembly module instances, they cannot use import module names or import/export names that start with reserved prefixes:
wasm-js:- reserved in all module import names, module names and export names.wasm:- reserved in module import names and export names (imported module names are allowed in order to support future builtin polyfills).
Importing a module using the above reserved names will throw a
WebAssembly.LinkError.
Top-level await#
The await keyword may be used in the top level body of an ECMAScript module.
Assuming an a.mjs with
export const five = await Promise.resolve(5);
And a b.mjs with
import { five } from './a.mjs';
console.log(five); // Logs `5`
node b.mjs # works
If a top level await expression never resolves, the node process will exit
with a 13 status code.
import { spawn } from 'node:child_process';
import { execPath } from 'node:process';
spawn(execPath, [
'--input-type=module',
'--eval',
// Never-resolving Promise:
'await new Promise(() => {})',
]).once('exit', (code) => {
console.log(code); // Logs `13`
});
Loaders#
The former Loaders documentation is now at Modules: Customization hooks.
Resolution and loading algorithm#
Features#
The default resolver has the following properties:
- FileURL-based resolution as is used by ES modules
- Relative and absolute URL resolution
- No default extensions
- No folder mains
- Bare specifier package resolution lookup through node_modules
- Does not fail on unknown extensions or protocols
- Can optionally provide a hint of the format to the loading phase
The default loader has the following properties
- Support for builtin module loading via
node:URLs - Support for "inline" module loading via
data:URLs - Support for
file:module loading - Fails on any other URL protocol
- Fails on unknown extensions for
file:loading (supports only.cjs,.js, and.mjs)
When the --experimental-package-map flag is enabled, bare specifier
resolution first consults the package map configuration. If the importing
module is within a mapped package and the specifier matches a declared
dependency, the package map resolution takes precedence. See Package maps
for details.
Resolution algorithm#
The algorithm to load an ES module specifier is given through the ESM_RESOLVE method below. It returns the resolved URL for a module specifier relative to a parentURL.
The resolution algorithm determines the full resolved URL for a module
load, along with its suggested module format. The resolution algorithm
does not determine whether the resolved URL protocol can be loaded,
or whether the file extensions are permitted, instead these validations
are applied by Node.js during the load phase
(for example, if it was asked to load a URL that has a protocol that is
not file:, data: or node:.
The algorithm also tries to determine the format of the file based
on the extension (see ESM_FILE_FORMAT algorithm below). If it does
not recognize the file extension (eg if it is not .mjs, .cjs, or
.json), then a format of undefined is returned,
which will throw during the load phase.
The algorithm to determine the module format of a resolved URL is provided by ESM_FILE_FORMAT, which returns the unique module format for any file. The "module" format is returned for an ECMAScript Module, while the "commonjs" format is used to indicate loading through the legacy CommonJS loader. Additional formats such as "addon" can be extended in future updates.
In the following algorithms, all subroutine errors are propagated as errors of these top-level routines unless stated otherwise.
defaultConditions is the conditional environment name array,
["node", "import"].
The resolver can throw the following errors:
- Invalid Module Specifier: Module specifier is an invalid URL, package name or package subpath specifier.
- Invalid Package Configuration: package.json configuration is invalid or contains an invalid configuration.
- Invalid Package Target: Package exports or imports define a target module for the package that is an invalid type or string target.
- Package Path Not Exported: Package exports do not define or permit a target subpath in the package for the given module.
- Package Import Not Defined: Package imports do not define the specifier.
- Module Not Found: The package or module requested does not exist.
- Unsupported Directory Import: The resolved path corresponds to a directory, which is not a supported target for module imports.
Resolution Algorithm Specification#
ESM_RESOLVE(specifier, parentURL)
- Let resolved be undefined.
- If specifier is a valid URL, then
- Set resolved to the result of parsing and reserializing specifier as a URL.
- Otherwise, if specifier starts with "/", "./", or "../", then
- Set resolved to the URL resolution of specifier relative to parentURL.
- Otherwise, if specifier starts with "#", then
- Set resolved to the result of PACKAGE_IMPORTS_RESOLVE(specifier, parentURL, defaultConditions).
- Otherwise,
- Note: specifier is now a bare specifier.
- Set resolved the result of PACKAGE_RESOLVE(specifier, parentURL).
- Let format be undefined.
- If resolved is a "file:" URL, then
- If resolved contains any percent encodings of "/" or "\" ("%2F" and "%5C" respectively), then
- Throw an Invalid Module Specifier error.
- If the file at resolved is a directory, then
- Throw an Unsupported Directory Import error.
- If the file at resolved does not exist, then
- Throw a Module Not Found error.
- Set resolved to the real path of resolved, maintaining the same URL querystring and fragment components.
- Set format to the result of ESM_FILE_FORMAT(resolved).
- Otherwise,
- Set format the module format of the content type associated with the URL resolved.
- Return format and resolved to the loading phase
PACKAGE_RESOLVE(packageSpecifier, parentURL)
- Let packageName be undefined.
- If packageSpecifier is an empty string, then
- Throw an Invalid Module Specifier error.
- If packageSpecifier is a Node.js builtin module name, then
- Return the string "node:" concatenated with packageSpecifier.
- If packageSpecifier does not start with "@", then
- Set packageName to the substring of packageSpecifier until the first "/" separator or the end of the string.
- Otherwise,
- If packageSpecifier does not contain a "/" separator, then
- Throw an Invalid Module Specifier error.
- Set packageName to the substring of packageSpecifier until the second "/" separator or the end of the string.
- If packageName starts with "." or contains "\" or "%", then
- Throw an Invalid Module Specifier error.
- Let packageSubpath be "." concatenated with the substring of packageSpecifier from the position at the length of packageName.
- Let selfUrl be the result of PACKAGE_SELF_RESOLVE(packageName, packageSubpath, parentURL).
- If selfUrl is not undefined, return selfUrl.
- While parentURL is not the file system root,
- Let packageURL be the URL resolution of "node_modules/" concatenated with packageName, relative to parentURL.
- Set parentURL to the parent folder URL of parentURL.
- If the folder at packageURL does not exist, then
- Continue the next loop iteration.
- Let pjson be the result of READ_PACKAGE_JSON(packageURL).
- If pjson is not null and pjson.exports is not null or undefined, then
- Return the result of PACKAGE_EXPORTS_RESOLVE(packageURL, packageSubpath, pjson.exports, defaultConditions).
- Otherwise, if packageSubpath is equal to ".", then
- If pjson.main is a string, then
- Return the URL resolution of main in packageURL.
- Otherwise,
- Return the URL resolution of packageSubpath in packageURL.
- Throw a Module Not Found error.
PACKAGE_SELF_RESOLVE(packageName, packageSubpath, parentURL)
- Let packageURL be the result of LOOKUP_PACKAGE_SCOPE(parentURL).
- If packageURL is null, then
- Return undefined.
- Let pjson be the result of READ_PACKAGE_JSON(packageURL).
- If pjson is null or if pjson.exports is null or undefined, then
- Return undefined.
- If pjson.name is equal to packageName, then
- Return the result of PACKAGE_EXPORTS_RESOLVE(packageURL, packageSubpath, pjson.exports, defaultConditions).
- Otherwise, return undefined.
PACKAGE_EXPORTS_RESOLVE(packageURL, subpath, exports, conditions)
Note: This function is directly invoked by the CommonJS resolution algorithm.
- If exports is an Object with both a key starting with "." and a key not starting with ".", throw an Invalid Package Configuration error.
- If subpath is equal to ".", then
- Let mainExport be undefined.
- If exports is a String or Array, or an Object containing no keys starting with ".", then
- Set mainExport to exports.
- Otherwise if exports is an Object containing a "." property, then
- Set mainExport to exports["."].
- If mainExport is not undefined, then
- Let resolved be the result of PACKAGE_TARGET_RESOLVE( packageURL, mainExport, null, false, conditions).
- If resolved is not null or undefined, return resolved.
- Otherwise, if exports is an Object and all keys of exports start with ".", then
- Assert: subpath begins with "./".
- Let resolved be the result of PACKAGE_IMPORTS_EXPORTS_RESOLVE( subpath, exports, packageURL, false, conditions).
- If resolved is not null or undefined, return resolved.
- Throw a Package Path Not Exported error.
PACKAGE_IMPORTS_RESOLVE(specifier, parentURL, conditions)
Note: This function is directly invoked by the CommonJS resolution algorithm.
- Assert: specifier begins with "#".
- If specifier is exactly equal to "#", then
- Throw an Invalid Module Specifier error.
- Let packageURL be the result of LOOKUP_PACKAGE_SCOPE(parentURL).
- If packageURL is not null, then
- Let pjson be the result of READ_PACKAGE_JSON(packageURL).
- If pjson.imports is a non-null Object, then
- Let resolved be the result of PACKAGE_IMPORTS_EXPORTS_RESOLVE( specifier, pjson.imports, packageURL, true, conditions).
- If resolved is not null or undefined, return resolved.
- Throw a Package Import Not Defined error.
PACKAGE_IMPORTS_EXPORTS_RESOLVE(matchKey, matchObj, packageURL, isImports, conditions)
- If matchKey ends in "/", then
- Throw an Invalid Module Specifier error.
- If matchKey is a key of matchObj and does not contain "*", then
- Let target be the value of matchObj[matchKey].
- Return the result of PACKAGE_TARGET_RESOLVE(packageURL, target, null, isImports, conditions).
- Let expansionKeys be the list of keys of matchObj containing only a single "*", sorted by the sorting function PATTERN_KEY_COMPARE which orders in descending order of specificity.
- For each key expansionKey in expansionKeys, do
- Let patternBase be the substring of expansionKey up to but excluding the first "*" character.
- If matchKey starts with but is not equal to patternBase, then
- Let patternTrailer be the substring of expansionKey from the index after the first "*" character.
- If patternTrailer has zero length, or if matchKey ends with patternTrailer and the length of matchKey is greater than or equal to the length of expansionKey, then
- Let target be the value of matchObj[expansionKey].
- Let patternMatch be the substring of matchKey starting at the index of the length of patternBase up to the length of matchKey minus the length of patternTrailer.
- Return the result of PACKAGE_TARGET_RESOLVE(packageURL, target, patternMatch, isImports, conditions).
- Return null.
PATTERN_KEY_COMPARE(keyA, keyB)
- Assert: keyA contains only a single "*".
- Assert: keyB contains only a single "*".
- Let baseLengthA be the index of "*" in keyA.
- Let baseLengthB be the index of "*" in keyB.
- If baseLengthA is greater than baseLengthB, return -1.
- If baseLengthB is greater than baseLengthA, return 1.
- If the length of keyA is greater than the length of keyB, return -1.
- If the length of keyB is greater than the length of keyA, return 1.
- Return 0.
PACKAGE_TARGET_RESOLVE(packageURL, target, patternMatch, isImports, conditions)
- If target is a String, then
- If target does not start with "./", then
- If isImports is false, or if target starts with "../" or "/", or if target is a valid URL, then
- Throw an Invalid Package Target error.
- If patternMatch is a String, then
- Return PACKAGE_RESOLVE(target with every instance of "*" replaced by patternMatch, packageURL + "/").
- Return PACKAGE_RESOLVE(target, packageURL + "/").
- If target split on "/" or "\" contains any "", ".", "..", or "node_modules" segments after the first "." segment, case insensitive and including percent encoded variants, throw an Invalid Package Target error.
- Let resolvedTarget be the URL resolution of the concatenation of packageURL and target.
- Assert: packageURL is contained in resolvedTarget.
- If patternMatch is null, then
- Return resolvedTarget.
- If patternMatch split on "/" or "\" contains any "", ".", "..", or "node_modules" segments, case insensitive and including percent encoded variants, throw an Invalid Module Specifier error.
- Return the URL resolution of resolvedTarget with every instance of "*" replaced with patternMatch.
- Otherwise, if target is a non-null Object, then
- If target contains any index property keys, as defined in ECMA-262 6.1.7 Array Index, throw an Invalid Package Configuration error.
- For each property p of target, in object insertion order as,
- If p equals "default" or conditions contains an entry for p, then
- Let targetValue be the value of the p property in target.
- Let resolved be the result of PACKAGE_TARGET_RESOLVE( packageURL, targetValue, patternMatch, isImports, conditions).
- If resolved is equal to undefined, continue the loop.
- Return resolved.
- Return undefined.
- Otherwise, if target is an Array, then
- If _target.length is zero, return null.
- For each item targetValue in target, do
- Let resolved be the result of PACKAGE_TARGET_RESOLVE( packageURL, targetValue, patternMatch, isImports, conditions), continuing the loop on any Invalid Package Target error.
- If resolved is undefined, continue the loop.
- Return resolved.
- Return or throw the last fallback resolution null return or error.
- Otherwise, if target is null, return null.
- Otherwise throw an Invalid Package Target error.
ESM_FILE_FORMAT(url)
- Assert: url corresponds to an existing file.
- If url ends in ".mjs", then
- Return "module".
- If url ends in ".cjs", then
- Return "commonjs".
- If url ends in ".json", then
- Return "json".
- If url ends in ".wasm", then
- Return "wasm".
- If
--experimental-addon-modulesis enabled and url ends in ".node", then
- Return "addon".
- Let packageURL be the result of LOOKUP_PACKAGE_SCOPE(url).
- Let pjson be the result of READ_PACKAGE_JSON(packageURL).
- Let packageType be null.
- If pjson?.type is "module" or "commonjs", then
- Set packageType to pjson.type.
- If url ends in ".js", then
- If packageType is not null, then
- Return packageType.
- If the result of DETECT_MODULE_SYNTAX(source) is true, then
- Return "module".
- Return "commonjs".
- If url does not have any extension, then
- If packageType is "module" and the file at url contains the "application/wasm" content type header for a WebAssembly module, then
- Return "wasm".
- If packageType is not null, then
- Return packageType.
- If the result of DETECT_MODULE_SYNTAX(source) is true, then
- Return "module".
- Return "commonjs".
- Return undefined (will throw during load phase).
LOOKUP_PACKAGE_SCOPE(url)
- Let scopeURL be url.
- While scopeURL is not the file system root,
- Set scopeURL to the parent URL of scopeURL.
- If scopeURL ends in a "node_modules" path segment, return null.
- Let pjsonURL be the resolution of "package.json" within scopeURL.
- if the file at pjsonURL exists, then
- Return scopeURL.
- Return null.
READ_PACKAGE_JSON(packageURL)
- Let pjsonURL be the resolution of "package.json" within packageURL.
- If the file at pjsonURL does not exist, then
- Return null.
- If the file at packageURL does not parse as valid JSON, then
- Throw an Invalid Package Configuration error.
- Return the parsed JSON source of the file at pjsonURL.
DETECT_MODULE_SYNTAX(source)
- Parse source as an ECMAScript module.
- If the parse is successful, then
- If source contains top-level
await, staticimportorexportstatements, orimport.meta, return true.- If source contains a top-level lexical declaration (
const,let, orclass) of any of the CommonJS wrapper variables (require,exports,module,__filename, or__dirname) then return true.- Return false.
Customizing ESM specifier resolution algorithm#
Module customization hooks provide a mechanism for customizing the ESM specifier resolution algorithm. An example that provides CommonJS-style resolution for ESM specifiers is commonjs-extension-resolution-loader.
Modules: Packages#
Introduction#
A package is a folder tree described by a package.json file. The package
consists of the folder containing the package.json file and all subfolders
until the next folder containing another package.json file, or a folder
named node_modules.
This page provides guidance for package authors writing package.json files
along with a reference for the package.json fields defined by Node.js.
Determining module system#
Introduction#
Node.js will treat the following as ES modules when passed to node as the
initial input, or when referenced by import statements or import()
expressions:
-
Files with an
.mjsextension. -
Files with a
.jsextension when the nearest parentpackage.jsonfile contains a top-level"type"field with a value of"module". -
Strings passed in as an argument to
--eval, or piped tonodeviaSTDIN, with the flag--input-type=module. -
Code containing syntax only successfully parsed as ES modules, such as
importorexportstatements orimport.meta, with no explicit marker of how it should be interpreted. Explicit markers are.mjsor.cjsextensions,package.json"type"fields with either"module"or"commonjs"values, or the--input-typeflag. Dynamicimport()expressions are supported in either CommonJS or ES modules and would not force a file to be treated as an ES module. See Syntax detection.
Node.js will treat the following as CommonJS when passed to node as the
initial input, or when referenced by import statements or import()
expressions:
-
Files with a
.cjsextension. -
Files with a
.jsextension when the nearest parentpackage.jsonfile contains a top-level field"type"with a value of"commonjs". -
Strings passed in as an argument to
--evalor--print, or piped tonodeviaSTDIN, with the flag--input-type=commonjs. -
Files with a
.jsextension with no parentpackage.jsonfile or where the nearest parentpackage.jsonfile lacks atypefield, and where the code can evaluate successfully as CommonJS. In other words, Node.js tries to run such "ambiguous" files as CommonJS first, and will retry evaluating them as ES modules if the evaluation as CommonJS fails because the parser found ES module syntax.
Writing ES module syntax in "ambiguous" files incurs a performance cost, and
therefore it is encouraged that authors be explicit wherever possible. In
particular, package authors should always include the "type" field in
their package.json files, even in packages where all sources are CommonJS.
Being explicit about the type of the package will future-proof the package in
case the default type of Node.js ever changes, and it will also make things
easier for build tools and loaders to determine how the files in the package
should be interpreted.
Syntax detection#
Stability: 1.2 - Release candidate
Node.js will inspect the source code of ambiguous input to determine whether it contains ES module syntax; if such syntax is detected, the input will be treated as an ES module.
Ambiguous input is defined as:
- Files with a
.jsextension or no extension; and either no controllingpackage.jsonfile or one that lacks atypefield. - String input (
--evalorSTDIN) when--input-typeis not specified.
ES module syntax is defined as syntax that would throw when evaluated as CommonJS. This includes the following:
importstatements (but notimport()expressions, which are valid in CommonJS).exportstatements.import.metareferences.awaitat the top level of a module.- Lexical redeclarations of the CommonJS wrapper variables (
require,module,exports,__dirname,__filename).
Module resolution and loading#
Node.js has two types of module resolution and loading, chosen based on how the module is requested.
When a module is requested via require() (available by default in CommonJS modules,
and can be dynamically generated using createRequire() in both CommonJS and ES Modules):
- Resolution:
- The resolution initiated by
require()supports folders as modules. - When resolving a specifier, if no exact match is found,
require()will try to add extensions (.js,.json, and finally.node) and then attempt to resolve folders as modules. - It does not support URLs as specifiers by default.
- The resolution initiated by
- Loading:
.jsonfiles are treated as JSON text files..nodefiles are interpreted as compiled addon modules loaded withprocess.dlopen()..ts,.mtsand.ctsfiles are treated as TypeScript text files.- Files with any other extension, or without extensions, are treated as JavaScript text files.
require()can only be used to load ECMAScript modules from CommonJS modules if the ECMAScript module and its dependencies are synchronous (i.e. they do not contain top-levelawait).
When a module is requested via static import statements (only available in ES Modules)
or import() expressions (available in both CommonJS and ES Modules):
- Resolution:
- The resolution of
import/import()does not support folders as modules, directory indexes (e.g.'./startup/index.js') must be fully specified. - It does not perform extension searching. A file extension must be provided when the specifier is a relative or absolute file URL.
- It supports
file://anddata:URLs as specifiers by default.
- The resolution of
- Loading:
.jsonfiles are treated as JSON text files. When importing JSON modules, an import type attribute is required (e.g.import json from './data.json' with { type: 'json' })..nodefiles are interpreted as compiled addon modules loaded withprocess.dlopen(), if--experimental-addon-modulesis enabled..ts,.mtsand.ctsfiles are treated as TypeScript text files.- It accepts only
.js,.mjs, and.cjsextensions for JavaScript text files. .wasmfiles are treated as WebAssembly modules.- Any other file extensions will result in a
ERR_UNKNOWN_FILE_EXTENSIONerror. Additional file extensions can be facilitated via customization hooks. import/import()can be used to load JavaScript CommonJS modules. Such modules are passed through merve to try to identify named exports, which are available if they can be determined through static analysis.
Regardless of how a module is requested, the resolution and loading process can be customized using customization hooks.
package.json and file extensions#
Within a package, the package.json "type" field defines how
Node.js should interpret .js files. If a package.json file does not have a
"type" field, .js files are treated as CommonJS.
A package.json "type" value of "module" tells Node.js to interpret .js
files within that package as using ES module syntax.
The "type" field applies not only to initial entry points (node my-app.js)
but also to files referenced by import statements and import() expressions.
// my-app.js, treated as an ES module because there is a package.json
// file in the same folder with "type": "module".
import './startup/init.js';
// Loaded as ES module since ./startup contains no package.json file,
// and therefore inherits the "type" value from one level up.
import 'commonjs-package';
// Loaded as CommonJS since ./node_modules/commonjs-package/package.json
// lacks a "type" field or contains "type": "commonjs".
import './node_modules/commonjs-package/index.js';
// Loaded as CommonJS since ./node_modules/commonjs-package/package.json
// lacks a "type" field or contains "type": "commonjs".
Files ending with .mjs are always loaded as ES modules regardless of
the nearest parent package.json.
Files ending with .cjs are always loaded as CommonJS regardless of the
nearest parent package.json.
import './legacy-file.cjs';
// Loaded as CommonJS since .cjs is always loaded as CommonJS.
import 'commonjs-package/src/index.mjs';
// Loaded as ES module since .mjs is always loaded as ES module.
The .mjs and .cjs extensions can be used to mix types within the same
package:
-
Within a
"type": "module"package, Node.js can be instructed to interpret a particular file as CommonJS by naming it with a.cjsextension (since both.jsand.mjsfiles are treated as ES modules within a"module"package). -
Within a
"type": "commonjs"package, Node.js can be instructed to interpret a particular file as an ES module by naming it with an.mjsextension (since both.jsand.cjsfiles are treated as CommonJS within a"commonjs"package).
--input-type flag#
Strings passed in as an argument to --eval (or -e), or piped to node via
STDIN, are treated as ES modules when the --input-type=module flag
is set.
node --input-type=module --eval "import { sep } from 'node:path'; console.log(sep);"
echo "import { sep } from 'node:path'; console.log(sep);" | node --input-type=module
For completeness there is also --input-type=commonjs, for explicitly running
string input as CommonJS. This is the default behavior if --input-type is
unspecified.
Package entry points#
In a package's package.json file, two fields can define entry points for a
package: "main" and "exports". Both fields apply to both ES module
and CommonJS module entry points.
The "main" field is supported in all versions of Node.js, but its
capabilities are limited: it only defines the main entry point of the package.
The "exports" provides a modern alternative to "main" allowing
multiple entry points to be defined, conditional entry resolution support
between environments, and preventing any other entry points besides those
defined in "exports". This encapsulation allows module authors to
clearly define the public interface for their package.
For new packages targeting the currently supported versions of Node.js, the
"exports" field is recommended. For packages supporting Node.js 10 and
below, the "main" field is required. If both "exports" and
"main" are defined, the "exports" field takes precedence over
"main" in supported versions of Node.js.
Conditional exports can be used within "exports" to define different
package entry points per environment, including whether the package is
referenced via require or via import. For more information about supporting
both CommonJS and ES modules in a single package please consult
the dual CommonJS/ES module packages section.
Existing packages introducing the "exports" field will prevent consumers
of the package from using any entry points that are not defined, including the
package.json (e.g. require('your-package/package.json')). This will
likely be a breaking change.
To make the introduction of "exports" non-breaking, ensure that every
previously supported entry point is exported. It is best to explicitly specify
entry points so that the package's public API is well-defined. For example,
a project that previously exported main, lib,
feature, and the package.json could use the following package.exports:
{
"name": "my-package",
"exports": {
".": "./lib/index.js",
"./lib": "./lib/index.js",
"./lib/index": "./lib/index.js",
"./lib/index.js": "./lib/index.js",
"./feature": "./feature/index.js",
"./feature/index": "./feature/index.js",
"./feature/index.js": "./feature/index.js",
"./package.json": "./package.json"
}
}
Alternatively a project could choose to export entire folders both with and without extensioned subpaths using export patterns:
{
"name": "my-package",
"exports": {
".": "./lib/index.js",
"./lib": "./lib/index.js",
"./lib/*": "./lib/*.js",
"./lib/*.js": "./lib/*.js",
"./feature": "./feature/index.js",
"./feature/*": "./feature/*.js",
"./feature/*.js": "./feature/*.js",
"./package.json": "./package.json"
}
}
With the above providing backwards-compatibility for any minor package versions, a future major change for the package can then properly restrict the exports to only the specific feature exports exposed:
{
"name": "my-package",
"exports": {
".": "./lib/index.js",
"./feature/*.js": "./feature/*.js",
"./feature/internal/*": null
}
}
Main entry point export#
When writing a new package, it is recommended to use the "exports" field:
{
"exports": "./index.js"
}
When the "exports" field is defined, all subpaths of the package are
encapsulated and no longer available to importers. For example,
require('pkg/subpath.js') throws an ERR_PACKAGE_PATH_NOT_EXPORTED
error.
This encapsulation of exports provides more reliable guarantees
about package interfaces for tools and when handling semver upgrades for a
package. It is not a strong encapsulation since a direct require of any
absolute subpath of the package such as
require('/path/to/node_modules/pkg/subpath.js') will still load subpath.js.
All currently supported versions of Node.js and modern build tools support the
"exports" field. For projects using an older version of Node.js or a related
build tool, compatibility can be achieved by including the "main" field
alongside "exports" pointing to the same module:
{
"main": "./index.js",
"exports": "./index.js"
}
Subpath exports#
When using the "exports" field, custom subpaths can be defined along
with the main entry point by treating the main entry point as the
"." subpath:
{
"exports": {
".": "./index.js",
"./submodule.js": "./src/submodule.js"
}
}
Now only the defined subpath in "exports" can be imported by a consumer:
import submodule from 'es-module-package/submodule.js';
// Loads ./node_modules/es-module-package/src/submodule.js
While other subpaths will error:
import submodule from 'es-module-package/private-module.js';
// Throws ERR_PACKAGE_PATH_NOT_EXPORTED
Extensions in subpaths#
Package authors should provide either extensioned (import 'pkg/subpath.js') or
extensionless (import 'pkg/subpath') subpaths in their exports. This ensures
that there is only one subpath for each exported module so that all dependents
import the same consistent specifier, keeping the package contract clear for
consumers and simplifying package subpath completions.
Traditionally, packages tended to use the extensionless style, which has the benefits of readability and of masking the true path of the file within the package.
With import maps now providing a standard for package resolution in browsers and other JavaScript runtimes, using the extensionless style can result in bloated import map definitions. Explicit file extensions can avoid this issue by enabling the import map to utilize a packages folder mapping to map multiple subpaths where possible instead of a separate map entry per package subpath export. This also mirrors the requirement of using the full specifier path in relative and absolute import specifiers.
Path Rules and Validation for Export Targets#
When defining paths as targets in the "exports" field, Node.js enforces
several rules to ensure security, predictability, and proper encapsulation.
Understanding these rules is crucial for authors publishing packages.
Targets must be relative URLs#
All target paths in the "exports" map (the values associated with export
keys) must be relative URL strings starting with ./.
// package.json
{
"name": "my-package",
"exports": {
".": "./dist/main.js", // Correct
"./feature": "./lib/feature.js", // Correct
// "./origin-relative": "/dist/main.js", // Incorrect: Must start with ./
// "./absolute": "file:///dev/null", // Incorrect: Must start with ./
// "./outside": "../common/util.js" // Incorrect: Must start with ./
}
}
Reasons for this behavior include:
- Security: Prevents exporting arbitrary files from outside the package's own directory.
- Encapsulation: Ensures all exported paths are resolved relative to the package root, making the package self-contained.
No path traversal or invalid segments#
Export targets must not resolve to a location outside the package's root
directory. Additionally, path segments like . (single dot), .. (double dot),
or node_modules (and their URL-encoded equivalents) are generally disallowed
within the target string after the initial ./ and in any subpath part
substituted into a target pattern.
// package.json
{
"name": "my-package",
"exports": {
// ".": "./dist/../../elsewhere/file.js", // Invalid: path traversal
// ".": "././dist/main.js", // Invalid: contains "." segment
// ".": "./dist/../dist/main.js", // Invalid: contains ".." segment
// "./utils/./helper.js": "./utils/helper.js" // Key has invalid segment
}
}
Exports sugar#
If the "." export is the only export, the "exports" field provides sugar
for this case being the direct "exports" field value.
{
"exports": {
".": "./index.js"
}
}
can be written:
{
"exports": "./index.js"
}
Subpath imports#
In addition to the "exports" field, there is a package "imports" field
to create private mappings that only apply to import specifiers from within the
package itself.
Entries in the "imports" field must always start with # to ensure they are
disambiguated from external package specifiers.
For example, the imports field can be used to gain the benefits of conditional exports for internal modules:
// package.json
{
"imports": {
"#dep": {
"node": "dep-node-native",
"default": "./dep-polyfill.js"
}
},
"dependencies": {
"dep-node-native": "^1.0.0"
}
}
where import '#dep' does not get the resolution of the external package
dep-node-native (including its exports in turn), and instead gets the local
file ./dep-polyfill.js relative to the package in other environments.
Unlike the "exports" field, the "imports" field permits mapping to external
packages.
The resolution rules for the imports field are otherwise analogous to the exports field.
Subpath patterns#
For packages with a small number of exports or imports, we recommend
explicitly listing each exports subpath entry. But for packages that have
large numbers of subpaths, this might cause package.json bloat and
maintenance issues.
For these use cases, subpath export patterns can be used instead:
// ./node_modules/es-module-package/package.json
{
"exports": {
"./features/*.js": "./src/features/*.js"
},
"imports": {
"#internal/*.js": "./src/internal/*.js"
}
}
* maps expose nested subpaths as it is a string replacement syntax
only.
All instances of * on the right hand side will then be replaced with this
value, including if it contains any / separators.
import featureX from 'es-module-package/features/x.js';
// Loads ./node_modules/es-module-package/src/features/x.js
import featureY from 'es-module-package/features/y/y.js';
// Loads ./node_modules/es-module-package/src/features/y/y.js
import internalZ from '#internal/z.js';
// Loads ./src/internal/z.js
This is a direct static matching and replacement without any special handling
for file extensions. Including the "*.js" on both sides of the mapping
restricts the exposed package exports to only JS files.
The property of exports being statically enumerable is maintained with exports
patterns since the individual exports for a package can be determined by
treating the right hand side target pattern as a ** glob against the list of
files within the package. Because node_modules paths are forbidden in exports
targets, this expansion is dependent on only the files of the package itself.
To exclude private subfolders from patterns, null targets can be used:
// ./node_modules/es-module-package/package.json
{
"exports": {
"./features/*.js": "./src/features/*.js",
"./features/private-internal/*": null
}
}
import featureInternal from 'es-module-package/features/private-internal/m.js';
// Throws: ERR_PACKAGE_PATH_NOT_EXPORTED
import featureX from 'es-module-package/features/x.js';
// Loads ./node_modules/es-module-package/src/features/x.js
Conditional exports#
Conditional exports provide a way to map to different paths depending on certain conditions. They are supported for both CommonJS and ES module imports.
For example, a package that wants to provide different ES module exports for
require() and import can be written:
// package.json
{
"exports": {
"import": "./index-module.js",
"require": "./index-require.cjs"
},
"type": "module"
}
Node.js implements the following conditions, listed in order from most specific to least specific as conditions should be defined:
"node-addons"- similar to"node"and matches for any Node.js environment. This condition can be used to provide an entry point which uses native C++ addons as opposed to an entry point which is more universal and doesn't rely on native addons. This condition can be disabled via the--no-addonsflag."node"- matches for any Node.js environment. Can be a CommonJS or ES module file. In most cases explicitly calling out the Node.js platform is not necessary."import"- matches when the package is loaded viaimportorimport(), or via any top-level import or resolve operation by the ECMAScript module loader. Applies regardless of the module format of the target file. Always mutually exclusive with"require"."require"- matches when the package is loaded viarequire(). The referenced file should be loadable withrequire()although the condition matches regardless of the module format of the target file. Expected formats include CommonJS, JSON, native addons, and ES modules. Always mutually exclusive with"import"."module-sync"- matches no matter the package is loaded viaimport,import()orrequire(). The format is expected to be ES modules that does not contain top-level await in its module graph - if it does,ERR_REQUIRE_ASYNC_MODULEwill be thrown when the module isrequire()-ed."default"- the generic fallback that always matches. Can be a CommonJS or ES module file. This condition should always come last.
Within the "exports" object, key order is significant. During condition
matching, earlier entries have higher priority and take precedence over later
entries. The general rule is that conditions should be from most specific to
least specific in object order.
Using the "import" and "require" conditions can lead to some hazards,
which are further explained in the dual CommonJS/ES module packages section.
The "node-addons" condition can be used to provide an entry point which
uses native C++ addons. However, this condition can be disabled via the
--no-addons flag. When using "node-addons", it's recommended to treat
"default" as an enhancement that provides a more universal entry point, e.g.
using WebAssembly instead of a native addon.
Conditional exports can also be extended to exports subpaths, for example:
{
"exports": {
".": "./index.js",
"./feature.js": {
"node": "./feature-node.js",
"default": "./feature.js"
}
}
}
Defines a package where require('pkg/feature.js') and
import 'pkg/feature.js' could provide different implementations between
Node.js and other JS environments.
When using environment branches, always include a "default" condition where
possible. Providing a "default" condition ensures that any unknown JS
environments are able to use this universal implementation, which helps avoid
these JS environments from having to pretend to be existing environments in
order to support packages with conditional exports. For this reason, using
"node" and "default" condition branches is usually preferable to using
"node" and "browser" condition branches.
Nested conditions#
In addition to direct mappings, Node.js also supports nested condition objects.
For example, to define a package that only has dual mode entry points for use in Node.js but not the browser:
{
"exports": {
"node": {
"import": "./feature-node.mjs",
"require": "./feature-node.cjs"
},
"default": "./feature.mjs"
}
}
Conditions continue to be matched in order as with flat conditions. If
a nested condition does not have any mapping it will continue checking
the remaining conditions of the parent condition. In this way nested
conditions behave analogously to nested JavaScript if statements.
Resolving user conditions#
When running Node.js, custom user conditions can be added with the
--conditions flag:
node --conditions=development index.js
which would then resolve the "development" condition in package imports and
exports, while resolving the existing "node", "node-addons", "default",
"import", and "require" conditions as appropriate.
Any number of custom conditions can be set with repeat flags.
Typical conditions should only contain alphanumerical characters, using ":", "-", or "=" as separators if necessary. Anything else may run into compatibility issues outside of node.
In node, conditions have very few restrictions, but specifically these include:
- They must contain at least one character.
- They cannot start with "." since they may appear in places that also allow relative paths.
- They cannot contain "," since they may be parsed as a comma-separated list by some CLI tools.
- They cannot be integer property keys like "10" since that can have unexpected effects on property key ordering for JS objects.
Community Conditions Definitions#
Condition strings other than the "import", "require", "node", "module-sync",
"node-addons" and "default" conditions
implemented in Node.js core are ignored by default.
Other platforms may implement other conditions and user conditions can be
enabled in Node.js via the --conditions / -C flag.
Since custom package conditions require clear definitions to ensure correct usage, a list of common known package conditions and their strict definitions is provided below to assist with ecosystem coordination.
"types"- can be used by typing systems to resolve the typing file for the given export. This condition should always be included first."browser"- any web browser environment."development"- can be used to define a development-only environment entry point, for example to provide additional debugging context such as better error messages when running in a development mode. Must always be mutually exclusive with"production"."production"- can be used to define a production environment entry point. Must always be mutually exclusive with"development".
For other runtimes, platform-specific condition key definitions are maintained by the WinterCG in the Runtime Keys proposal specification.
New conditions definitions may be added to this list by creating a pull request to the Node.js documentation for this section. The requirements for listing a new condition definition here are that:
- The definition should be clear and unambiguous for all implementers.
- The use case for why the condition is needed should be clearly justified.
- There should exist sufficient existing implementation usage.
- The condition name should not conflict with another condition definition or condition in wide usage.
- The listing of the condition definition should provide a coordination benefit to the ecosystem that wouldn't otherwise be possible. For example, this would not necessarily be the case for company-specific or application-specific conditions.
- The condition should be such that a Node.js user would expect it to be in
Node.js core documentation. The
"types"condition is a good example: It doesn't really belong in the Runtime Keys proposal but is a good fit here in the Node.js docs.
The above definitions may be moved to a dedicated conditions registry in due course.
Self-referencing a package using its name#
Within a package, the values defined in the package's
package.json "exports" field can be referenced via the package's name.
For example, assuming the package.json is:
// package.json
{
"name": "a-package",
"exports": {
".": "./index.mjs",
"./foo.js": "./foo.js"
}
}
Then any module in that package can reference an export in the package itself:
// ./a-module.mjs
import { something } from 'a-package'; // Imports "something" from ./index.mjs.
Self-referencing is available only if package.json has "exports", and
will allow importing only what that "exports" (in the package.json)
allows. So the code below, given the previous package, will generate a runtime
error:
// ./another-module.mjs
// Imports "another" from ./m.mjs. Fails because
// the "package.json" "exports" field
// does not provide an export named "./m.mjs".
import { another } from 'a-package/m.mjs';
Self-referencing is also available when using require, both in an ES module,
and in a CommonJS one. For example, this code will also work:
// ./a-module.js
const { something } = require('a-package/foo.js'); // Loads from ./foo.js.
Finally, self-referencing also works with scoped packages. For example, this code will also work:
// package.json
{
"name": "@my/package",
"exports": "./index.js"
}
// ./index.js
module.exports = 42;
// ./other.js
console.log(require('@my/package'));
$ node other.js
42
Dual CommonJS/ES module packages#
See the package examples repository for details.
Package maps#
Stability: 1 - Experimental. Enable this API with --experimental-package-map.
Package maps provide a mechanism to control package resolution without relying
on the node_modules folder structure. When enabled via the
--experimental-package-map flag, Node.js uses a JSON configuration file
to determine how bare specifiers are resolved.
This feature is useful for:
- Monorepos: Define explicit dependency relationships between workspace packages without symlinks or hoisting complexities.
- Dependency isolation: Prevent packages from accessing undeclared dependencies (phantom dependencies).
- Low file system coupling: The package resolution algorithm runs without inspecting the file system, relying instead on static data tables.
Configuration file format#
The package map configuration file is a JSON file with a packages object.
Each key in packages is called a package ID and is a unique identifier for a package entry:
{
"packages": {
"app": {
"url": "./packages/app",
"dependencies": {
"@myorg/utils": "utils",
"@myorg/ui-lib": "ui-lib"
}
},
"utils": {
"url": "./packages/utils"
},
"ui-lib": {
"url": "./packages/ui-lib",
"dependencies": {
"@myorg/utils": "utils"
}
}
}
}
Each package entry has the following fields:
url<string>Required. An absolute or relative URL. This is parsed using the WHATWGURLAPI, using the configuration file URL as base. Onlyfile:protocol is supported. Multiple packages are allowed to share the same URL; consumers must key module instances by both module url and package IDs to differentiate them.dependencies<Object>An object mapping bare specifiers to package keys. Each key is the import name used in source code, and each value is the corresponding package key in thepackagesobject. Defaults to an empty object.
Resolution algorithm#
When a bare specifier is encountered:
- Node.js determines which package performs the resolution request.
- If possible the package ID for the importer file should be provided to the resolution algorithm.
- Failing that, the resolution will check if the file path is within any
package location decoded from its
url.
- If no package ID is provided and the importing file is not within any mapped package, an
ERR_PACKAGE_MAP_EXTERNAL_FILEerror is thrown. - Node.js looks up the specifier's package name in the importing package's
dependenciesobject to find the corresponding package key. - If found, the resolution algorithm locates the target package location from the
package's
urlfield in the package map. - If the specifier is not in
dependencies, aMODULE_NOT_FOUNDerror is thrown. - The package location is forwarded to the regular Node.js resolution algorithm to
finish the resolution (
index.js, exports field, etc).
More details can be found in the resolution algorithm pseudo-code.
Multiple package versions#
Different packages can depend on different versions of the same package.
Because dependencies maps bare specifiers to package keys, two packages
can map the same specifier to different targets:
{
"packages": {
"app": {
"url": "./app",
"dependencies": {
"component": "component-v2"
}
},
"legacy": {
"url": "./legacy",
"dependencies": {
"component": "component-v1"
}
},
"component-v1": {
"url": "./vendor/component-1.0.0"
},
"component-v2": {
"url": "./vendor/component-2.0.0"
}
}
}
Both app and legacy can import 'component', but they resolve to
different paths based on their declared dependencies.
Multiple packages for the same URL#
To address complex hoisting situations, multiple packages may share the same URL, which introduces ambiguity when determining which package an import originates from:
{
"packages": {
"app-old": {
"url": "./app-old",
"dependencies": {
"lib": "lib-old"
}
},
"app-new": {
"url": "./app-new",
"dependencies": {
"lib": "lib-new"
}
},
"lib-old": {
"url": "./lib",
"dependencies": {
"react": "react-15"
}
},
"lib-new": {
"url": "./lib",
"dependencies": {
"react": "react-18"
}
}
}
}
In the example above both lib-old and lib-new use the same ./lib folder to
store their sources, the only difference being in which version of react they'll
access when performing require calls or using import.
Because multiple package entries share the same URL, resolving a bare specifier from a file within that URL is ambiguous unless the originating package ID is known. If the package ID cannot be determined (for example, because the caller did not propagate it from a previous resolution), Node.js will throw an error rather than guess.
To support this pattern, implementers must key module instances by package ID
and propagate it from each resolution result to subsequent resolution requests.
This ensures that when lib requires react, the runtime knows whether the
request comes from lib-old or lib-new and can select the correct dependency.
Interaction with other resolution#
Package maps only apply to bare specifiers that are not Node.js builtin modules. The following cases are not affected by package maps and continue to use standard resolution:
- Relative paths or URLs (
./or../). - Absolute paths or URLs.
- Node.js builtin modules (
node:fs, etc.).
Limitations#
- Package maps must be a single static file; dynamic configuration is not supported.
- Circular dependency detection is not performed by the package map resolver.
- The package map file is loaded synchronously at startup.
Node.js package.json field definitions#
This section describes the fields used by the Node.js runtime. Other tools (such as npm) use additional fields which are ignored by Node.js and not documented here.
The following fields in package.json files are used in Node.js:
"name"- Relevant when using named imports within a package. Also used by package managers as the name of the package."main"- The default module when loading the package, if exports is not specified, and in versions of Node.js prior to the introduction of exports."type"- The package type determining whether to load.jsfiles as CommonJS or ES modules."exports"- Package exports and conditional exports. When present, limits which submodules can be loaded from within the package."imports"- Package imports, for use by modules within the package itself.
"name"#
- Type:
<string>
{
"name": "package-name"
}
The "name" field defines your package's name. Publishing to the
npm registry requires a name that satisfies
certain requirements.
The "name" field can be used in addition to the "exports" field to
self-reference a package using its name.
"main"#
- Type:
<string>
{
"main": "./index.js"
}
The "main" field defines the entry point of a package when imported by name
via a node_modules lookup. Its value is a path.
The "exports" field, if it exists, takes precedence over the
"main" field when importing the package by name.
It also defines the script that is used when the package directory is loaded
via require().
// This resolves to ./path/to/directory/index.js.
require('./path/to/directory');
"type"#
- Type:
<string>
The "type" field defines the module format that Node.js uses for all
.js files that have that package.json file as their nearest parent.
Files ending with .js are loaded as ES modules when the nearest parent
package.json file contains a top-level field "type" with a value of
"module".
The nearest parent package.json is defined as the first package.json found
when searching in the current folder, that folder's parent, and so on up
until a node_modules folder or the volume root is reached.
// package.json
{
"type": "module"
}
# In same folder as preceding package.json
node my-app.js # Runs as ES module
If the nearest parent package.json lacks a "type" field, or contains
"type": "commonjs", .js files are treated as CommonJS. If the volume
root is reached and no package.json is found, .js files are treated as
CommonJS.
import statements of .js files are treated as ES modules if the nearest
parent package.json contains "type": "module".
// my-app.js, part of the same example as above
import './startup.js'; // Loaded as ES module because of package.json
Regardless of the value of the "type" field, .mjs files are always treated
as ES modules and .cjs files are always treated as CommonJS.
"exports"#
{
"exports": "./index.js"
}
The "exports" field allows defining the entry points of a package when
imported by name loaded either via a node_modules lookup or a
self-reference to its own name. It is supported in Node.js 12+ as an
alternative to the "main" that can support defining subpath exports
and conditional exports while encapsulating internal unexported modules.
Conditional Exports can also be used within "exports" to define different
package entry points per environment, including whether the package is
referenced via require or via import.
All paths defined in the "exports" must be relative file URLs starting with
./.
"imports"#
- Type:
<Object>
// package.json
{
"imports": {
"#dep": {
"node": "dep-node-native",
"default": "./dep-polyfill.js"
}
},
"dependencies": {
"dep-node-native": "^1.0.0"
}
}
Entries in the imports field must be strings starting with #.
Package imports permit mapping to external packages.
This field defines subpath imports for the current package.
Modules: TypeScript#
Stability: 2 - Stable
Enabling#
There are two ways to enable runtime TypeScript support in Node.js:
-
For full support of all of TypeScript's syntax and features, including using any version of TypeScript, use a third-party package.
-
For lightweight support, you can use the built-in support for type stripping.
Full TypeScript support#
To use TypeScript with full support for all TypeScript features, including
tsconfig.json, you can use a third-party package. These instructions use
tsx as an example but there are many other similar libraries available.
-
Install the package as a development dependency using whatever package manager you're using for your project. For example, with
npm:npm install --save-dev tsx -
Then you can run your TypeScript code via:
npx tsx your-file.tsOr alternatively, you can run with
nodevia:node --import=tsx your-file.ts
Type stripping#
By default Node.js will execute TypeScript files that contains only
erasable TypeScript syntax.
Node.js will replace TypeScript syntax with whitespace,
and no type checking is performed.
To disable this feature, use the flag --no-strip-types.
Node.js ignores tsconfig.json files and therefore
features that depend on settings within tsconfig.json,
such as paths or converting newer JavaScript syntax to older standards, are
intentionally unsupported. To get full TypeScript support, see Full TypeScript support.
The type stripping feature is designed to be lightweight. By intentionally not supporting syntaxes that require JavaScript code generation, and by replacing inline types with whitespace, Node.js can run TypeScript code without the need for source maps.
Type stripping is compatible with most versions of TypeScript
but we recommend version 5.8 or newer with the following tsconfig.json settings:
{
"compilerOptions": {
"noEmit": true, // Optional - see note below
"target": "esnext",
"module": "nodenext",
"rewriteRelativeImportExtensions": true,
"erasableSyntaxOnly": true,
"verbatimModuleSyntax": true
}
}
Use the noEmit option if you intend to only execute *.ts files, for example
a build script. You won't need this flag if you intend to distribute *.js
files.
Determining module system#
Node.js supports both CommonJS and ES Modules syntax in TypeScript
files. Node.js will not convert from one module system to another; if you want
your code to run as an ES module, you must use import and export syntax, and
if you want your code to run as CommonJS you must use require and
module.exports.
.tsfiles will have their module system determined the same way as.jsfiles. To useimportandexportsyntax, add"type": "module"to the nearest parentpackage.json..mtsfiles will always be run as ES modules, similar to.mjsfiles..ctsfiles will always be run as CommonJS modules, similar to.cjsfiles..tsxfiles are unsupported.
As in JavaScript files, file extensions are mandatory in import statements
and import() expressions: import './file.ts', not import './file'. Because
of backward compatibility, file extensions are also mandatory in require()
calls: require('./file.ts'), not require('./file'), similar to how the
.cjs extension is mandatory in require calls in CommonJS files.
The tsconfig.json option allowImportingTsExtensions will allow the
TypeScript compiler tsc to type-check files with import specifiers that
include the .ts extension.
TypeScript features#
Since Node.js is only removing inline types, any TypeScript features that involve replacing TypeScript syntax with new JavaScript syntax will error.
The most prominent features that require transformation are:
Enumdeclarationsnamespacewith runtime code- parameter properties
- import aliases
namespaces that do not contain runtime code are supported.
This example will work correctly:
// This namespace is exporting a type
namespace TypeOnly {
export type A = string;
}
This will result in ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX error:
// This namespace is exporting a value
namespace A {
export let x = 1
}
Since Decorators are currently a TC39 Stage 3 proposal, they are not transformed and will result in a parser error. Node.js does not provide polyfills and thus will not support decorators until they are supported natively in JavaScript.
In addition, Node.js does not read tsconfig.json files and does not support
features that depend on settings within tsconfig.json, such as paths or
converting newer JavaScript syntax into older standards.
Importing types without type keyword#
Due to the nature of type stripping, the type keyword is necessary to
correctly strip type imports. Without the type keyword, Node.js will treat the
import as a value import, which will result in a runtime error. The tsconfig
option verbatimModuleSyntax can be used to match this behavior.
This example will work correctly:
import type { Type1, Type2 } from './module.ts';
import { fn, type FnParams } from './fn.ts';
This will result in a runtime error:
import { Type1, Type2 } from './module.ts';
import { fn, FnParams } from './fn.ts';
Non-file forms of input#
Type stripping can be enabled for --eval and STDIN. The module system
will be determined by --input-type, as it is for JavaScript.
TypeScript syntax is unsupported in the REPL, --check, and
inspect.
Source maps#
Since inline types are replaced by whitespace, source maps are unnecessary for correct line numbers in stack traces; and Node.js does not generate them.
Type stripping in dependencies#
To discourage package authors from publishing packages written in TypeScript,
Node.js refuses to handle TypeScript files inside folders under a node_modules
path.
Paths aliases#
tsconfig "paths" won't be transformed and therefore produce an error. The closest
feature available is subpath imports with the limitation that they need to start
with #.
Net#
Stability: 2 - Stable
The node:net module provides an asynchronous network API for creating stream-based
TCP or IPC servers (net.createServer()) and clients
(net.createConnection()).
It can be accessed using:
import net from 'node:net';const net = require('node:net');
IPC support#
The node:net module supports IPC with named pipes on Windows, and Unix domain
sockets on other operating systems.
Identifying paths for IPC connections#
net.connect(), net.createConnection(), server.listen(), and
socket.connect() take a path parameter to identify IPC endpoints.
On Unix, the local domain is also known as the Unix domain. The path is a
file system pathname. It will throw an error when the length of pathname is
greater than the length of sizeof(sockaddr_un.sun_path). Typical values are
107 bytes on Linux and 103 bytes on macOS. If a Node.js API abstraction creates
the Unix domain socket, it will unlink the Unix domain socket as well. For
example, net.createServer() may create a Unix domain socket and
server.close() will unlink it. But if a user creates the Unix domain
socket outside of these abstractions, the user will need to remove it. The same
applies when a Node.js API creates a Unix domain socket but the program then
crashes. In short, a Unix domain socket will be visible in the file system and
will persist until unlinked. On Linux, You can use Unix abstract socket by adding
\0 to the beginning of the path, such as \0abstract. The path to the Unix
abstract socket is not visible in the file system and it will disappear automatically
when all open references to the socket are closed.
On Windows, the local domain is implemented using a named pipe. The path must
refer to an entry in \\?\pipe\ or \\.\pipe\. Any characters are permitted,
but the latter may do some processing of pipe names, such as resolving ..
sequences. Despite how it might look, the pipe namespace is flat. Pipes will
not persist. They are removed when the last reference to them is closed.
Unlike Unix domain sockets, Windows will close and remove the pipe when the
owning process exits.
JavaScript string escaping requires paths to be specified with extra backslash escaping such as:
net.createServer().listen(
path.join('\\\\?\\pipe', process.cwd(), 'myctl'));
Class: net.BlockList#
The BlockList object can be used with some network APIs to specify rules for
disabling inbound or outbound access to specific IP addresses, IP ranges, or
IP subnets.
blockList.addAddress(address[, type])#
address<string>|<net.SocketAddress>An IPv4 or IPv6 address.type<string>Either'ipv4'or'ipv6'. Default:'ipv4'.
Adds a rule to block the given IP address.
blockList.addAddresses(addresses[, type])#
addresses<string>[] |<net.SocketAddress>[] An array of IPv4 or IPv6 addresses.type<string>Either'ipv4'or'ipv6'. Default:'ipv4'.
Adds multiple address rules to the block list in a single operation.
This is more efficient than calling blockList.addAddress() repeatedly
when adding a large number of individual addresses, as the addresses
are inserted under a single internal lock acquisition.
blockList.addCIDR(cidr)#
cidr<string>An IPv4 or IPv6 subnet in CIDR notation (e.g.'10.0.0.0/8'or'2001:db8::/32').
Adds a subnet rule using CIDR notation. The address family is automatically
detected from the address (IPv6 if the address contains ':', IPv4
otherwise). This is equivalent to calling blockList.addSubnet() with
the parsed network address, prefix length, and family.
blockList.addCIDRs(cidrs)#
cidrs<string>[] An array of IPv4 or IPv6 subnets in CIDR notation.
Adds multiple subnet rules using CIDR notation in a single call. The address
family for each entry is automatically detected. This is equivalent to
calling blockList.addCIDR() for each element of the array.
blockList.addRange(start, end[, type])#
start<string>|<net.SocketAddress>The starting IPv4 or IPv6 address in the range.end<string>|<net.SocketAddress>The ending IPv4 or IPv6 address in the range.type<string>Either'ipv4'or'ipv6'. Default:'ipv4'.
Adds a rule to block a range of IP addresses from start (inclusive) to
end (inclusive).
blockList.addSubnet(net, prefix[, type])#
net<string>|<net.SocketAddress>The network IPv4 or IPv6 address.prefix<number>The number of CIDR prefix bits. For IPv4, this must be a value between0and32. For IPv6, this must be between0and128.type<string>Either'ipv4'or'ipv6'. Default:'ipv4'.
Adds a rule to block a range of IP addresses specified as a subnet mask.
blockList.check(address[, type])#
address<string>|<net.SocketAddress>The IP address to checktype<string>Either'ipv4'or'ipv6'. Default:'ipv4'.- Returns:
<boolean>
Returns true if the given IP address matches any of the rules added to the
BlockList.
const blockList = new net.BlockList();
blockList.addAddress('123.123.123.123');
blockList.addRange('10.0.0.1', '10.0.0.10');
blockList.addSubnet('8592:757c:efae:4e45::', 64, 'ipv6');
console.log(blockList.check('123.123.123.123')); // Prints: true
console.log(blockList.check('10.0.0.3')); // Prints: true
console.log(blockList.check('222.111.111.222')); // Prints: false
// IPv6 notation for IPv4 addresses works:
console.log(blockList.check('::ffff:7b7b:7b7b', 'ipv6')); // Prints: true
console.log(blockList.check('::ffff:123.123.123.123', 'ipv6')); // Prints: true
blockList.clear()#
Clears all rules from the BlockList.
blockList.fromJSON(value)#
Stability: 1.2 - Release candidate
const blockList = new net.BlockList();
const data = [
'Subnet: IPv4 192.168.1.0/24',
'Address: IPv4 10.0.0.5',
'Range: IPv4 192.168.2.1-192.168.2.10',
'Range: IPv4 10.0.0.1-10.0.0.10',
];
blockList.fromJSON(data);
blockList.fromJSON(JSON.stringify(data));
valueBlocklist.rules
BlockList.isBlockList(value)#
BlockList.PRIVATE_RANGES#
- Type:
<string>[]
A frozen array of CIDR strings representing private, loopback, and link-local
IP address ranges. This can be passed to blockList.addCIDRs() to quickly
populate a blocklist with all non-routable address ranges.
The included ranges are:
10.0.0.0/8— RFC 1918 private IPv4172.16.0.0/12— RFC 1918 private IPv4192.168.0.0/16— RFC 1918 private IPv4127.0.0.0/8— IPv4 loopback::1/128— IPv6 loopback169.254.0.0/16— IPv4 link-localfe80::/10— IPv6 link-localfc00::/7— IPv6 unique local (ULA)
const blockList = new net.BlockList();
blockList.addCIDRs(net.BlockList.PRIVATE_RANGES);
console.log(blockList.check('10.0.0.1')); // Prints: true
console.log(blockList.check('127.0.0.1')); // Prints: true
console.log(blockList.check('8.8.8.8')); // Prints: false
blockList.removeAddress(address[, type])#
address<string>|<net.SocketAddress>An IPv4 or IPv6 address.type<string>Either'ipv4'or'ipv6'. Default:'ipv4'.
Removes a rule that was previously added with blockList.addAddress(). The
address must match exactly the value used when the rule was added. If the
specified address does not exist, this is a no-op.
blockList.removeCIDR(cidr)#
cidr<string>An IPv4 or IPv6 subnet in CIDR notation (e.g.'10.0.0.0/8'or'2001:db8::/32').
Removes a subnet rule using CIDR notation. The address family is automatically
detected from the address. This is equivalent to calling
blockList.removeSubnet() with the parsed network address, prefix length,
and family. If the specified subnet does not exist, this is a no-op.
blockList.removeRange(start, end[, type])#
start<string>|<net.SocketAddress>The starting IPv4 or IPv6 address in the range.end<string>|<net.SocketAddress>The ending IPv4 or IPv6 address in the range.type<string>Either'ipv4'or'ipv6'. Default:'ipv4'.
Removes a rule that was previously added with blockList.addRange(). The start
and end addresses must match exactly the values used when the rule was added.
If the specified range does not exist, this is a no-op.
blockList.removeSubnet(net, prefix[, type])#
net<string>|<net.SocketAddress>The network IPv4 or IPv6 address.prefix<number>The number of CIDR prefix bits. For IPv4, this must be a value between0and32. For IPv6, this must be between0and128.type<string>Either'ipv4'or'ipv6'. Default:'ipv4'.
Removes a rule that was previously added with blockList.addSubnet(). The
network address and prefix must match exactly the values used when the rule was
added. If the specified subnet does not exist, this is a no-op.
blockList.rules#
- Type:
<string>[]
The list of rules added to the blocklist.
blockList.size#
- Type:
<number>
The number of rules in the blocklist. This is equivalent to
blockList.rules.length but does not allocate the rules array.
blockList.toJSON()#
Stability: 1.2 - Release candidate
- Returns Blocklist.rules
Class: net.SocketAddress#
new net.SocketAddress([options])#
options<Object>
socketaddress.address#
- Type:
<string>
socketaddress.family#
- Type:
<string>Either'ipv4'or'ipv6'.
socketaddress.flowlabel#
- Type:
<number>
socketaddress.port#
- Type:
<number>
SocketAddress.parse(input)#
input<string>An input string containing an IP address and optional port, e.g.123.1.2.3:1234or[1::1]:1234.- Returns:
<net.SocketAddress>Returns aSocketAddressif parsing was successful. Otherwise returnsundefined.
Class: net.Server#
- Extends:
<EventEmitter>
This class is used to create a TCP or IPC server.
A listening TCP net.Server can be transferred to a worker thread by listing it
in the transferList of a worker_threads postMessage() call. This moves
the underlying listening socket to the receiving thread, where it resumes
accepting connections. See Transferring TCP handles to other threads.
new net.Server([options][, connectionListener])#
options<Object>Seenet.createServer([options][, connectionListener]).connectionListener<Function>Automatically set as a listener for the'connection'event.- Returns:
<net.Server>
net.Server is an EventEmitter with the following events:
Event: 'close'#
Emitted when the server closes. If connections exist, this event is not emitted until all connections are ended.
Event: 'connection'#
- Type:
<net.Socket>The connection object
Emitted when a new connection is made. socket is an instance of
net.Socket.
Event: 'error'#
- Type:
<Error>
Emitted when an error occurs. Unlike net.Socket, the 'close'
event will not be emitted directly following this event unless
server.close() is manually called. See the example in discussion of
server.listen().
Event: 'listening'#
Emitted when the server has been bound after calling server.listen().
Event: 'drop'#
When the number of connections reaches the threshold of server.maxConnections,
the server will drop new connections and emit 'drop' event instead. If it is a
TCP server, the argument is as follows, otherwise the argument is undefined.
server.address()#
Returns the bound address, the address family name, and port of the server
as reported by the operating system if listening on an IP socket
(useful to find which port was assigned when getting an OS-assigned address):
{ port: 12346, family: 'IPv4', address: '127.0.0.1' }.
For a server listening on a pipe or Unix domain socket, the name is returned as a string.
const server = net.createServer((socket) => {
socket.end('goodbye\n');
}).on('error', (err) => {
// Handle errors here.
throw err;
});
// Grab an arbitrary unused port.
server.listen(() => {
console.log('opened server on', server.address());
});
server.address() returns null before the 'listening' event has been
emitted or after calling server.close().
server.close([callback])#
callback<Function>Called when the server is closed.- Returns:
<net.Server>
Stops the server from accepting new connections and keeps existing
connections. This function is asynchronous, the server is finally closed
when all connections are ended and the server emits a 'close' event.
The optional callback will be called once the 'close' event occurs. Unlike
that event, it will be called with an Error as its only argument if the server
was not open when it was closed.
server[Symbol.asyncDispose]()#
Calls server.close() and returns a promise that fulfills when the
server has closed.
server.getConnections(callback)#
callback<Function>- Returns:
<net.Server>
Asynchronously get the number of concurrent connections on the server. Works when sockets were sent to forks.
Callback should take two arguments err and count.
server.listen()#
Start a server listening for connections. A net.Server can be a TCP or
an IPC server depending on what it listens to.
Possible signatures:
server.listen(handle[, backlog][, callback])server.listen(options[, callback])server.listen(path[, backlog][, callback])for IPC serversserver.listen([port[, host[, backlog]]][, callback])for TCP servers
This function is asynchronous. When the server starts listening, the
'listening' event will be emitted. The last parameter callback
will be added as a listener for the 'listening' event.
All listen() methods can take a backlog parameter to specify the maximum
length of the queue of pending connections. The actual length will be determined
by the OS through sysctl settings such as tcp_max_syn_backlog and somaxconn
on Linux. The default value of this parameter is 511 (not 512).
All net.Socket are set to SO_REUSEADDR (see socket(7) for
details).
The server.listen() method can be called again if and only if there was an
error during the first server.listen() call or server.close() has been
called. Otherwise, an ERR_SERVER_ALREADY_LISTEN error will be thrown.
One of the most common errors raised when listening is EADDRINUSE.
This happens when another server is already listening on the requested
port/path/handle. One way to handle this would be to retry
after a certain amount of time:
server.on('error', (e) => {
if (e.code === 'EADDRINUSE') {
console.error('Address in use, retrying...');
setTimeout(() => {
server.close();
server.listen(PORT, HOST);
},