- Assertion testing
- Asynchronous context tracking
- Async hooks
- Buffer
- C++ addons
- C/C++ addons with Node-API
- C++ embedder API
- Child processes
- Cluster
- Command-line options
- Console
- Corepack
- Crypto
- Debugger
- Deprecated APIs
- Diagnostics Channel
- DNS
- Domain
- Errors
- Events
- File system
- Globals
- HTTP
- HTTP/2
- HTTPS
- Inspector
- Internationalization
- Modules: CommonJS modules
- Modules: ECMAScript modules
- Modules:
node:moduleAPI - Modules: Packages
- Net
- OS
- Path
- Performance hooks
- Permissions
- Process
- Punycode
- Query strings
- Readline
- REPL
- Report
- Stream
- String decoder
- Test runner
- Timers
- TLS/SSL
- Trace events
- TTY
- UDP/datagram
- URL
- Utilities
- V8
- VM
- WASI
- Web Crypto API
- Web Streams API
- Worker threads
- Zlib
Node.js v16.20.2 documentation
- Node.js v16.20.2
- ► Other versions
- ► Options
Table of contents
- About this documentation
- Usage and example
- Assert
- Strict assertion mode
- Legacy assertion mode
- Class: assert.AssertionError
- Class:
assert.CallTracker 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.fail(actual, expected[, message[, operator[, stackStartFn]]])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])
- Asynchronous context tracking
- Introduction
- Class:
AsyncLocalStorage - 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
- Async hooks
- Terminology
- Overview
async_hooks.createHook(callbacks)- Class:
AsyncHook - Promise execution tracking
- JavaScript embedder API
- Class:
AsyncLocalStorage
- 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) - Static method:
Buffer.allocUnsafeSlow(size) - Static method:
Buffer.byteLength(string[, encoding]) - Static method:
Buffer.compare(buf1, buf2) - Static method:
Buffer.concat(list[, totalLength]) - 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) - Class property:
Buffer.poolSize buf[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[, byteOffset][, encoding])buf.indexOf(value[, byteOffset][, encoding])buf.keys()buf.lastIndexOf(value[, byteOffset][, 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:
node:buffermodule APIsBuffer.from(),Buffer.alloc(), andBuffer.allocUnsafe()
- C++ addons
- Node-API
- 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_arraybuffernapi_create_external_buffernapi_create_objectnapi_create_symbolnode_api_symbol_fornapi_create_typedarraynapi_create_dataview
- Functions to convert from C types to Node-API
- 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
- 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_seal
- 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
- C++ embedder API
- 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.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
- Command-line API
- Synopsis
- Program entry point
- Options
-----abort-on-uncaught-exception--completion-bash-C=condition,--conditions=condition--cpu-prof--cpu-prof-dir--cpu-prof-interval--cpu-prof-name--diagnostic-dir=directory--disable-proto=mode--disallow-code-generation-from-strings--dns-result-order=order--enable-fips--enable-source-maps--experimental-fetch--experimental-global-customevent--experimental-global-webcrypto--experimental-import-meta-resolve--experimental-loader=module--experimental-network-imports--experimental-policy--no-experimental-repl-await--experimental-specifier-resolution=mode--experimental-vm-modules--experimental-wasi-unstable-preview1--experimental-wasm-modules--force-context-aware--force-fips--frozen-intrinsics--force-node-api-uncaught-exceptions-policy--heapsnapshot-near-heap-limit=max_count--heapsnapshot-signal=signal--heap-prof--heap-prof-dir--heap-prof-interval--heap-prof-name--icu-data-dir=file--input-type=type--inspect-brk[=[host:]port]--inspect-port=[host:]port--inspect[=[host:]port]--inspect-publish-uid=stderr,http--insecure-http-parser--jitless--max-http-header-size=size--napi-modules--no-addons--no-deprecation--no-force-async-hooks-checks--no-global-search-paths--no-warnings--node-memory-debug--openssl-config=file--openssl-shared-config--openssl-legacy-provider--pending-deprecation--policy-integrity=sri--preserve-symlinks--preserve-symlinks-main--prof--prof-process--redirect-warnings=file--report-compact--report-dir=directory,report-directory=directory--report-filename=filename--report-on-fatalerror--report-on-signal--report-signal=signal--report-uncaught-exception--secure-heap=n--secure-heap-min=n--test--test-only--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-atomics-wait--trace-deprecation--trace-event-categories--trace-event-file-pattern--trace-events-enabled--trace-exit--trace-sigint--trace-sync-io--trace-tls--trace-uncaught--trace-warnings--track-heap-objects--unhandled-rejections=mode--use-bundled-ca,--use-openssl-ca--use-largepages=mode--v8-options--v8-pool-size=num--watch--watch-path--zero-fill-buffers-c,--check-e,--eval "script"-h,--help-i,--interactive-p,--print "script"-r,--require module-v,--version
- Environment variables
FORCE_COLOR=[1, 2, 3]NODE_DEBUG=module[,…]NODE_DEBUG_NATIVE=module[,…]NODE_DISABLE_COLORS=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_HISTORY=fileNODE_REPL_EXTERNAL_MODULE=fileNODE_SKIP_PLATFORM_CHECK=valueNODE_TLS_REJECT_UNAUTHORIZED=valueNODE_V8_COVERAGE=dirNO_COLOR=<any>OPENSSL_CONF=fileSSL_CERT_DIR=dirSSL_CERT_FILE=fileTZUV_THREADPOOL_SIZE=size
- Useful V8 options
- 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:
- Corepack
- Crypto
- Determining if crypto support is unavailable
- Class:
Certificate - Class:
Cipher - Class:
Decipher - 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:
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.validTox509.verify(publicKey)
node:cryptomodule methods and propertiescrypto.constantscrypto.DEFAULT_ENCODINGcrypto.fipscrypto.checkPrime(candidate[, options], callback)crypto.checkPrimeSync(candidate[, options])crypto.createCipher(algorithm, password[, options])crypto.createCipheriv(algorithm, key, iv[, options])crypto.createDecipher(algorithm, password[, 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.createPrivateKey(key)crypto.createPublicKey(key)crypto.createSecretKey(key[, encoding])crypto.createSign(algorithm[, options])crypto.createVerify(algorithm[, options])crypto.diffieHellman(options)crypto.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.hkdf(digest, ikm, salt, info, keylen, callback)crypto.hkdfSync(digest, ikm, salt, info, keylen)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.randomFillSync(buffer[, offset][, size])crypto.randomFill(buffer[, offset][, size], callback)crypto.randomInt([min, ]max[, callback])crypto.randomUUID([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.timingSafeEqual(a, b)crypto.verify(algorithm, data, key, signature[, callback])crypto.webcrypto
- Notes
- Crypto constants
- Debugger
- 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) - 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 - DEP0167: Weak
DiffieHellmanGroupinstances (modp1,modp2,modp5) - DEP0168: Unhandled exception in Node-API callbacks
- DEP0001:
- Diagnostics Channel
- 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.resolveTxt(hostname, callback)dns.reverse(ip, callback)dns.setDefaultResultOrder(order)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.resolveTxt(hostname)dnsPromises.reverse(ip)dnsPromises.setDefaultResultOrder(order)dnsPromises.setServers(servers)
- Class:
- Error codes
- Implementation considerations
- Class:
- Domain
- Errors
- Error propagation and interception
- Class:
Error - Class:
AssertionError - 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_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_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_KEY_OBJECT_TYPEERR_CRYPTO_INVALID_KEYLENERR_CRYPTO_INVALID_KEYPAIRERR_CRYPTO_INVALID_KEYTYPEERR_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_OPERATION_FAILEDERR_CRYPTO_PBKDF2_ERRORERR_CRYPTO_SCRYPT_INVALID_PARAMETERERR_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_DLOPEN_DISABLEDERR_DLOPEN_FAILEDERR_DIR_CLOSEDERR_DIR_CONCURRENT_OPERATIONERR_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_FS_CP_DIR_TO_NON_DIRERR_FS_CP_EEXISTERR_FS_CP_EINVALERR_HTTP_CONTENT_LENGTH_MISMATCHERR_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_INVALID_SYMLINK_TYPEERR_HTTP_HEADERS_SENTERR_HTTP_INVALID_HEADER_VALUEERR_HTTP_INVALID_STATUS_CODEERR_HTTP_REQUEST_TIMEOUTERR_HTTP_SOCKET_ENCODINGERR_HTTP_TRAILER_INVALIDERR_HTTP2_ALTSVC_INVALID_ORIGINERR_HTTP2_ALTSVC_LENGTHERR_HTTP2_CONNECT_AUTHORITYERR_HTTP2_CONNECT_PATHERR_HTTP2_CONNECT_SCHEMEERR_HTTP2_ERRORERR_HTTP2_GOAWAY_SESSIONERR_HTTP2_HEADER_SINGLE_VALUEERR_HTTP2_HEADERS_AFTER_RESPONDERR_HTTP2_HEADERS_SENTERR_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_INVALID_FRAMESERR_HTTP2_TRAILERS_ALREADY_SENTERR_HTTP2_TRAILERS_NOT_READYERR_HTTP2_UNSUPPORTED_PROTOCOLERR_ILLEGAL_CONSTRUCTORERR_IMPORT_ASSERTION_TYPE_FAILEDERR_IMPORT_ASSERTION_TYPE_MISSINGERR_IMPORT_ASSERTION_TYPE_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_ADDRESS_FAMILYERR_INVALID_ARG_TYPEERR_INVALID_ARG_VALUEERR_INVALID_ASYNC_IDERR_INVALID_BUFFER_SIZEERR_INVALID_CALLBACKERR_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_MODULEERR_INVALID_MODULE_SPECIFIERERR_INVALID_PACKAGE_CONFIGERR_INVALID_PACKAGE_TARGETERR_INVALID_PERFORMANCE_MARKERR_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_TRANSFER_OBJECTERR_INVALID_TUPLEERR_INVALID_URIERR_INVALID_URLERR_INVALID_URL_SCHEMEERR_IPC_CHANNEL_CLOSEDERR_IPC_DISCONNECTEDERR_IPC_ONE_PIPEERR_IPC_SYNC_FORKERR_LOADER_CHAIN_INCOMPLETEERR_MANIFEST_ASSERT_INTEGRITYERR_MANIFEST_DEPENDENCY_MISSINGERR_MANIFEST_INTEGRITY_MISMATCHERR_MANIFEST_INVALID_RESOURCE_FIELDERR_MANIFEST_INVALID_SPECIFIERERR_MANIFEST_PARSE_POLICYERR_MANIFEST_TDZERR_MANIFEST_UNKNOWN_ONERRORERR_MEMORY_ALLOCATION_FAILEDERR_MESSAGE_TARGET_CONTEXT_UNAVAILABLEERR_METHOD_NOT_IMPLEMENTEDERR_MISSING_ARGSERR_MISSING_OPTIONERR_MISSING_PASSPHRASEERR_MISSING_PLATFORM_FOR_WORKERERR_MISSING_TRANSFERABLE_IN_TRANSFER_LISTERR_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_NAPI_TSFN_START_IDLE_LOOPERR_NAPI_TSFN_STOP_IDLE_LOOPERR_NOT_BUILDING_SNAPSHOTERR_NO_CRYPTOERR_NO_ICUERR_NON_CONTEXT_AWARE_DISABLEDERR_OUT_OF_RANGEERR_PACKAGE_IMPORT_NOT_DEFINEDERR_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_REQUIRE_ESMERR_SCRIPT_EXECUTION_INTERRUPTEDERR_SCRIPT_EXECUTION_TIMEOUTERR_SERVER_ALREADY_LISTENERR_SERVER_NOT_RUNNINGERR_SOCKET_ALREADY_BOUNDERR_SOCKET_BAD_BUFFER_SIZEERR_SOCKET_BAD_PORTERR_SOCKET_BAD_TYPEERR_SOCKET_BUFFER_SIZEERR_SOCKET_CLOSEDERR_SOCKET_DGRAM_IS_CONNECTEDERR_SOCKET_DGRAM_NOT_CONNECTEDERR_SOCKET_DGRAM_NOT_RUNNINGERR_SRI_PARSEERR_STREAM_ALREADY_FINISHEDERR_STREAM_CANNOT_PIPEERR_STREAM_DESTROYEDERR_STREAM_NULL_VALUESERR_STREAM_PREMATURE_CLOSEERR_STREAM_PUSH_AFTER_EOFERR_STREAM_UNSHIFT_AFTER_END_EVENTERR_STREAM_WRAPERR_STREAM_WRITE_AFTER_ENDERR_STRING_TOO_LONGERR_SYNTHETICERR_SYSTEM_ERRORERR_TEST_FAILUREERR_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_IDENTIY_HINT_FAILEDERR_TLS_RENEGOTIATION_DISABLEDERR_TLS_REQUIRED_SERVER_NAMEERR_TLS_SESSION_ATTACKERR_TLS_SNI_FROM_SERVERERR_TRACE_EVENTS_CATEGORY_REQUIREDERR_TRACE_EVENTS_UNAVAILABLEERR_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_VALID_PERFORMANCE_ENTRY_TYPEERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSINGERR_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_WORKER_INIT_FAILEDERR_WORKER_INVALID_EXEC_ARGVERR_WORKER_NOT_RUNNINGERR_WORKER_OUT_OF_MEMORYERR_WORKER_PATHERR_WORKER_UNSERIALIZABLE_ERRORERR_WORKER_UNSUPPORTED_OPERATIONERR_ZLIB_INITIALIZATION_FAILEDHPE_HEADER_OVERFLOWHPE_UNEXPECTED_CONTENT_LENGTHMODULE_NOT_FOUND
- Legacy Node.js error codes
ERR_CANNOT_TRANSFER_OBJECTERR_CRYPTO_HASH_DIGEST_NO_UTF16ERR_HTTP2_FRAME_ERRORERR_HTTP2_HEADERS_OBJECTERR_HTTP2_HEADER_REQUIREDERR_HTTP2_INFO_HEADERS_AFTER_RESPONDERR_HTTP2_STREAM_CLOSEDERR_HTTP_INVALID_CHARERR_INDEX_OUT_OF_RANGEERR_INVALID_OPT_VALUEERR_INVALID_OPT_VALUE_ENCODINGERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LISTERR_NAPI_CONS_PROTOTYPE_OBJECTERR_NETWORK_IMPORT_BAD_RESPONSEERR_NETWORK_IMPORT_DISALLOWEDERR_NO_LONGER_SUPPORTEDERR_OPERATION_FAILEDERR_OUTOFMEMORYERR_PARSE_HISTORY_DATAERR_SOCKET_CANNOT_SENDERR_STDERR_CLOSEERR_STDOUT_CLOSEERR_STREAM_READ_NOT_IMPLEMENTEDERR_TLS_RENEGOTIATION_FAILEDERR_TRANSFERRING_EXTERNALIZED_SHAREDARRAYBUFFERERR_UNKNOWN_STDIN_TYPEERR_UNKNOWN_STREAM_TYPEERR_V8BREAKITERATORERR_VALUE_OUT_OF_RANGEERR_VM_MODULE_NOT_LINKEDERR_VM_MODULE_LINKING_ERROREDERR_WORKER_UNSUPPORTED_EXTENSIONERR_ZLIB_BINDING_CLOSEDERR_CPU_USAGE
- 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)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.once(emitter, name[, options])events.captureRejectionsevents.captureRejectionSymbolevents.listenerCount(emitter, eventName)events.on(emitter, eventName[, options])events.setMaxListeners(n[, ...eventTargets])- Class:
events.EventEmitterAsyncResource extends EventEmitter EventTargetandEventAPI- Node.js
EventTargetvs. DOMEventTarget NodeEventTargetvs.EventEmitter- Event listener
EventTargeterror handling- Class:
Eventevent.bubblesevent.cancelBubble()event.cancelableevent.composedevent.composedPath()event.currentTargetevent.defaultPreventedevent.eventPhaseevent.isTrustedevent.preventDefault()event.returnValueevent.srcElementevent.stopImmediatePropagation()event.stopPropagation()event.targetevent.timeStampevent.type
- Class:
EventTarget - Class:
CustomEvent - Class:
NodeEventTargetnodeEventTarget.addListener(type, listener[, options])nodeEventTarget.eventNames()nodeEventTarget.listenerCount(type)nodeEventTarget.off(type, listener)nodeEventTarget.on(type, listener[, options])nodeEventTarget.once(type, listener[, options])nodeEventTarget.removeAllListeners([type])nodeEventTarget.removeListener(type, listener)
- Node.js
- Passing arguments and
- 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.read(buffer, offset, length, position)filehandle.read([options])filehandle.read(buffer[, options])filehandle.readFile(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])
- 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.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.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.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.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.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.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.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.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.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.WriteStream fs.constants
- Class:
- Notes
- Global objects
- Class:
AbortController - Class:
Buffer __dirname__filenameatob(data)btoa(data)clearImmediate(immediateObject)clearInterval(intervalObject)clearTimeout(timeoutObject)consoleCryptocryptoCryptoKeyCustomEventEventEventTargetexportsfetch- Class
FormData global- Class
Headers MessageChannelMessageEventMessagePortmoduleperformanceprocessqueueMicrotask(callback)require()ResponseRequestsetImmediate(callback[, ...args])setInterval(callback, delay[, ...args])setTimeout(callback, delay[, ...args])SubtleCryptoTextDecoderTextEncoderURLURLSearchParamsWebAssembly
- Class:
- HTTP
- Class:
http.Agent - 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.headersTimeoutserver.listen()server.listeningserver.maxHeadersCountserver.requestTimeoutserver.setTimeout([msecs][, callback])server.maxRequestsPerSocketserver.timeoutserver.keepAliveTimeout
- 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.uncork()response.writableEndedresponse.writableFinishedresponse.write(chunk[, encoding][, callback])response.writeContinue()response.writeHead(statusCode[, statusMessage][, headers])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.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.setTimeout(msesc[, 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.validateHeaderName(name)http.validateHeaderValue(name, value)http.setMaxIdleHTTPParsers
- 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.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.connectionresponse.createPushResponse(headers, callback)response.end([data[, encoding]][, callback])response.finishedresponse.getHeader(name)response.getHeaderNames()response.getHeaders()response.hasHeader(name)response.headersSentresponse.removeHeader(name)
- Event:
response.reqresponse.sendDateresponse.setHeader(name, value)response.setTimeout(msecs[, callback])response.socketresponse.statusCoderesponse.statusMessageresponse.streamresponse.writableEndedresponse.write(chunk[, encoding][, callback])response.writeContinue()response.writeHead(statusCode[, statusMessage][, headers])
- Collecting HTTP/2 performance metrics
- Note on
:authorityandhost
- HTTPS
- Inspector
- Internationalization support
- Modules: CommonJS modules
- Enabling
- Accessing the main module
- Package manager tips
- The
.mjsextension - All together
- Caching
- Core 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:
node:moduleAPI - Modules: Packages
- Net
- IPC support
- Class:
net.BlockList - Class:
net.SocketAddress - Class:
net.Server - Class:
net.Socketnew net.Socket([options])- Event:
'close' - Event:
'connect' - Event:
'data' - Event:
'drain' - Event:
'end' - Event:
'error' - Event:
'lookup' - Event:
'ready' - Event:
'timeout' socket.address()socket.bufferSizesocket.bytesReadsocket.bytesWrittensocket.connect()socket.connectingsocket.destroy([error])socket.destroyedsocket.end([data[, encoding]][, callback])socket.localAddresssocket.localPortsocket.localFamilysocket.pause()socket.pendingsocket.ref()socket.remoteAddresssocket.remoteFamilysocket.remotePortsocket.resetAndDestroy()socket.resume()socket.setEncoding([encoding])socket.setKeepAlive([enable][, initialDelay])socket.setNoDelay([noDelay])socket.setTimeout(timeout[, callback])socket.timeoutsocket.unref()socket.write(data[, encoding][, callback])socket.readyState
net.connect()net.createConnection()net.createServer([options][, connectionListener])net.isIP(input)net.isIPv4(input)net.isIPv6(input)
- OS
os.EOLos.arch()os.constantsos.cpus()os.devNullos.endianness()os.freemem()os.getPriority([pid])os.homedir()os.hostname()os.loadavg()os.networkInterfaces()os.platform()os.release()os.setPriority([pid, ]priority)os.tmpdir()os.totalmem()os.type()os.uptime()os.userInfo([options])os.version()os.machine()- OS constants
- Path
- Windows vs. POSIX
path.basename(path[, suffix])path.delimiterpath.dirname(path)path.extname(path)path.format(pathObject)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)performance.measure(name[, startMarkOrOptions[, endMark]])performance.nodeTimingperformance.now()performance.timeOriginperformance.timerify(fn[, options])performance.toJSON()
- Class:
PerformanceEntryperformanceEntry.detailperformanceEntry.durationperformanceEntry.entryTypeperformanceEntry.flagsperformanceEntry.nameperformanceEntry.kindperformanceEntry.startTime- Garbage Collection ('gc') Details
- HTTP ('http') Details
- HTTP/2 ('http2') Details
- Timerify ('function') Details
- Net ('net') Details
- DNS ('dns') Details
- Class:
PerformanceNodeTiming - Class:
PerformanceResourceTimingperformanceResourceTiming.workerStartperformanceResourceTiming.redirectStartperformanceResourceTiming.redirectEndperformanceResourceTiming.fetchStartperformanceResourceTiming.domainLookupStartperformanceResourceTiming.domainLookupEndperformanceResourceTiming.connectStartperformanceResourceTiming.connectEndperformanceResourceTiming.secureConnectionStartperformanceResourceTiming.requestStartperformanceResourceTiming.responseEndperformanceResourceTiming.transferSizeperformanceResourceTiming.encodedBodySizeperformanceResourceTiming.decodedBodySizeperformanceResourceTiming.toJSON()
- Class:
perf_hooks.PerformanceObserver - Class:
PerformanceObserverEntryList perf_hooks.createHistogram([options])perf_hooks.monitorEventLoopDelay([options])- Class:
Histogramhistogram.counthistogram.countBigInthistogram.exceedshistogram.exceedsBigInthistogram.maxhistogram.maxBigInthistogram.meanhistogram.minhistogram.minBigInthistogram.percentile(percentile)histogram.percentileBigInt(percentile)histogram.percentileshistogram.percentilesBigInthistogram.reset()histogram.stddev
- Class:
IntervalHistogram extends Histogram - Class:
RecordableHistogram extends Histogram - Examples
- Permissions
- Process
- Process events
process.abort()process.allowedNodeEnvironmentFlagsprocess.archprocess.argvprocess.argv0process.channelprocess.chdir(directory)process.configprocess.connectedprocess.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.exit([code])process.exitCodeprocess.getActiveResourcesInfo()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.mainModuleprocess.memoryUsage()process.memoryUsage.rss()process.nextTick(callback[, ...args])process.noDeprecationprocess.pidprocess.platformprocess.ppidprocess.releaseprocess.reportprocess.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.stderrprocess.stdinprocess.stdoutprocess.throwDeprecationprocess.titleprocess.traceDeprecationprocess.umask()process.umask(mask)process.uptime()process.versionprocess.versions- Exit codes
- Punycode
- Query string
- Readline
- Class:
Interface- Event:
'close' - Event:
'line' - Event:
'history' - Event:
'pause' - Event:
'resume' - Event:
'SIGCONT' - Event:
'SIGINT' - Event:
'SIGTSTP' rl.close()rl.pause()rl.prompt([preserveCursor])rl.question(query[, options], callback)rl.resume()rl.setPrompt(prompt)rl.getPrompt()rl.write(data[, key])rl[Symbol.asyncIterator]()rl.linerl.cursorrl.getCursorPos()
- Event:
readline.clearLine(stream, dir[, callback])readline.clearScreenDown(stream[, callback])readline.createInterface(options)readline.cursorTo(stream, x[, y][, callback])readline.emitKeypressEvents(stream[, interface])readline.moveCursor(stream, dx, dy[, callback])- Example: Tiny CLI
- Example: Read file stream line-by-Line
- TTY keybindings
- Class:
- REPL
- Diagnostic report
- 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.destroyedwritable.end([chunk[, encoding]][, callback])writable.setDefaultEncoding(encoding)writable.uncork()writable.writablewritable.writableAbortedwritable.writableEndedwritable.writableCorkedwritable.writableFinishedwritable.writableHighWaterMarkwritable.writableLengthwritable.writableNeedDrainwritable.writableObjectModewritable.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.destroyedreadable.isPaused()readable.pause()readable.pipe(destination[, options])readable.read([size])readable.readablereadable.readableAbortedreadable.readableDidReadreadable.readableEncodingreadable.readableEndedreadable.readableFlowingreadable.readableHighWaterMarkreadable.readableLengthreadable.readableObjectModereadable.resume()readable.setEncoding(encoding)readable.unpipe([destination])readable.unshift(chunk[, encoding])readable.wrap(stream)readable[Symbol.asyncIterator]()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.asIndexedPairs([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.Readable.from(iterable[, options])stream.Readable.isDisturbed(stream)stream.isErrored(stream)stream.isReadable(stream)stream.Readable.toWeb(streamReadable)stream.Writable.fromWeb(writableStream[, options])stream.Writable.toWeb(streamWritable)stream.Duplex.from(src)stream.addAbortSignal(signal, stream)
- Writable streams
- API for stream implementers
- Additional notes
- String decoder
- Test runner
- Subtests
- Skipping tests
describe/itsyntax- Extraneous asynchronous activity
- Running tests from the command line
run([options])test([name][, options][, fn])describe([name][, options][, fn])describe.skip([name][, options][, fn])describe.todo([name][, options][, fn])it([name][, options][, fn])it.skip([name][, options][, fn])it.todo([name][, options][, fn])before([, fn][, options])after([, fn][, options])beforeEach([, fn][, options])afterEach([, fn][, options])- Class:
TapStream - Class:
TestContext - Class:
SuiteContext
- Timers
- TLS (SSL)
- Determining if crypto support is unavailable
- TLS/SSL concepts
- Modifying the default TLS cipher suite
- X509 certificate error codes
- Class:
tls.CryptoStream - Class:
tls.SecurePair - 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:
'secureConnect' - Event:
'session' tlsSocket.address()tlsSocket.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.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.createSecurePair([context][, isServer][, requestCert][, rejectUnauthorized][, options])tls.createServer([options][, secureConnectionListener])tls.getCiphers()tls.rootCertificatestls.DEFAULT_ECDH_CURVEtls.DEFAULT_MAX_VERSIONtls.DEFAULT_MIN_VERSION
- Trace events
- TTY
- Class:
tty.ReadStream - Class:
tty.WriteStream- 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
- Event:
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.close([callback])socket.connect(port[, address][, callback])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:
URLSearchParamsnew URLSearchParams()new URLSearchParams(string)new URLSearchParams(obj)new URLSearchParams(iterable)urlSearchParams.append(name, value)urlSearchParams.delete(name)urlSearchParams.entries()urlSearchParams.forEach(fn[, thisArg])urlSearchParams.get(name)urlSearchParams.getAll(name)urlSearchParams.has(name)urlSearchParams.keys()urlSearchParams.set(name, value)urlSearchParams.sort()urlSearchParams.toString()urlSearchParams.values()urlSearchParams[Symbol.iterator]()
url.domainToASCII(domain)url.domainToUnicode(domain)url.fileURLToPath(url)url.format(URL[, options])url.pathToFileURL(path)url.urlToHttpOptions(url)
- Class:
- Legacy URL API
- Percent-encoding in URLs
- Util
util.callbackify(original)util.debuglog(section[, callback])util.debug(section)util.deprecate(fn, msg[, code])util.format(format[, ...args])util.formatWithOptions(inspectOptions, format[, ...args])util.getSystemErrorName(err)util.getSystemErrorMap()util.inherits(constructor, superConstructor)util.inspect(object[, options])util.inspect(object[, showHidden[, depth[, colors]]])util.isDeepStrictEqual(val1, val2)util.parseArgs([config])util.promisify(original)util.stripVTControlCharacters(str)- Class:
util.TextDecoder - Class:
util.TextEncoder util.toUSVString(string)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.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.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)util.types.isWebAssemblyCompiledModule(value)
- Deprecated APIs
util._extend(target, source)util.isArray(object)util.isBoolean(object)util.isBuffer(object)util.isDate(object)util.isError(object)util.isFunction(object)util.isNull(object)util.isNullOrUndefined(object)util.isNumber(object)util.isObject(object)util.isPrimitive(object)util.isRegExp(object)util.isString(object)util.isSymbol(object)util.isUndefined(object)util.log(string)
- V8
v8.cachedDataVersionTag()v8.getHeapCodeStatistics()v8.getHeapSnapshot()v8.getHeapSpaceStatistics()v8.getHeapStatistics()v8.setFlagsFromString(flags)v8.stopCoverage()v8.takeCoverage()v8.writeHeapSnapshot([filename])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
- VM (executing JavaScript)
- Class:
vm.Script - Class:
vm.Module - Class:
vm.SourceTextModule - Class:
vm.SyntheticModule vm.compileFunction(code[, params[, options]])vm.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
- Class:
- WebAssembly System Interface (WASI)
- Web Crypto API
- Examples
- Algorithm matrix
- Class:
Crypto - Class:
CryptoKey - Class:
CryptoKeyPair - Class:
SubtleCryptosubtle.decrypt(algorithm, key, data)subtle.deriveBits(algorithm, baseKey, length)subtle.deriveKey(algorithm, baseKey, derivedKeyAlgorithm, extractable, keyUsages)subtle.digest(algorithm, data)subtle.encrypt(algorithm, key, data)subtle.exportKey(format, key)subtle.generateKey(algorithm, extractable, keyUsages)subtle.importKey(format, keyData, algorithm, extractable, keyUsages)subtle.sign(algorithm, key, data)subtle.unwrapKey(format, wrappedKey, unwrappingKey, unwrapAlgo, unwrappedKeyAlgo, extractable, keyUsages)subtle.verify(algorithm, key, signature, data)subtle.wrapKey(format, key, wrappingKey, wrapAlgo)
- Algorithm parameters
- Class:
AlgorithmIdentifier - Class:
AesCbcParams - Class:
AesCtrParams - Class:
AesGcmParams - Class:
AesKeyGenParams - Class:
EcdhKeyDeriveParams - Class:
EcdsaParams - Class:
EcKeyGenParams - Class:
EcKeyImportParams - Class:
Ed448Params - Class:
HkdfParams - Class:
HmacImportParams - Class:
HmacKeyGenParams - Class:
Pbkdf2Params - Class:
RsaHashedImportParams - Class:
RsaHashedKeyGenParams - Class:
RsaOaepParams - Class:
RsaPssParams
- Class:
- Web Streams API
- Overview
- API
- 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()
- 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 - Utility Consumers
- Class:
- Worker threads
worker.getEnvironmentData(key)worker.isMainThreadworker.markAsUntransferable(object)worker.moveMessagePortToContext(port, contextifiedSandbox)worker.parentPortworker.receiveMessageOnPort(port)worker.resourceLimitsworker.SHARE_ENVworker.setEnvironmentData(key[, value])worker.threadIdworker.workerData- Class:
BroadcastChannel extends EventTarget - Class:
MessageChannel - Class:
MessagePort - Class:
Workernew Worker(filename[, options])- Event:
'error' - Event:
'exit' - Event:
'message' - Event:
'messageerror' - Event:
'online' worker.getHeapSnapshot()worker.performanceworker.postMessage(value[, transferList])worker.ref()worker.resourceLimitsworker.stderrworker.stdinworker.stdoutworker.terminate()worker.threadIdworker.unref()
- 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.ZlibBase zlib.constantszlib.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])- 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])
About this documentation#
Welcome to the official API reference documentation for Node.js!
Node.js is a JavaScript runtime built on the V8 JavaScript engine.
Contributing#
Report errors in this documentation in the issue tracker. See the contributing guide for directions on how to submit pull requests.
Stability index#
Throughout the documentation are indications of a section's stability. Some APIs are so proven and so relied upon that they are unlikely to ever change at all. Others are brand new and experimental, or known to be hazardous.
The stability indices are as follows:
Features are marked as legacy rather than being deprecated if their use does no harm, and they are widely relied upon within the npm ecosystem. Bugs found in legacy features are unlikely to be fixed.
Use caution when making use of Experimental features, particularly within modules. Users may not be aware that experimental features are being used. Bugs or behavior changes may surprise users when Experimental API modifications occur. To avoid surprises, use of an Experimental feature may need a command-line flag. Experimental features may also emit a warning.
Stability overview#
JSON output#
Every .html document has a corresponding .json document. This is for IDEs
and other utilities that consume the documentation.
System calls and man pages#
Node.js functions which wrap a system call will document that. The docs link to the corresponding man pages which describe how the system call works.
Most Unix system calls have Windows analogues. Still, behavior differences may be unavoidable.
Usage and example#
Usage#
node [options] [V8 options] [script.js | -e "script" | - ] [arguments]
Please see the Command-line options document for more information.
Example#
An example of a web server written with Node.js which responds with
'Hello, World!':
Commands in this document start with $ or > to replicate how they would
appear in a user's terminal. Do not include the $ and > characters. They are
there to show the start of each command.
Lines that don't start with $ or > character show the output of the previous
command.
First, make sure to have downloaded and installed Node.js. See Installing Node.js via package manager for further install information.
Now, create an empty project folder called projects, then navigate into it.
Linux and Mac:
$ mkdir ~/projects
$ cd ~/projects
Windows CMD:
> mkdir %USERPROFILE%\projects
> cd %USERPROFILE%\projects
Windows PowerShell:
> mkdir $env:USERPROFILE\projects
> cd $env:USERPROFILE\projects
Next, create a new source file in the projects
folder and call it hello-world.js.
Open hello-world.js in any preferred text editor and
paste in the following content:
const http = require('node:http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello, World!\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
Save the file, go back to the terminal window, and enter the following command:
$ node hello-world.js
Output like this should appear in the terminal:
Server running at http://127.0.0.1:3000/
Now, open any preferred web browser and visit http://127.0.0.1:3000.
If the browser displays the string Hello, World!, that indicates
the server is working.
Assert#
Source Code: lib/assert.js
The node:assert module provides a set of assertion functions for verifying
invariants.
Strict assertion mode#
In strict assertion mode, non-strict methods behave like their corresponding
strict methods. For example, assert.deepEqual() will behave like
assert.deepStrictEqual().
In strict assertion mode, error messages for objects display a diff. In legacy assertion mode, error messages for objects display the objects, often truncated.
To use strict assertion mode:
import { strict as assert } from 'node:assert';const assert = require('node:assert').strict;
import assert from 'node:assert/strict';const assert = require('node:assert/strict');
Example error diff:
import { strict as assert } from 'node:assert';
assert.deepEqual([[[1, 2, 3]], 4, 5], [[[1, 2, '3']], 4, 5]);
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected ... Lines skipped
//
// [
// [
// ...
// 2,
// + 3
// - '3'
// ],
// ...
// 5
// ]const assert = require('node:assert/strict');
assert.deepEqual([[[1, 2, 3]], 4, 5], [[[1, 2, '3']], 4, 5]);
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected ... Lines skipped
//
// [
// [
// ...
// 2,
// + 3
// - '3'
// ],
// ...
// 5
// ]
To deactivate the colors, use the NO_COLOR or NODE_DISABLE_COLORS
environment variables. This will also deactivate the colors in the REPL. For
more on color support in terminal environments, read the tty
getColorDepth() documentation.
Legacy assertion mode#
Legacy assertion mode uses the == operator in:
To use legacy assertion mode:
import assert from 'node:assert';const assert = require('node:assert');
Legacy assertion mode may have surprising results, especially when using
assert.deepEqual():
// WARNING: This does not throw an AssertionError in legacy assertion mode!
assert.deepEqual(/a/gi, new Date());
Class: assert.AssertionError[src]#
- Extends: <errors.Error>
Indicates the failure of an assertion. All errors thrown by the node:assert
module will be instances of the AssertionError class.
new assert.AssertionError(options)#
options<Object>message<string> If provided, the error message is set to this value.actual<any> Theactualproperty on the error instance.expected<any> Theexpectedproperty on the error instance.operator<string> Theoperatorproperty on the error instance.stackStartFn<Function> If provided, the generated stack trace omits frames before this function.
A subclass of Error that indicates the failure of an assertion.
All instances contain the built-in Error properties (message and name)
and:
actual<any> Set to theactualargument for methods such asassert.strictEqual().expected<any> Set to theexpectedvalue for methods such asassert.strictEqual().generatedMessage<boolean> Indicates if the message was auto-generated (true) or not.code<string> Value is alwaysERR_ASSERTIONto show that the error is an assertion error.operator<string> Set to the passed in operator value.
import assert from 'node:assert';
// Generate an AssertionError to compare the error message later:
const { message } = new assert.AssertionError({
actual: 1,
expected: 2,
operator: 'strictEqual'
});
// Verify error output:
try {
assert.strictEqual(1, 2);
} catch (err) {
assert(err instanceof assert.AssertionError);
assert.strictEqual(err.message, message);
assert.strictEqual(err.name, 'AssertionError');
assert.strictEqual(err.actual, 1);
assert.strictEqual(err.expected, 2);
assert.strictEqual(err.code, 'ERR_ASSERTION');
assert.strictEqual(err.operator, 'strictEqual');
assert.strictEqual(err.generatedMessage, true);
}const assert = require('node:assert');
// Generate an AssertionError to compare the error message later:
const { message } = new assert.AssertionError({
actual: 1,
expected: 2,
operator: 'strictEqual'
});
// Verify error output:
try {
assert.strictEqual(1, 2);
} catch (err) {
assert(err instanceof assert.AssertionError);
assert.strictEqual(err.message, message);
assert.strictEqual(err.name, 'AssertionError');
assert.strictEqual(err.actual, 1);
assert.strictEqual(err.expected, 2);
assert.strictEqual(err.code, 'ERR_ASSERTION');
assert.strictEqual(err.operator, 'strictEqual');
assert.strictEqual(err.generatedMessage, true);
}
Class: assert.CallTracker#
This feature is currently experimental and behavior might still change.
new assert.CallTracker()#
Creates a new CallTracker object which can be used to track if functions
were called a specific number of times. The tracker.verify() must be called
for the verification to take place. The usual pattern would be to call it in a
process.on('exit') handler.
import assert from 'node:assert';
import process from 'node:process';
const tracker = new assert.CallTracker();
function func() {}
// callsfunc() must be called exactly 1 time before tracker.verify().
const callsfunc = tracker.calls(func, 1);
callsfunc();
// Calls tracker.verify() and verifies if all tracker.calls() functions have
// been called exact times.
process.on('exit', () => {
tracker.verify();
});const assert = require('node:assert');
const tracker = new assert.CallTracker();
function func() {}
// callsfunc() must be called exactly 1 time before tracker.verify().
const callsfunc = tracker.calls(func, 1);
callsfunc();
// Calls tracker.verify() and verifies if all tracker.calls() functions have
// been called exact times.
process.on('exit', () => {
tracker.verify();
});
tracker.calls([fn][, exact])#
fn<Function> Default: A no-op function.exact<number> Default:1.- Returns: <Function> that wraps
fn.
The wrapper function is expected to be called exactly exact times. If the
function has not been called exactly exact times when
tracker.verify() is called, then tracker.verify() will throw an
error.
import assert from 'node:assert';
// Creates call tracker.
const tracker = new assert.CallTracker();
function func() {}
// Returns a function that wraps func() that must be called exact times
// before tracker.verify().
const callsfunc = tracker.calls(func);const assert = require('node:assert');
// Creates call tracker.
const tracker = new assert.CallTracker();
function func() {}
// Returns a function that wraps func() that must be called exact times
// before tracker.verify().
const callsfunc = tracker.calls(func);
tracker.getCalls(fn)#
-
fn<Function>. -
Returns: <Array> with all the calls to a tracked function.
-
Object <Object>
import assert from 'node:assert';
const tracker = new assert.CallTracker();
function func() {}
const callsfunc = tracker.calls(func);
callsfunc(1, 2, 3);
assert.deepStrictEqual(tracker.getCalls(callsfunc),
[{ thisArg: this, arguments: [1, 2, 3 ] }]);const assert = require('node:assert');
// Creates call tracker.
const tracker = new assert.CallTracker();
function func() {}
const callsfunc = tracker.calls(func);
callsfunc(1, 2, 3);
assert.deepStrictEqual(tracker.getCalls(callsfunc),
[{ thisArg: this, arguments: [1, 2, 3 ] }]);
tracker.report()#
- Returns: <Array> of objects containing information about the wrapper functions
returned by
tracker.calls(). - Object <Object>
The arrays contains information about the expected and actual number of calls of the functions that have not been called the expected number of times.
import assert from 'node:assert';
// Creates call tracker.
const tracker = new assert.CallTracker();
function func() {}
// Returns a function that wraps func() that must be called exact times
// before tracker.verify().
const callsfunc = tracker.calls(func, 2);
// Returns an array containing information on callsfunc()
tracker.report();
// [
// {
// message: 'Expected the func function to be executed 2 time(s) but was
// executed 0 time(s).',
// actual: 0,
// expected: 2,
// operator: 'func',
// stack: stack trace
// }
// ]const assert = require('node:assert');
// Creates call tracker.
const tracker = new assert.CallTracker();
function func() {}
// Returns a function that wraps func() that must be called exact times
// before tracker.verify().
const callsfunc = tracker.calls(func, 2);
// Returns an array containing information on callsfunc()
tracker.report();
// [
// {
// message: 'Expected the func function to be executed 2 time(s) but was
// executed 0 time(s).',
// actual: 0,
// expected: 2,
// operator: 'func',
// stack: stack trace
// }
// ]
tracker.reset([fn])#
fn<Function> a tracked function to reset.
reset calls of the call tracker. if a tracked function is passed as an argument, the calls will be reset for it. if no arguments are passed, all tracked functions will be reset
import assert from 'node:assert';
const tracker = new assert.CallTracker();
function func() {}
const callsfunc = tracker.calls(func);
callsfunc();
// Tracker was called once
tracker.getCalls(callsfunc).length === 1;
tracker.reset(callsfunc);
tracker.getCalls(callsfunc).length === 0;const assert = require('node:assert');
function func() {}
const callsfunc = tracker.calls(func);
callsfunc();
// Tracker was called once
tracker.getCalls(callsfunc).length === 1;
tracker.reset(callsfunc);
tracker.getCalls(callsfunc).length === 0;
tracker.verify()#
Iterates through the list of functions passed to
tracker.calls() and will throw an error for functions that
have not been called the expected number of times.
import assert from 'node:assert';
// Creates call tracker.
const tracker = new assert.CallTracker();
function func() {}
// Returns a function that wraps func() that must be called exact times
// before tracker.verify().
const callsfunc = tracker.calls(func, 2);
callsfunc();
// Will throw an error since callsfunc() was only called once.
tracker.verify();const assert = require('node:assert');
// Creates call tracker.
const tracker = new assert.CallTracker();
function func() {}
// Returns a function that wraps func() that must be called exact times
// before tracker.verify().
const callsfunc = tracker.calls(func, 2);
callsfunc();
// Will throw an error since callsfunc() was only called once.
tracker.verify();
assert(value[, message])#
An alias of assert.ok().
assert.deepEqual(actual, expected[, message])#
Strict assertion mode
An alias of assert.deepStrictEqual().
Legacy assertion mode
assert.deepStrictEqual() instead.Tests for deep equality between the actual and expected parameters. Consider
using assert.deepStrictEqual() instead. assert.deepEqual() can have
surprising results.
Deep equality means that the enumerable "own" properties of child objects are also recursively evaluated by the following rules.
Comparison details#
- Primitive values are compared with the
==operator, with the exception ofNaN. It is treated as being identical in case both sides areNaN. - Type tags of objects should be the same.
- Only enumerable "own" properties are considered.
Errornames and messages are always compared, even if these are not enumerable properties.- Object wrappers are compared both as objects and unwrapped values.
Objectproperties are compared unordered.Mapkeys andSetitems are compared unordered.- Recursion stops when both sides differ or both sides encounter a circular reference.
- Implementation does not test the
[[Prototype]]of objects. Symbolproperties are not compared.WeakMapandWeakSetcomparison does not rely on their values.
The following example does not throw an AssertionError because the
primitives are compared using the == operator.
import assert from 'node:assert';
// WARNING: This does not throw an AssertionError!
assert.deepEqual('+00000000', false);const assert = require('node:assert');
// WARNING: This does not throw an AssertionError!
assert.deepEqual('+00000000', false);
"Deep" equality means that the enumerable "own" properties of child objects are evaluated also:
import assert from 'node:assert';
const obj1 = {
a: {
b: 1
}
};
const obj2 = {
a: {
b: 2
}
};
const obj3 = {
a: {
b: 1
}
};
const obj4 = Object.create(obj1);
assert.deepEqual(obj1, obj1);
// OK
// Values of b are different:
assert.deepEqual(obj1, obj2);
// AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } }
assert.deepEqual(obj1, obj3);
// OK
// Prototypes are ignored:
assert.deepEqual(obj1, obj4);
// AssertionError: { a: { b: 1 } } deepEqual {}const assert = require('node:assert');
const obj1 = {
a: {
b: 1
}
};
const obj2 = {
a: {
b: 2
}
};
const obj3 = {
a: {
b: 1
}
};
const obj4 = Object.create(obj1);
assert.deepEqual(obj1, obj1);
// OK
// Values of b are different:
assert.deepEqual(obj1, obj2);
// AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } }
assert.deepEqual(obj1, obj3);
// OK
// Prototypes are ignored:
assert.deepEqual(obj1, obj4);
// AssertionError: { a: { b: 1 } } deepEqual {}
If the values are not equal, an AssertionError is thrown with a message
property set equal to the value of the message parameter. If the message
parameter is undefined, a default error message is assigned. If the message
parameter is an instance of an Error then it will be thrown instead of the
AssertionError.
assert.deepStrictEqual(actual, expected[, message])#
Tests for deep equality between the actual and expected parameters.
"Deep" equality means that the enumerable "own" properties of child objects
are recursively evaluated also by the following rules.
Comparison details#
- Primitive values are compared using
Object.is(). - Type tags of objects should be the same.
[[Prototype]]of objects are compared using the===operator.- Only enumerable "own" properties are considered.
Errornames and messages are always compared, even if these are not enumerable properties.- Enumerable own
Symbolproperties are compared as well. - Object wrappers are compared both as objects and unwrapped values.
Objectproperties are compared unordered.Mapkeys andSetitems are compared unordered.- Recursion stops when both sides differ or both sides encounter a circular reference.
WeakMapandWeakSetcomparison does not rely on their values. See below for further details.
import assert from 'node:assert/strict';
// This fails because 1 !== '1'.
assert.deepStrictEqual({ a: 1 }, { a: '1' });
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
// {
// + a: 1
// - a: '1'
// }
// The following objects don't have own properties
const date = new Date();
const object = {};
const fakeDate = {};
Object.setPrototypeOf(fakeDate, Date.prototype);
// Different [[Prototype]]:
assert.deepStrictEqual(object, fakeDate);
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
// + {}
// - Date {}
// Different type tags:
assert.deepStrictEqual(date, fakeDate);
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
// + 2018-04-26T00:49:08.604Z
// - Date {}
assert.deepStrictEqual(NaN, NaN);
// OK because Object.is(NaN, NaN) is true.
// Different unwrapped numbers:
assert.deepStrictEqual(new Number(1), new Number(2));
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
// + [Number: 1]
// - [Number: 2]
assert.deepStrictEqual(new String('foo'), Object('foo'));
// OK because the object and the string are identical when unwrapped.
assert.deepStrictEqual(-0, -0);
// OK
// Different zeros:
assert.deepStrictEqual(0, -0);
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
// + 0
// - -0
const symbol1 = Symbol();
const symbol2 = Symbol();
assert.deepStrictEqual({ [symbol1]: 1 }, { [symbol1]: 1 });
// OK, because it is the same symbol on both objects.
assert.deepStrictEqual({ [symbol1]: 1 }, { [symbol2]: 1 });
// AssertionError [ERR_ASSERTION]: Inputs identical but not reference equal:
//
// {
// [Symbol()]: 1
// }
const weakMap1 = new WeakMap();
const weakMap2 = new WeakMap([[{}, {}]]);
const weakMap3 = new WeakMap();
weakMap3.unequal = true;
assert.deepStrictEqual(weakMap1, weakMap2);
// OK, because it is impossible to compare the entries
// Fails because weakMap3 has a property that weakMap1 does not contain:
assert.deepStrictEqual(weakMap1, weakMap3);
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
// WeakMap {
// + [items unknown]
// - [items unknown],
// - unequal: true
// }const assert = require('node:assert/strict');
// This fails because 1 !== '1'.
assert.deepStrictEqual({ a: 1 }, { a: '1' });
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
// {
// + a: 1
// - a: '1'
// }
// The following objects don't have own properties
const date = new Date();
const object = {};
const fakeDate = {};
Object.setPrototypeOf(fakeDate, Date.prototype);
// Different [[Prototype]]:
assert.deepStrictEqual(object, fakeDate);
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
// + {}
// - Date {}
// Different type tags:
assert.deepStrictEqual(date, fakeDate);
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
// + 2018-04-26T00:49:08.604Z
// - Date {}
assert.deepStrictEqual(NaN, NaN);
// OK because Object.is(NaN, NaN) is true.
// Different unwrapped numbers:
assert.deepStrictEqual(new Number(1), new Number(2));
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
// + [Number: 1]
// - [Number: 2]
assert.deepStrictEqual(new String('foo'), Object('foo'));
// OK because the object and the string are identical when unwrapped.
assert.deepStrictEqual(-0, -0);
// OK
// Different zeros:
assert.deepStrictEqual(0, -0);
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
// + 0
// - -0
const symbol1 = Symbol();
const symbol2 = Symbol();
assert.deepStrictEqual({ [symbol1]: 1 }, { [symbol1]: 1 });
// OK, because it is the same symbol on both objects.
assert.deepStrictEqual({ [symbol1]: 1 }, { [symbol2]: 1 });
// AssertionError [ERR_ASSERTION]: Inputs identical but not reference equal:
//
// {
// [Symbol()]: 1
// }
const weakMap1 = new WeakMap();
const weakMap2 = new WeakMap([[{}, {}]]);
const weakMap3 = new WeakMap();
weakMap3.unequal = true;
assert.deepStrictEqual(weakMap1, weakMap2);
// OK, because it is impossible to compare the entries
// Fails because weakMap3 has a property that weakMap1 does not contain:
assert.deepStrictEqual(weakMap1, weakMap3);
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
// WeakMap {
// + [items unknown]
// - [items unknown],
// - unequal: true
// }
If the values are not equal, an AssertionError is thrown with a message
property set equal to the value of the message parameter. If the message
parameter is undefined, a default error message is assigned. If the message
parameter is an instance of an Error then it will be thrown instead of the
AssertionError.
assert.doesNotMatch(string, regexp[, message])#
Expects the string input not to match the regular expression.
import assert from 'node:assert/strict';
assert.doesNotMatch('I will fail', /fail/);
// AssertionError [ERR_ASSERTION]: The input was expected to not match the ...
assert.doesNotMatch(123, /pass/);
// AssertionError [ERR_ASSERTION]: The "string" argument must be of type string.
assert.doesNotMatch('I will pass', /different/);
// OKconst assert = require('node:assert/strict');
assert.doesNotMatch('I will fail', /fail/);
// AssertionError [ERR_ASSERTION]: The input was expected to not match the ...
assert.doesNotMatch(123, /pass/);
// AssertionError [ERR_ASSERTION]: The "string" argument must be of type string.
assert.doesNotMatch('I will pass', /different/);
// OK
If the values do match, or if the string argument is of another type than
string, an AssertionError is thrown with a message property set equal
to the value of the message parameter. If the message parameter is
undefined, a default error message is assigned. If the message parameter is an
instance of an Error then it will be thrown instead of the
AssertionError.
assert.doesNotReject(asyncFn[, error][, message])#
asyncFn<Function> | <Promise>error<RegExp> | <Function>message<string>
Awaits the asyncFn promise or, if asyncFn is a function, immediately
calls the function and awaits the returned promise to complete. It will then
check that the promise is not rejected.
If asyncFn is a function and it throws an error synchronously,
assert.doesNotReject() will return a rejected Promise with that error. If
the function does not return a promise, assert.doesNotReject() will return a
rejected Promise with an ERR_INVALID_RETURN_VALUE error. In both cases
the error handler is skipped.
Using assert.doesNotReject() is actually not useful because there is little
benefit in catching a rejection and then rejecting it again. Instead, consider
adding a comment next to the specific code path that should not reject and keep
error messages as expressive as possible.
If specified, error can be a Class, RegExp, or a validation
function. See assert.throws() for more details.
Besides the async nature to await the completion behaves identically to
assert.doesNotThrow().
import assert from 'node:assert/strict';
await assert.doesNotReject(
async () => {
throw new TypeError('Wrong value');
},
SyntaxError
);const assert = require('node:assert/strict');
(async () => {
await assert.doesNotReject(
async () => {
throw new TypeError('Wrong value');
},
SyntaxError
);
})();
import assert from 'node:assert/strict';
assert.doesNotReject(Promise.reject(new TypeError('Wrong value')))
.then(() => {
// ...
});const assert = require('node:assert/strict');
assert.doesNotReject(Promise.reject(new TypeError('Wrong value')))
.then(() => {
// ...
});
assert.doesNotThrow(fn[, error][, message])#
fn<Function>error<RegExp> | <Function>message<string>
Asserts that the function fn does not throw an error.
Using assert.doesNotThrow() is actually not useful because there
is no benefit in catching an error and then rethrowing it. Instead, consider
adding a comment next to the specific code path that should not throw and keep
error messages as expressive as possible.
When assert.doesNotThrow() is called, it will immediately call the fn
function.
If an error is thrown and it is the same type as that specified by the error
parameter, then an AssertionError is thrown. If the error is of a
different type, or if the error parameter is undefined, the error is
propagated back to the caller.
If specified, error can be a Class, RegExp, or a validation
function. See assert.throws() for more details.
The following, for instance, will throw the TypeError because there is no
matching error type in the assertion:
import assert from 'node:assert/strict';
assert.doesNotThrow(
() => {
throw new TypeError('Wrong value');
},
SyntaxError
);const assert = require('node:assert/strict');
assert.doesNotThrow(
() => {
throw new TypeError('Wrong value');
},
SyntaxError
);
However, the following will result in an AssertionError with the message
'Got unwanted exception...':
import assert from 'node:assert/strict';
assert.doesNotThrow(
() => {
throw new TypeError('Wrong value');
},
TypeError
);const assert = require('node:assert/strict');
assert.doesNotThrow(
() => {
throw new TypeError('Wrong value');
},
TypeError
);
If an AssertionError is thrown and a value is provided for the message
parameter, the value of message will be appended to the AssertionError
message:
import assert from 'node:assert/strict';
assert.doesNotThrow(
() => {
throw new TypeError('Wrong value');
},
/Wrong value/,
'Whoops'
);
// Throws: AssertionError: Got unwanted exception: Whoopsconst assert = require('node:assert/strict');
assert.doesNotThrow(
() => {
throw new TypeError('Wrong value');
},
/Wrong value/,
'Whoops'
);
// Throws: AssertionError: Got unwanted exception: Whoops
assert.equal(actual, expected[, message])#
Strict assertion mode
An alias of assert.strictEqual().
Legacy assertion mode
assert.strictEqual() instead.Tests shallow, coercive equality between the actual and expected parameters
using the == operator. NaN is specially handled
and treated as being identical if both sides are NaN.
import assert from 'node:assert';
assert.equal(1, 1);
// OK, 1 == 1
assert.equal(1, '1');
// OK, 1 == '1'
assert.equal(NaN, NaN);
// OK
assert.equal(1, 2);
// AssertionError: 1 == 2
assert.equal({ a: { b: 1 } }, { a: { b: 1 } });
// AssertionError: { a: { b: 1 } } == { a: { b: 1 } }const assert = require('node:assert');
assert.equal(1, 1);
// OK, 1 == 1
assert.equal(1, '1');
// OK, 1 == '1'
assert.equal(NaN, NaN);
// OK
assert.equal(1, 2);
// AssertionError: 1 == 2
assert.equal({ a: { b: 1 } }, { a: { b: 1 } });
// AssertionError: { a: { b: 1 } } == { a: { b: 1 } }
If the values are not equal, an AssertionError is thrown with a message
property set equal to the value of the message parameter. If the message
parameter is undefined, a default error message is assigned. If the message
parameter is an instance of an Error then it will be thrown instead of the
AssertionError.
assert.fail([message])#
Throws an AssertionError with the provided error message or a default
error message. If the message parameter is an instance of an Error then
it will be thrown instead of the AssertionError.
import assert from 'node:assert/strict';
assert.fail();
// AssertionError [ERR_ASSERTION]: Failed
assert.fail('boom');
// AssertionError [ERR_ASSERTION]: boom
assert.fail(new TypeError('need array'));
// TypeError: need arrayconst assert = require('node:assert/strict');
assert.fail();
// AssertionError [ERR_ASSERTION]: Failed
assert.fail('boom');
// AssertionError [ERR_ASSERTION]: boom
assert.fail(new TypeError('need array'));
// TypeError: need array
Using assert.fail() with more than two arguments is possible but deprecated.
See below for further details.
assert.fail(actual, expected[, message[, operator[, stackStartFn]]])#
assert.fail([message]) or other assert
functions instead.actual<any>expected<any>message<string> | <Error>operator<string> Default:'!='stackStartFn<Function> Default:assert.fail
If message is falsy, the error message is set as the values of actual and
expected separated by the provided operator. If just the two actual and
expected arguments are provided, operator will default to '!='. If
message is provided as third argument it will be used as the error message and
the other arguments will be stored as properties on the thrown object. If
stackStartFn is provided, all stack frames above that function will be
removed from stacktrace (see Error.captureStackTrace). If no arguments are
given, the default message Failed will be used.
import assert from 'node:assert/strict';
assert.fail('a', 'b');
// AssertionError [ERR_ASSERTION]: 'a' != 'b'
assert.fail(1, 2, undefined, '>');
// AssertionError [ERR_ASSERTION]: 1 > 2
assert.fail(1, 2, 'fail');
// AssertionError [ERR_ASSERTION]: fail
assert.fail(1, 2, 'whoops', '>');
// AssertionError [ERR_ASSERTION]: whoops
assert.fail(1, 2, new TypeError('need array'));
// TypeError: need arrayconst assert = require('node:assert/strict');
assert.fail('a', 'b');
// AssertionError [ERR_ASSERTION]: 'a' != 'b'
assert.fail(1, 2, undefined, '>');
// AssertionError [ERR_ASSERTION]: 1 > 2
assert.fail(1, 2, 'fail');
// AssertionError [ERR_ASSERTION]: fail
assert.fail(1, 2, 'whoops', '>');
// AssertionError [ERR_ASSERTION]: whoops
assert.fail(1, 2, new TypeError('need array'));
// TypeError: need array
In the last three cases actual, expected, and operator have no
influence on the error message.
Example use of stackStartFn for truncating the exception's stacktrace:
import assert from 'node:assert/strict';
function suppressFrame() {
assert.fail('a', 'b', undefined, '!==', suppressFrame);
}
suppressFrame();
// AssertionError [ERR_ASSERTION]: 'a' !== 'b'
// at repl:1:1
// at ContextifyScript.Script.runInThisContext (vm.js:44:33)
// ...const assert = require('node:assert/strict');
function suppressFrame() {
assert.fail('a', 'b', undefined, '!==', suppressFrame);
}
suppressFrame();
// AssertionError [ERR_ASSERTION]: 'a' !== 'b'
// at repl:1:1
// at ContextifyScript.Script.runInThisContext (vm.js:44:33)
// ...
assert.ifError(value)#
value<any>
Throws value if value is not undefined or null. This is useful when
testing the error argument in callbacks. The stack trace contains all frames
from the error passed to ifError() including the potential new frames for
ifError() itself.
import assert from 'node:assert/strict';
assert.ifError(null);
// OK
assert.ifError(0);
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: 0
assert.ifError('error');
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: 'error'
assert.ifError(new Error());
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: Error
// Create some random error frames.
let err;
(function errorFrame() {
err = new Error('test error');
})();
(function ifErrorFrame() {
assert.ifError(err);
})();
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: test error
// at ifErrorFrame
// at errorFrameconst assert = require('node:assert/strict');
assert.ifError(null);
// OK
assert.ifError(0);
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: 0
assert.ifError('error');
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: 'error'
assert.ifError(new Error());
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: Error
// Create some random error frames.
let err;
(function errorFrame() {
err = new Error('test error');
})();
(function ifErrorFrame() {
assert.ifError(err);
})();
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: test error
// at ifErrorFrame
// at errorFrame
assert.match(string, regexp[, message])#
Expects the string input to match the regular expression.
import assert from 'node:assert/strict';
assert.match('I will fail', /pass/);
// AssertionError [ERR_ASSERTION]: The input did not match the regular ...
assert.match(123, /pass/);
// AssertionError [ERR_ASSERTION]: The "string" argument must be of type string.
assert.match('I will pass', /pass/);
// OKconst assert = require('node:assert/strict');
assert.match('I will fail', /pass/);
// AssertionError [ERR_ASSERTION]: The input did not match the regular ...
assert.match(123, /pass/);
// AssertionError [ERR_ASSERTION]: The "string" argument must be of type string.
assert.match('I will pass', /pass/);
// OK
If the values do not match, or if the string argument is of another type than
string, an AssertionError is thrown with a message property set equal
to the value of the message parameter. If the message parameter is
undefined, a default error message is assigned. If the message parameter is an
instance of an Error then it will be thrown instead of the
AssertionError.
assert.notDeepEqual(actual, expected[, message])#
Strict assertion mode
An alias of assert.notDeepStrictEqual().
Legacy assertion mode
assert.notDeepStrictEqual() instead.Tests for any deep inequality. Opposite of assert.deepEqual().
import assert from 'node:assert';
const obj1 = {
a: {
b: 1
}
};
const obj2 = {
a: {
b: 2
}
};
const obj3 = {
a: {
b: 1
}
};
const obj4 = Object.create(obj1);
assert.notDeepEqual(obj1, obj1);
// AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } }
assert.notDeepEqual(obj1, obj2);
// OK
assert.notDeepEqual(obj1, obj3);
// AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } }
assert.notDeepEqual(obj1, obj4);
// OKconst assert = require('node:assert');
const obj1 = {
a: {
b: 1
}
};
const obj2 = {
a: {
b: 2
}
};
const obj3 = {
a: {
b: 1
}
};
const obj4 = Object.create(obj1);
assert.notDeepEqual(obj1, obj1);
// AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } }
assert.notDeepEqual(obj1, obj2);
// OK
assert.notDeepEqual(obj1, obj3);
// AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } }
assert.notDeepEqual(obj1, obj4);
// OK
If the values are deeply equal, an AssertionError is thrown with a
message property set equal to the value of the message parameter. If the
message parameter is undefined, a default error message is assigned. If the
message parameter is an instance of an Error then it will be thrown
instead of the AssertionError.
assert.notDeepStrictEqual(actual, expected[, message])#
Tests for deep strict inequality. Opposite of assert.deepStrictEqual().
import assert from 'node:assert/strict';
assert.notDeepStrictEqual({ a: 1 }, { a: '1' });
// OKconst assert = require('node:assert/strict');
assert.notDeepStrictEqual({ a: 1 }, { a: '1' });
// OK
If the values are deeply and strictly equal, an AssertionError is thrown
with a message property set equal to the value of the message parameter. If
the message parameter is undefined, a default error message is assigned. If
the message parameter is an instance of an Error then it will be thrown
instead of the AssertionError.
assert.notEqual(actual, expected[, message])#
Strict assertion mode
An alias of assert.notStrictEqual().
Legacy assertion mode
assert.notStrictEqual() instead.Tests shallow, coercive inequality with the != operator. NaN is
specially handled and treated as being identical if both sides are NaN.
import assert from 'node:assert';
assert.notEqual(1, 2);
// OK
assert.notEqual(1, 1);
// AssertionError: 1 != 1
assert.notEqual(1, '1');
// AssertionError: 1 != '1'const assert = require('node:assert');
assert.notEqual(1, 2);
// OK
assert.notEqual(1, 1);
// AssertionError: 1 != 1
assert.notEqual(1, '1');
// AssertionError: 1 != '1'
If the values are equal, an AssertionError is thrown with a message
property set equal to the value of the message parameter. If the message
parameter is undefined, a default error message is assigned. If the message
parameter is an instance of an Error then it will be thrown instead of the
AssertionError.
assert.notStrictEqual(actual, expected[, message])#
Tests strict inequality between the actual and expected parameters as
determined by Object.is().
import assert from 'node:assert/strict';
assert.notStrictEqual(1, 2);
// OK
assert.notStrictEqual(1, 1);
// AssertionError [ERR_ASSERTION]: Expected "actual" to be strictly unequal to:
//
// 1
assert.notStrictEqual(1, '1');
// OKconst assert = require('node:assert/strict');
assert.notStrictEqual(1, 2);
// OK
assert.notStrictEqual(1, 1);
// AssertionError [ERR_ASSERTION]: Expected "actual" to be strictly unequal to:
//
// 1
assert.notStrictEqual(1, '1');
// OK
If the values are strictly equal, an AssertionError is thrown with a
message property set equal to the value of the message parameter. If the
message parameter is undefined, a default error message is assigned. If the
message parameter is an instance of an Error then it will be thrown
instead of the AssertionError.
assert.ok(value[, message])#
Tests if value is truthy. It is equivalent to
assert.equal(!!value, true, message).
If value is not truthy, an AssertionError is thrown with a message
property set equal to the value of the message parameter. If the message
parameter is undefined, a default error message is assigned. If the message
parameter is an instance of an Error then it will be thrown instead of the
AssertionError.
If no arguments are passed in at all message will be set to the string:
'No value argument passed to `assert.ok()`'.
Be aware that in the repl the error message will be different to the one
thrown in a file! See below for further details.
import assert from 'node:assert/strict';
assert.ok(true);
// OK
assert.ok(1);
// OK
assert.ok();
// AssertionError: No value argument passed to `assert.ok()`
assert.ok(false, 'it\'s false');
// AssertionError: it's false
// In the repl:
assert.ok(typeof 123 === 'string');
// AssertionError: false == true
// In a file (e.g. test.js):
assert.ok(typeof 123 === 'string');
// AssertionError: The expression evaluated to a falsy value:
//
// assert.ok(typeof 123 === 'string')
assert.ok(false);
// AssertionError: The expression evaluated to a falsy value:
//
// assert.ok(false)
assert.ok(0);
// AssertionError: The expression evaluated to a falsy value:
//
// assert.ok(0)const assert = require('node:assert/strict');
assert.ok(true);
// OK
assert.ok(1);
// OK
assert.ok();
// AssertionError: No value argument passed to `assert.ok()`
assert.ok(false, 'it\'s false');
// AssertionError: it's false
// In the repl:
assert.ok(typeof 123 === 'string');
// AssertionError: false == true
// In a file (e.g. test.js):
assert.ok(typeof 123 === 'string');
// AssertionError: The expression evaluated to a falsy value:
//
// assert.ok(typeof 123 === 'string')
assert.ok(false);
// AssertionError: The expression evaluated to a falsy value:
//
// assert.ok(false)
assert.ok(0);
// AssertionError: The expression evaluated to a falsy value:
//
// assert.ok(0)
import assert from 'node:assert/strict';
// Using `assert()` works the same:
assert(0);
// AssertionError: The expression evaluated to a falsy value:
//
// assert(0)const assert = require('node:assert');
// Using `assert()` works the same:
assert(0);
// AssertionError: The expression evaluated to a falsy value:
//
// assert(0)
assert.rejects(asyncFn[, error][, message])#
asyncFn<Function> | <Promise>error<RegExp> | <Function> | <Object> | <Error>message<string>
Awaits the asyncFn promise or, if asyncFn is a function, immediately
calls the function and awaits the returned promise to complete. It will then
check that the promise is rejected.
If asyncFn is a function and it throws an error synchronously,
assert.rejects() will return a rejected Promise with that error. If the
function does not return a promise, assert.rejects() will return a rejected
Promise with an ERR_INVALID_RETURN_VALUE error. In both cases the error
handler is skipped.
Besides the async nature to await the completion behaves identically to
assert.throws().
If specified, error can be a Class, RegExp, a validation function,
an object where each property will be tested for, or an instance of error where
each property will be tested for including the non-enumerable message and
name properties.
If specified, message will be the message provided by the AssertionError
if the asyncFn fails to reject.
import assert from 'node:assert/strict';
await assert.rejects(
async () => {
throw new TypeError('Wrong value');
},
{
name: 'TypeError',
message: 'Wrong value'
}
);const assert = require('node:assert/strict');
(async () => {
await assert.rejects(
async () => {
throw new TypeError('Wrong value');
},
{
name: 'TypeError',
message: 'Wrong value'
}
);
})();
import assert from 'node:assert/strict';
await assert.rejects(
async () => {
throw new TypeError('Wrong value');
},
(err) => {
assert.strictEqual(err.name, 'TypeError');
assert.strictEqual(err.message, 'Wrong value');
return true;
}
);const assert = require('node:assert/strict');
(async () => {
await assert.rejects(
async () => {
throw new TypeError('Wrong value');
},
(err) => {
assert.strictEqual(err.name, 'TypeError');
assert.strictEqual(err.message, 'Wrong value');
return true;
}
);
})();
import assert from 'node:assert/strict';
assert.rejects(
Promise.reject(new Error('Wrong value')),
Error
).then(() => {
// ...
});const assert = require('node:assert/strict');
assert.rejects(
Promise.reject(new Error('Wrong value')),
Error
).then(() => {
// ...
});
error cannot be a string. If a string is provided as the second
argument, then error is assumed to be omitted and the string will be used for
message instead. This can lead to easy-to-miss mistakes. Please read the
example in assert.throws() carefully if using a string as the second
argument gets considered.
assert.strictEqual(actual, expected[, message])#
Tests strict equality between the actual and expected parameters as
determined by Object.is().
import assert from 'node:assert/strict';
assert.strictEqual(1, 2);
// AssertionError [ERR_ASSERTION]: Expected inputs to be strictly equal:
//
// 1 !== 2
assert.strictEqual(1, 1);
// OK
assert.strictEqual('Hello foobar', 'Hello World!');
// AssertionError [ERR_ASSERTION]: Expected inputs to be strictly equal:
// + actual - expected
//
// + 'Hello foobar'
// - 'Hello World!'
// ^
const apples = 1;
const oranges = 2;
assert.strictEqual(apples, oranges, `apples ${apples} !== oranges ${oranges}`);
// AssertionError [ERR_ASSERTION]: apples 1 !== oranges 2
assert.strictEqual(1, '1', new TypeError('Inputs are not identical'));
// TypeError: Inputs are not identicalconst assert = require('node:assert/strict');
assert.strictEqual(1, 2);
// AssertionError [ERR_ASSERTION]: Expected inputs to be strictly equal:
//
// 1 !== 2
assert.strictEqual(1, 1);
// OK
assert.strictEqual('Hello foobar', 'Hello World!');
// AssertionError [ERR_ASSERTION]: Expected inputs to be strictly equal:
// + actual - expected
//
// + 'Hello foobar'
// - 'Hello World!'
// ^
const apples = 1;
const oranges = 2;
assert.strictEqual(apples, oranges, `apples ${apples} !== oranges ${oranges}`);
// AssertionError [ERR_ASSERTION]: apples 1 !== oranges 2
assert.strictEqual(1, '1', new TypeError('Inputs are not identical'));
// TypeError: Inputs are not identical
If the values are not strictly equal, an AssertionError is thrown with a
message property set equal to the value of the message parameter. If the
message parameter is undefined, a default error message is assigned. If the
message parameter is an instance of an Error then it will be thrown
instead of the AssertionError.
assert.throws(fn[, error][, message])#
fn<Function>error<RegExp> | <Function> | <Object> | <Error>message<string>
Expects the function fn to throw an error.
If specified, error can be a Class, RegExp, a validation function,
a validation object where each property will be tested for strict deep equality,
or an instance of error where each property will be tested for strict deep
equality including the non-enumerable message and name properties. When
using an object, it is also possible to use a regular expression, when
validating against a string property. See below for examples.
If specified, message will be appended to the message provided by the
AssertionError if the fn call fails to throw or in case the error validation
fails.
Custom validation object/error instance:
import assert from 'node:assert/strict';
const err = new TypeError('Wrong value');
err.code = 404;
err.foo = 'bar';
err.info = {
nested: true,
baz: 'text'
};
err.reg = /abc/i;
assert.throws(
() => {
throw err;
},
{
name: 'TypeError',
message: 'Wrong value',
info: {
nested: true,
baz: 'text'
}
// Only properties on the validation object will be tested for.
// Using nested objects requires all properties to be present. Otherwise
// the validation is going to fail.
}
);
// Using regular expressions to validate error properties:
assert.throws(
() => {
throw err;
},
{
// The `name` and `message` properties are strings and using regular
// expressions on those will match against the string. If they fail, an
// error is thrown.
name: /^TypeError$/,
message: /Wrong/,
foo: 'bar',
info: {
nested: true,
// It is not possible to use regular expressions for nested properties!
baz: 'text'
},
// The `reg` property contains a regular expression and only if the
// validation object contains an identical regular expression, it is going
// to pass.
reg: /abc/i
}
);
// Fails due to the different `message` and `name` properties:
assert.throws(
() => {
const otherErr = new Error('Not found');
// Copy all enumerable properties from `err` to `otherErr`.
for (const [key, value] of Object.entries(err)) {
otherErr[key] = value;
}
throw otherErr;
},
// The error's `message` and `name` properties will also be checked when using
// an error as validation object.
err
);const assert = require('node:assert/strict');
const err = new TypeError('Wrong value');
err.code = 404;
err.foo = 'bar';
err.info = {
nested: true,
baz: 'text'
};
err.reg = /abc/i;
assert.throws(
() => {
throw err;
},
{
name: 'TypeError',
message: 'Wrong value',
info: {
nested: true,
baz: 'text'
}
// Only properties on the validation object will be tested for.
// Using nested objects requires all properties to be present. Otherwise
// the validation is going to fail.
}
);
// Using regular expressions to validate error properties:
assert.throws(
() => {
throw err;
},
{
// The `name` and `message` properties are strings and using regular
// expressions on those will match against the string. If they fail, an
// error is thrown.
name: /^TypeError$/,
message: /Wrong/,
foo: 'bar',
info: {
nested: true,
// It is not possible to use regular expressions for nested properties!
baz: 'text'
},
// The `reg` property contains a regular expression and only if the
// validation object contains an identical regular expression, it is going
// to pass.
reg: /abc/i
}
);
// Fails due to the different `message` and `name` properties:
assert.throws(
() => {
const otherErr = new Error('Not found');
// Copy all enumerable properties from `err` to `otherErr`.
for (const [key, value] of Object.entries(err)) {
otherErr[key] = value;
}
throw otherErr;
},
// The error's `message` and `name` properties will also be checked when using
// an error as validation object.
err
);
Validate instanceof using constructor:
import assert from 'node:assert/strict';
assert.throws(
() => {
throw new Error('Wrong value');
},
Error
);const assert = require('node:assert/strict');
assert.throws(
() => {
throw new Error('Wrong value');
},
Error
);
Validate error message using RegExp:
Using a regular expression runs .toString on the error object, and will
therefore also include the error name.
import assert from 'node:assert/strict';
assert.throws(
() => {
throw new Error('Wrong value');
},
/^Error: Wrong value$/
);const assert = require('node:assert/strict');
assert.throws(
() => {
throw new Error('Wrong value');
},
/^Error: Wrong value$/
);
Custom error validation:
The function must return true to indicate all internal validations passed.
It will otherwise fail with an AssertionError.
import assert from 'node:assert/strict';
assert.throws(
() => {
throw new Error('Wrong value');
},
(err) => {
assert(err instanceof Error);
assert(/value/.test(err));
// Avoid returning anything from validation functions besides `true`.
// Otherwise, it's not clear what part of the validation failed. Instead,
// throw an error about the specific validation that failed (as done in this
// example) and add as much helpful debugging information to that error as
// possible.
return true;
},
'unexpected error'
);const assert = require('node:assert/strict');
assert.throws(
() => {
throw new Error('Wrong value');
},
(err) => {
assert(err instanceof Error);
assert(/value/.test(err));
// Avoid returning anything from validation functions besides `true`.
// Otherwise, it's not clear what part of the validation failed. Instead,
// throw an error about the specific validation that failed (as done in this
// example) and add as much helpful debugging information to that error as
// possible.
return true;
},
'unexpected error'
);
error cannot be a string. If a string is provided as the second
argument, then error is assumed to be omitted and the string will be used for
message instead. This can lead to easy-to-miss mistakes. Using the same
message as the thrown error message is going to result in an
ERR_AMBIGUOUS_ARGUMENT error. Please read the example below carefully if using
a string as the second argument gets considered:
import assert from 'node:assert/strict';
function throwingFirst() {
throw new Error('First');
}
function throwingSecond() {
throw new Error('Second');
}
function notThrowing() {}
// The second argument is a string and the input function threw an Error.
// The first case will not throw as it does not match for the error message
// thrown by the input function!
assert.throws(throwingFirst, 'Second');
// In the next example the message has no benefit over the message from the
// error and since it is not clear if the user intended to actually match
// against the error message, Node.js throws an `ERR_AMBIGUOUS_ARGUMENT` error.
assert.throws(throwingSecond, 'Second');
// TypeError [ERR_AMBIGUOUS_ARGUMENT]
// The string is only used (as message) in case the function does not throw:
assert.throws(notThrowing, 'Second');
// AssertionError [ERR_ASSERTION]: Missing expected exception: Second
// If it was intended to match for the error message do this instead:
// It does not throw because the error messages match.
assert.throws(throwingSecond, /Second$/);
// If the error message does not match, an AssertionError is thrown.
assert.throws(throwingFirst, /Second$/);
// AssertionError [ERR_ASSERTION]const assert = require('node:assert/strict');
function throwingFirst() {
throw new Error('First');
}
function throwingSecond() {
throw new Error('Second');
}
function notThrowing() {}
// The second argument is a string and the input function threw an Error.
// The first case will not throw as it does not match for the error message
// thrown by the input function!
assert.throws(throwingFirst, 'Second');
// In the next example the message has no benefit over the message from the
// error and since it is not clear if the user intended to actually match
// against the error message, Node.js throws an `ERR_AMBIGUOUS_ARGUMENT` error.
assert.throws(throwingSecond, 'Second');
// TypeError [ERR_AMBIGUOUS_ARGUMENT]
// The string is only used (as message) in case the function does not throw:
assert.throws(notThrowing, 'Second');
// AssertionError [ERR_ASSERTION]: Missing expected exception: Second
// If it was intended to match for the error message do this instead:
// It does not throw because the error messages match.
assert.throws(throwingSecond, /Second$/);
// If the error message does not match, an AssertionError is thrown.
assert.throws(throwingFirst, /Second$/);
// AssertionError [ERR_ASSERTION]
Due to the confusing error-prone notation, avoid a string as the second argument.
Asynchronous context tracking#
Source Code: lib/async_hooks.js
Introduction#
These classes are used to associate state and propagate it throughout callbacks and promise chains. They allow storing data throughout the lifetime of a web request or any other asynchronous duration. It is similar to thread-local storage in other languages.
The AsyncLocalStorage and AsyncResource classes are part of the
node:async_hooks module:
import { AsyncLocalStorage, AsyncResource } from 'node:async_hooks';const { AsyncLocalStorage, AsyncResource } = require('node:async_hooks');
Class: AsyncLocalStorage#
This class creates stores that stay coherent through asynchronous operations.
While you can create your own implementation on top of the node:async_hooks
module, AsyncLocalStorage should be preferred as it is a performant and memory
safe implementation that involves significant optimizations that are non-obvious
to implement.
The following example uses AsyncLocalStorage to build a simple logger
that assigns IDs to incoming HTTP requests and includes them in messages
logged within each request.
import http from 'node:http';
import { AsyncLocalStorage } from 'node:async_hooks';
const asyncLocalStorage = new AsyncLocalStorage();
function logWithId(msg) {
const id = asyncLocalStorage.getStore();
console.log(`${id !== undefined ? id : '-'}:`, msg);
}
let idSeq = 0;
http.createServer((req, res) => {
asyncLocalStorage.run(idSeq++, () => {
logWithId('start');
// Imagine any chain of async operations here
setImmediate(() => {
logWithId('finish');
res.end();
});
});
}).listen(8080);
http.get('http://localhost:8080');
http.get('http://localhost:8080');
// Prints:
// 0: start
// 1: start
// 0: finish
// 1: finishconst http = require('node:http');
const { AsyncLocalStorage } = require('node:async_hooks');
const asyncLocalStorage = new AsyncLocalStorage();
function logWithId(msg) {
const id = asyncLocalStorage.getStore();
console.log(`${id !== undefined ? id : '-'}:`, msg);
}
let idSeq = 0;
http.createServer((req, res) => {
asyncLocalStorage.run(idSeq++, () => {
logWithId('start');
// Imagine any chain of async operations here
setImmediate(() => {
logWithId('finish');
res.end();
});
});
}).listen(8080);
http.get('http://localhost:8080');
http.get('http://localhost:8080');
// Prints:
// 0: start
// 1: start
// 0: finish
// 1: finish
Each instance of AsyncLocalStorage maintains an independent storage context.
Multiple instances can safely exist simultaneously without risk of interfering
with each other's data.
new AsyncLocalStorage()#
Creates a new instance of AsyncLocalStorage. Store is only provided within a
run() call or after an enterWith() call.
asyncLocalStorage.disable()#
Disables the instance of AsyncLocalStorage. All subsequent calls
to asyncLocalStorage.getStore() will return undefined until
asyncLocalStorage.run() or asyncLocalStorage.enterWith() is called again.
When calling asyncLocalStorage.disable(), all current contexts linked to the
instance will be exited.
Calling asyncLocalStorage.disable() is required before the
asyncLocalStorage can be garbage collected. This does not apply to stores
provided by the asyncLocalStorage, as those objects are garbage collected
along with the corresponding async resources.
Use this method when the asyncLocalStorage is not in use anymore
in the current process.
asyncLocalStorage.getStore()#
- Returns: <any>
Returns the current store.
If called outside of an asynchronous context initialized by
calling asyncLocalStorage.run() or asyncLocalStorage.enterWith(), it
returns undefined.
asyncLocalStorage.enterWith(store)#
store<any>
Transitions into the context for the remainder of the current synchronous execution and then persists the store through any following asynchronous calls.
Example:
const store = { id: 1 };
// Replaces previous store with the given store object
asyncLocalStorage.enterWith(store);
asyncLocalStorage.getStore(); // Returns the store object
someAsyncOperation(() => {
asyncLocalStorage.getStore(); // Returns the same object
});
This transition will continue for the entire synchronous execution.
This means that if, for example, the context is entered within an event
handler subsequent event handlers will also run within that context unless
specifically bound to another context with an AsyncResource. That is why
run() should be preferred over enterWith() unless there are strong reasons
to use the latter method.
const store = { id: 1 };
emitter.on('my-event', () => {
asyncLocalStorage.enterWith(store);
});
emitter.on('my-event', () => {
asyncLocalStorage.getStore(); // Returns the same object
});
asyncLocalStorage.getStore(); // Returns undefined
emitter.emit('my-event');
asyncLocalStorage.getStore(); // Returns the same object
asyncLocalStorage.run(store, callback[, ...args])#
store<any>callback<Function>...args<any>
Runs a function synchronously within a context and returns its return value. The store is not accessible outside of the callback function. The store is accessible to any asynchronous operations created within the callback.
The optional args are passed to the callback function.
If the callback function throws an error, the error is thrown by run() too.
The stacktrace is not impacted by this call and the context is exited.
Example:
const store = { id: 2 };
try {
asyncLocalStorage.run(store, () => {
asyncLocalStorage.getStore(); // Returns the store object
setTimeout(() => {
asyncLocalStorage.getStore(); // Returns the store object
}, 200);
throw new Error();
});
} catch (e) {
asyncLocalStorage.getStore(); // Returns undefined
// The error will be caught here
}
asyncLocalStorage.exit(callback[, ...args])#
callback<Function>...args<any>
Runs a function synchronously outside of a context and returns its
return value. The store is not accessible within the callback function or
the asynchronous operations created within the callback. Any getStore()
call done within the callback function will always return undefined.
The optional args are passed to the callback function.
If the callback function throws an error, the error is thrown by exit() too.
The stacktrace is not impacted by this call and the context is re-entered.
Example:
// Within a call to run
try {
asyncLocalStorage.getStore(); // Returns the store object or value
asyncLocalStorage.exit(() => {
asyncLocalStorage.getStore(); // Returns undefined
throw new Error();
});
} catch (e) {
asyncLocalStorage.getStore(); // Returns the same object or value
// The error will be caught here
}
Usage with async/await#
If, within an async function, only one await call is to run within a context,
the following pattern should be used:
async function fn() {
await asyncLocalStorage.run(new Map(), () => {
asyncLocalStorage.getStore().set('key', value);
return foo(); // The return value of foo will be awaited
});
}
In this example, the store is only available in the callback function and the
functions called by foo. Outside of run, calling getStore will return
undefined.
Troubleshooting: Context loss#
In most cases, AsyncLocalStorage works without issues. In rare situations, the
current store is lost in one of the asynchronous operations.
If your code is callback-based, it is enough to promisify it with
util.promisify() so it starts working with native promises.
If you need to use a callback-based API or your code assumes
a custom thenable implementation, use the AsyncResource class
to associate the asynchronous operation with the correct execution context.
Find the function call responsible for the context loss by logging the content
of asyncLocalStorage.getStore() after the calls you suspect are responsible
for the loss. When the code logs undefined, the last callback called is
probably responsible for the context loss.
Class: AsyncResource#
The class AsyncResource is designed to be extended by the embedder's async
resources. Using this, users can easily trigger the lifetime events of their
own resources.
The init hook will trigger when an AsyncResource is instantiated.
The following is an overview of the AsyncResource API.
import { AsyncResource, executionAsyncId } from 'node:async_hooks';
// AsyncResource() is meant to be extended. Instantiating a
// new AsyncResource() also triggers init. If triggerAsyncId is omitted then
// async_hook.executionAsyncId() is used.
const asyncResource = new AsyncResource(
type, { triggerAsyncId: executionAsyncId(), requireManualDestroy: false }
);
// Run a function in the execution context of the resource. This will
// * establish the context of the resource
// * trigger the AsyncHooks before callbacks
// * call the provided function `fn` with the supplied arguments
// * trigger the AsyncHooks after callbacks
// * restore the original execution context
asyncResource.runInAsyncScope(fn, thisArg, ...args);
// Call AsyncHooks destroy callbacks.
asyncResource.emitDestroy();
// Return the unique ID assigned to the AsyncResource instance.
asyncResource.asyncId();
// Return the trigger ID for the AsyncResource instance.
asyncResource.triggerAsyncId();const { AsyncResource, executionAsyncId } = require('node:async_hooks');
// AsyncResource() is meant to be extended. Instantiating a
// new AsyncResource() also triggers init. If triggerAsyncId is omitted then
// async_hook.executionAsyncId() is used.
const asyncResource = new AsyncResource(
type, { triggerAsyncId: executionAsyncId(), requireManualDestroy: false }
);
// Run a function in the execution context of the resource. This will
// * establish the context of the resource
// * trigger the AsyncHooks before callbacks
// * call the provided function `fn` with the supplied arguments
// * trigger the AsyncHooks after callbacks
// * restore the original execution context
asyncResource.runInAsyncScope(fn, thisArg, ...args);
// Call AsyncHooks destroy callbacks.
asyncResource.emitDestroy();
// Return the unique ID assigned to the AsyncResource instance.
asyncResource.asyncId();
// Return the trigger ID for the AsyncResource instance.
asyncResource.triggerAsyncId();
new AsyncResource(type[, options])#
type<string> The type of async event.options<Object>triggerAsyncId<number> The ID of the execution context that created this async event. Default:executionAsyncId().requireManualDestroy<boolean> If set totrue, disablesemitDestroywhen the object is garbage collected. This usually does not need to be set (even ifemitDestroyis called manually), unless the resource'sasyncIdis retrieved and the sensitive API'semitDestroyis called with it. When set tofalse, theemitDestroycall on garbage collection will only take place if there is at least one activedestroyhook. Default:false.
Example usage:
class DBQuery extends AsyncResource {
constructor(db) {
super('DBQuery');
this.db = db;
}
getInfo(query, callback) {
this.db.get(query, (err, data) => {
this.runInAsyncScope(callback, null, err, data);
});
}
close() {
this.db = null;
this.emitDestroy();
}
}
Static method: AsyncResource.bind(fn[, type[, thisArg]])#
fn<Function> The function to bind to the current execution context.type<string> An optional name to associate with the underlyingAsyncResource.thisArg<any>
Binds the given function to the current execution context.
The returned function will have an asyncResource property referencing
the AsyncResource to which the function is bound.
asyncResource.bind(fn[, thisArg])#
fn<Function> The function to bind to the currentAsyncResource.thisArg<any>
Binds the given function to execute to this AsyncResource's scope.
The returned function will have an asyncResource property referencing
the AsyncResource to which the function is bound.
asyncResource.runInAsyncScope(fn[, thisArg, ...args])#
fn<Function> The function to call in the execution context of this async resource.thisArg<any> The receiver to be used for the function call....args<any> Optional arguments to pass to the function.
Call the provided function with the provided arguments in the execution context of the async resource. This will establish the context, trigger the AsyncHooks before callbacks, call the function, trigger the AsyncHooks after callbacks, and then restore the original execution context.
asyncResource.emitDestroy()#
- Returns: <AsyncResource> A reference to
asyncResource.
Call all destroy hooks. This should only ever be called once. An error will
be thrown if it is called more than once. This must be manually called. If
the resource is left to be collected by the GC then the destroy hooks will
never be called.
asyncResource.asyncId()#
- Returns: <number> The unique
asyncIdassigned to the resource.
asyncResource.triggerAsyncId()#
- Returns: <number> The same
triggerAsyncIdthat is passed to theAsyncResourceconstructor.
Using AsyncResource for a Worker thread pool#
The following example shows how to use the AsyncResource class to properly
provide async tracking for a Worker pool. Other resource pools, such as
database connection pools, can follow a similar model.
Assuming that the task is adding two numbers, using a file named
task_processor.js with the following content:
import { parentPort } from 'node:worker_threads';
parentPort.on('message', (task) => {
parentPort.postMessage(task.a + task.b);
});const { parentPort } = require('node:worker_threads');
parentPort.on('message', (task) => {
parentPort.postMessage(task.a + task.b);
});
a Worker pool around it could use the following structure:
import { AsyncResource } from 'node:async_hooks';
import { EventEmitter } from 'node:events';
import path from 'node:path';
import { Worker } from 'node:worker_threads';
const kTaskInfo = Symbol('kTaskInfo');
const kWorkerFreedEvent = Symbol('kWorkerFreedEvent');
class WorkerPoolTaskInfo extends AsyncResource {
constructor(callback) {
super('WorkerPoolTaskInfo');
this.callback = callback;
}
done(err, result) {
this.runInAsyncScope(this.callback, null, err, result);
this.emitDestroy(); // `TaskInfo`s are used only once.
}
}
export default class WorkerPool extends EventEmitter {
constructor(numThreads) {
super();
this.numThreads = numThreads;
this.workers = [];
this.freeWorkers = [];
this.tasks = [];
for (let i = 0; i < numThreads; i++)
this.addNewWorker();
// Any time the kWorkerFreedEvent is emitted, dispatch
// the next task pending in the queue, if any.
this.on(kWorkerFreedEvent, () => {
if (this.tasks.length > 0) {
const { task, callback } = this.tasks.shift();
this.runTask(task, callback);
}
});
}
addNewWorker() {
const worker = new Worker(new URL('task_processer.js', import.meta.url));
worker.on('message', (result) => {
// In case of success: Call the callback that was passed to `runTask`,
// remove the `TaskInfo` associated with the Worker, and mark it as free
// again.
worker[kTaskInfo].done(null, result);
worker[kTaskInfo] = null;
this.freeWorkers.push(worker);
this.emit(kWorkerFreedEvent);
});
worker.on('error', (err) => {
// In case of an uncaught exception: Call the callback that was passed to
// `runTask` with the error.
if (worker[kTaskInfo])
worker[kTaskInfo].done(err, null);
else
this.emit('error', err);
// Remove the worker from the list and start a new Worker to replace the
// current one.
this.workers.splice(this.workers.indexOf(worker), 1);
this.addNewWorker();
});
this.workers.push(worker);
this.freeWorkers.push(worker);
this.emit(kWorkerFreedEvent);
}
runTask(task, callback) {
if (this.freeWorkers.length === 0) {
// No free threads, wait until a worker thread becomes free.
this.tasks.push({ task, callback });
return;
}
const worker = this.freeWorkers.pop();
worker[kTaskInfo] = new WorkerPoolTaskInfo(callback);
worker.postMessage(task);
}
close() {
for (const worker of this.workers) worker.terminate();
}
}const { AsyncResource } = require('node:async_hooks');
const { EventEmitter } = require('node:events');
const path = require('node:path');
const { Worker } = require('node:worker_threads');
const kTaskInfo = Symbol('kTaskInfo');
const kWorkerFreedEvent = Symbol('kWorkerFreedEvent');
class WorkerPoolTaskInfo extends AsyncResource {
constructor(callback) {
super('WorkerPoolTaskInfo');
this.callback = callback;
}
done(err, result) {
this.runInAsyncScope(this.callback, null, err, result);
this.emitDestroy(); // `TaskInfo`s are used only once.
}
}
class WorkerPool extends EventEmitter {
constructor(numThreads) {
super();
this.numThreads = numThreads;
this.workers = [];
this.freeWorkers = [];
this.tasks = [];
for (let i = 0; i < numThreads; i++)
this.addNewWorker();
// Any time the kWorkerFreedEvent is emitted, dispatch
// the next task pending in the queue, if any.
this.on(kWorkerFreedEvent, () => {
if (this.tasks.length > 0) {
const { task, callback } = this.tasks.shift();
this.runTask(task, callback);
}
});
}
addNewWorker() {
const worker = new Worker(path.resolve(__dirname, 'task_processor.js'));
worker.on('message', (result) => {
// In case of success: Call the callback that was passed to `runTask`,
// remove the `TaskInfo` associated with the Worker, and mark it as free
// again.
worker[kTaskInfo].done(null, result);
worker[kTaskInfo] = null;
this.freeWorkers.push(worker);
this.emit(kWorkerFreedEvent);
});
worker.on('error', (err) => {
// In case of an uncaught exception: Call the callback that was passed to
// `runTask` with the error.
if (worker[kTaskInfo])
worker[kTaskInfo].done(err, null);
else
this.emit('error', err);
// Remove the worker from the list and start a new Worker to replace the
// current one.
this.workers.splice(this.workers.indexOf(worker), 1);
this.addNewWorker();
});
this.workers.push(worker);
this.freeWorkers.push(worker);
this.emit(kWorkerFreedEvent);
}
runTask(task, callback) {
if (this.freeWorkers.length === 0) {
// No free threads, wait until a worker thread becomes free.
this.tasks.push({ task, callback });
return;
}
const worker = this.freeWorkers.pop();
worker[kTaskInfo] = new WorkerPoolTaskInfo(callback);
worker.postMessage(task);
}
close() {
for (const worker of this.workers) worker.terminate();
}
}
module.exports = WorkerPool;
Without the explicit tracking added by the WorkerPoolTaskInfo objects,
it would appear that the callbacks are associated with the individual Worker
objects. However, the creation of the Workers is not associated with the
creation of the tasks and does not provide information about when tasks
were scheduled.
This pool could be used as follows:
import WorkerPool from './worker_pool.js';
import os from 'node:os';
const pool = new WorkerPool(os.cpus().length);
let finished = 0;
for (let i = 0; i < 10; i++) {
pool.runTask({ a: 42, b: 100 }, (err, result) => {
console.log(i, err, result);
if (++finished === 10)
pool.close();
});
}const WorkerPool = require('./worker_pool.js');
const os = require('node:os');
const pool = new WorkerPool(os.cpus().length);
let finished = 0;
for (let i = 0; i < 10; i++) {
pool.runTask({ a: 42, b: 100 }, (err, result) => {
console.log(i, err, result);
if (++finished === 10)
pool.close();
});
}
Integrating AsyncResource with EventEmitter#
Event listeners triggered by an EventEmitter may be run in a different
execution context than the one that was active when eventEmitter.on() was
called.
The following example shows how to use the AsyncResource class to properly
associate an event listener with the correct execution context. The same
approach can be applied to a Stream or a similar event-driven class.
import { createServer } from 'node:http';
import { AsyncResource, executionAsyncId } from 'node:async_hooks';
const server = createServer((req, res) => {
req.on('close', AsyncResource.bind(() => {
// Execution context is bound to the current outer scope.
}));
req.on('close', () => {
// Execution context is bound to the scope that caused 'close' to emit.
});
res.end();
}).listen(3000);const { createServer } = require('node:http');
const { AsyncResource, executionAsyncId } = require('node:async_hooks');
const server = createServer((req, res) => {
req.on('close', AsyncResource.bind(() => {
// Execution context is bound to the current outer scope.
}));
req.on('close', () => {
// Execution context is bound to the scope that caused 'close' to emit.
});
res.end();
}).listen(3000);Async hooks#
Source Code: lib/async_hooks.js
The node:async_hooks module provides an API to track asynchronous resources.
It can be accessed using:
import async_hooks from 'node:async_hooks';const async_hooks = require('node:async_hooks');
Terminology#
An asynchronous resource represents an object with an associated callback.
This callback may be called multiple times, such as the 'connection'
event in net.createServer(), or just a single time like in fs.open().
A resource can also be closed before the callback is called. AsyncHook does
not explicitly distinguish between these different cases but will represent them
as the abstract concept that is a resource.
If Workers are used, each thread has an independent async_hooks
interface, and each thread will use a new set of async IDs.
Overview#
Following is a simple overview of the public API.
import async_hooks from 'node:async_hooks';
// Return the ID of the current execution context.
const eid = async_hooks.executionAsyncId();
// Return the ID of the handle responsible for triggering the callback of the
// current execution scope to call.
const tid = async_hooks.triggerAsyncId();
// Create a new AsyncHook instance. All of these callbacks are optional.
const asyncHook =
async_hooks.createHook({ init, before, after, destroy, promiseResolve });
// Allow callbacks of this AsyncHook instance to call. This is not an implicit
// action after running the constructor, and must be explicitly run to begin
// executing callbacks.
asyncHook.enable();
// Disable listening for new asynchronous events.
asyncHook.disable();
//
// The following are the callbacks that can be passed to createHook().
//
// init() is called during object construction. The resource may not have
// completed construction when this callback runs. Therefore, all fields of the
// resource referenced by "asyncId" may not have been populated.
function init(asyncId, type, triggerAsyncId, resource) { }
// before() is called just before the resource's callback is called. It can be
// called 0-N times for handles (such as TCPWrap), and will be called exactly 1
// time for requests (such as FSReqCallback).
function before(asyncId) { }
// after() is called just after the resource's callback has finished.
function after(asyncId) { }
// destroy() is called when the resource is destroyed.
function destroy(asyncId) { }
// promiseResolve() is called only for promise resources, when the
// resolve() function passed to the Promise constructor is invoked
// (either directly or through other means of resolving a promise).
function promiseResolve(asyncId) { }const async_hooks = require('node:async_hooks');
// Return the ID of the current execution context.
const eid = async_hooks.executionAsyncId();
// Return the ID of the handle responsible for triggering the callback of the
// current execution scope to call.
const tid = async_hooks.triggerAsyncId();
// Create a new AsyncHook instance. All of these callbacks are optional.
const asyncHook =
async_hooks.createHook({ init, before, after, destroy, promiseResolve });
// Allow callbacks of this AsyncHook instance to call. This is not an implicit
// action after running the constructor, and must be explicitly run to begin
// executing callbacks.
asyncHook.enable();
// Disable listening for new asynchronous events.
asyncHook.disable();
//
// The following are the callbacks that can be passed to createHook().
//
// init() is called during object construction. The resource may not have
// completed construction when this callback runs. Therefore, all fields of the
// resource referenced by "asyncId" may not have been populated.
function init(asyncId, type, triggerAsyncId, resource) { }
// before() is called just before the resource's callback is called. It can be
// called 0-N times for handles (such as TCPWrap), and will be called exactly 1
// time for requests (such as FSReqCallback).
function before(asyncId) { }
// after() is called just after the resource's callback has finished.
function after(asyncId) { }
// destroy() is called when the resource is destroyed.
function destroy(asyncId) { }
// promiseResolve() is called only for promise resources, when the
// resolve() function passed to the Promise constructor is invoked
// (either directly or through other means of resolving a promise).
function promiseResolve(asyncId) { }
async_hooks.createHook(callbacks)#
callbacks<Object> The Hook Callbacks to registerinit<Function> Theinitcallback.before<Function> Thebeforecallback.after<Function> Theaftercallback.destroy<Function> Thedestroycallback.promiseResolve<Function> ThepromiseResolvecallback.
- Returns: <AsyncHook> Instance used for disabling and enabling hooks
Registers functions to be called for different lifetime events of each async operation.
The callbacks init()/before()/after()/destroy() are called for the
respective asynchronous event during a resource's lifetime.
All callbacks are optional. For example, if only resource cleanup needs to
be tracked, then only the destroy callback needs to be passed. The
specifics of all functions that can be passed to callbacks is in the
Hook Callbacks section.
import { createHook } from 'node:async_hooks';
const asyncHook = createHook({
init(asyncId, type, triggerAsyncId, resource) { },
destroy(asyncId) { }
});const async_hooks = require('node:async_hooks');
const asyncHook = async_hooks.createHook({
init(asyncId, type, triggerAsyncId, resource) { },
destroy(asyncId) { }
});
The callbacks will be inherited via the prototype chain:
class MyAsyncCallbacks {
init(asyncId, type, triggerAsyncId, resource) { }
destroy(asyncId) {}
}
class MyAddedCallbacks extends MyAsyncCallbacks {
before(asyncId) { }
after(asyncId) { }
}
const asyncHook = async_hooks.createHook(new MyAddedCallbacks());
Because promises are asynchronous resources whose lifecycle is tracked
via the async hooks mechanism, the init(), before(), after(), and
destroy() callbacks must not be async functions that return promises.
Error handling#
If any AsyncHook callbacks throw, the application will print the stack trace
and exit. The exit path does follow that of an uncaught exception, but
all 'uncaughtException' listeners are removed, thus forcing the process to
exit. The 'exit' callbacks will still be called unless the application is run
with --abort-on-uncaught-exception, in which case a stack trace will be
printed and the application exits, leaving a core file.
The reason for this error handling behavior is that these callbacks are running at potentially volatile points in an object's lifetime, for example during class construction and destruction. Because of this, it is deemed necessary to bring down the process quickly in order to prevent an unintentional abort in the future. This is subject to change in the future if a comprehensive analysis is performed to ensure an exception can follow the normal control flow without unintentional side effects.
Printing in AsyncHook callbacks#
Because printing to the console is an asynchronous operation, console.log()
will cause AsyncHook callbacks to be called. Using console.log() or
similar asynchronous operations inside an AsyncHook callback function will
cause an infinite recursion. An easy solution to this when debugging is to use a
synchronous logging operation such as fs.writeFileSync(file, msg, flag).
This will print to the file and will not invoke AsyncHook recursively because
it is synchronous.
import { writeFileSync } from 'node:fs';
import { format } from 'node:util';
function debug(...args) {
// Use a function like this one when debugging inside an AsyncHook callback
writeFileSync('log.out', `${format(...args)}\n`, { flag: 'a' });
}const fs = require('node:fs');
const util = require('node:util');
function debug(...args) {
// Use a function like this one when debugging inside an AsyncHook callback
fs.writeFileSync('log.out', `${util.format(...args)}\n`, { flag: 'a' });
}
If an asynchronous operation is needed for logging, it is possible to keep
track of what caused the asynchronous operation using the information
provided by AsyncHook itself. The logging should then be skipped when
it was the logging itself that caused the AsyncHook callback to be called. By
doing this, the otherwise infinite recursion is broken.
Class: AsyncHook#
The class AsyncHook exposes an interface for tracking lifetime events
of asynchronous operations.
asyncHook.enable()#
- Returns: <AsyncHook> A reference to
asyncHook.
Enable the callbacks for a given AsyncHook instance. If no callbacks are
provided, enabling is a no-op.
The AsyncHook instance is disabled by default. If the AsyncHook instance
should be enabled immediately after creation, the following pattern can be used.
import { createHook } from 'node:async_hooks';
const hook = createHook(callbacks).enable();const async_hooks = require('node:async_hooks');
const hook = async_hooks.createHook(callbacks).enable();
asyncHook.disable()#
- Returns: <AsyncHook> A reference to
asyncHook.
Disable the callbacks for a given AsyncHook instance from the global pool of
AsyncHook callbacks to be executed. Once a hook has been disabled it will not
be called again until enabled.
For API consistency disable() also returns the AsyncHook instance.
Hook callbacks#
Key events in the lifetime of asynchronous events have been categorized into four areas: instantiation, before/after the callback is called, and when the instance is destroyed.
init(asyncId, type, triggerAsyncId, resource)#
asyncId<number> A unique ID for the async resource.type<string> The type of the async resource.triggerAsyncId<number> The unique ID of the async resource in whose execution context this async resource was created.resource<Object> Reference to the resource representing the async operation, needs to be released during destroy.
Called when a class is constructed that has the possibility to emit an
asynchronous event. This does not mean the instance must call
before/after before destroy is called, only that the possibility
exists.
This behavior can be observed by doing something like opening a resource then closing it before the resource can be used. The following snippet demonstrates this.
import { createServer } from 'node:net';
createServer().listen(function() { this.close(); });
// OR
clearTimeout(setTimeout(() => {}, 10));require('node:net').createServer().listen(function() { this.close(); });
// OR
clearTimeout(setTimeout(() => {}, 10));
Every new resource is assigned an ID that is unique within the scope of the current Node.js instance.
type#
The type is a string identifying the type of resource that caused
init to be called. Generally, it will correspond to the name of the
resource's constructor.
Valid values are:
FSEVENTWRAP, FSREQCALLBACK, GETADDRINFOREQWRAP, GETNAMEINFOREQWRAP, HTTPINCOMINGMESSAGE,
HTTPCLIENTREQUEST, JSSTREAM, PIPECONNECTWRAP, PIPEWRAP, PROCESSWRAP, QUERYWRAP,
SHUTDOWNWRAP, SIGNALWRAP, STATWATCHER, TCPCONNECTWRAP, TCPSERVERWRAP, TCPWRAP,
TTYWRAP, UDPSENDWRAP, UDPWRAP, WRITEWRAP, ZLIB, SSLCONNECTION, PBKDF2REQUEST,
RANDOMBYTESREQUEST, TLSWRAP, Microtask, Timeout, Immediate, TickObject
These values can change in any Node.js release. Furthermore users of AsyncResource
likely provide other values.
There is also the PROMISE resource type, which is used to track Promise
instances and asynchronous work scheduled by them.
Users are able to define their own type when using the public embedder API.
It is possible to have type name collisions. Embedders are encouraged to use unique prefixes, such as the npm package name, to prevent collisions when listening to the hooks.
triggerAsyncId#
triggerAsyncId is the asyncId of the resource that caused (or "triggered")
the new resource to initialize and that caused init to call. This is different
from async_hooks.executionAsyncId() that only shows when a resource was
created, while triggerAsyncId shows why a resource was created.
The following is a simple demonstration of triggerAsyncId:
import { createHook, executionAsyncId } from 'node:async_hooks';
import { stdout } from 'node:process';
import net from 'node:net';
createHook({
init(asyncId, type, triggerAsyncId) {
const eid = executionAsyncId();
fs.writeSync(
stdout.fd,
`${type}(${asyncId}): trigger: ${triggerAsyncId} execution: ${eid}\n`);
}
}).enable();
net.createServer((conn) => {}).listen(8080);const { createHook, executionAsyncId } = require('node:async_hooks');
const { stdout } = require('node:process');
const net = require('node:net');
createHook({
init(asyncId, type, triggerAsyncId) {
const eid = executionAsyncId();
fs.writeSync(
stdout.fd,
`${type}(${asyncId}): trigger: ${triggerAsyncId} execution: ${eid}\n`);
}
}).enable();
net.createServer((conn) => {}).listen(8080);
Output when hitting the server with nc localhost 8080:
TCPSERVERWRAP(5): trigger: 1 execution: 1
TCPWRAP(7): trigger: 5 execution: 0
The TCPSERVERWRAP is the server which receives the connections.
The TCPWRAP is the new connection from the client. When a new
connection is made, the TCPWrap instance is immediately constructed. This
happens outside of any JavaScript stack. (An executionAsyncId() of 0 means
that it is being executed from C++ with no JavaScript stack above it.) With only
that information, it would be impossible to link resources together in
terms of what caused them to be created, so triggerAsyncId is given the task
of propagating what resource is responsible for the new resource's existence.
resource#
resource is an object that represents the actual async resource that has
been initialized. This can contain useful information that can vary based on
the value of type. For instance, for the GETADDRINFOREQWRAP resource type,
resource provides the host name used when looking up the IP address for the
host in net.Server.listen(). The API for accessing this information is
not supported, but using the Embedder API, users can provide
and document their own resource objects. For example, such a resource object
could contain the SQL query being executed.
In some cases the resource object is reused for performance reasons, it is
thus not safe to use it as a key in a WeakMap or add properties to it.
Asynchronous context example#
The following is an example with additional information about the calls to
init between the before and after calls, specifically what the
callback to listen() will look like. The output formatting is slightly more
elaborate to make calling context easier to see.
const async_hooks = require('node:async_hooks');
const fs = require('node:fs');
const net = require('node:net');
const { fd } = process.stdout;
let indent = 0;
async_hooks.createHook({
init(asyncId, type, triggerAsyncId) {
const eid = async_hooks.executionAsyncId();
const indentStr = ' '.repeat(indent);
fs.writeSync(
fd,
`${indentStr}${type}(${asyncId}):` +
` trigger: ${triggerAsyncId} execution: ${eid}\n`);
},
before(asyncId) {
const indentStr = ' '.repeat(indent);
fs.writeSync(fd, `${indentStr}before: ${asyncId}\n`);
indent += 2;
},
after(asyncId) {
indent -= 2;
const indentStr = ' '.repeat(indent);
fs.writeSync(fd, `${indentStr}after: ${asyncId}\n`);
},
destroy(asyncId) {
const indentStr = ' '.repeat(indent);
fs.writeSync(fd, `${indentStr}destroy: ${asyncId}\n`);
},
}).enable();
net.createServer(() => {}).listen(8080, () => {
// Let's wait 10ms before logging the server started.
setTimeout(() => {
console.log('>>>', async_hooks.executionAsyncId());
}, 10);
});
Output from only starting the server:
TCPSERVERWRAP(5): trigger: 1 execution: 1
TickObject(6): trigger: 5 execution: 1
before: 6
Timeout(7): trigger: 6 execution: 6
after: 6
destroy: 6
before: 7
>>> 7
TickObject(8): trigger: 7 execution: 7
after: 7
before: 8
after: 8
As illustrated in the example, executionAsyncId() and execution each specify
the value of the current execution context; which is delineated by calls to
before and after.
Only using execution to graph resource allocation results in the following:
root(1)
^
|
TickObject(6)
^
|
Timeout(7)
The TCPSERVERWRAP is not part of this graph, even though it was the reason for
console.log() being called. This is because binding to a port without a host
name is a synchronous operation, but to maintain a completely asynchronous
API the user's callback is placed in a process.nextTick(). Which is why
TickObject is present in the output and is a 'parent' for .listen()
callback.
The graph only shows when a resource was created, not why, so to track
the why use triggerAsyncId. Which can be represented with the following
graph:
bootstrap(1)
|
˅
TCPSERVERWRAP(5)
|
˅
TickObject(6)
|
˅
Timeout(7)
before(asyncId)#
asyncId<number>
When an asynchronous operation is initiated (such as a TCP server receiving a
new connection) or completes (such as writing data to disk) a callback is
called to notify the user. The before callback is called just before said
callback is executed. asyncId is the unique identifier assigned to the
resource about to execute the callback.
The before callback will be called 0 to N times. The before callback
will typically be called 0 times if the asynchronous operation was cancelled
or, for example, if no connections are received by a TCP server. Persistent
asynchronous resources like a TCP server will typically call the before
callback multiple times, while other operations like fs.open() will call
it only once.
after(asyncId)#
asyncId<number>
Called immediately after the callback specified in before is completed.
If an uncaught exception occurs during execution of the callback, then after
will run after the 'uncaughtException' event is emitted or a domain's
handler runs.
destroy(asyncId)#
asyncId<number>
Called after the resource corresponding to asyncId is destroyed. It is also
called asynchronously from the embedder API emitDestroy().
Some resources depend on garbage collection for cleanup, so if a reference is
made to the resource object passed to init it is possible that destroy
will never be called, causing a memory leak in the application. If the resource
does not depend on garbage collection, then this will not be an issue.
promiseResolve(asyncId)#
asyncId<number>
Called when the resolve function passed to the Promise constructor is
invoked (either directly or through other means of resolving a promise).
resolve() does not do any observable synchronous work.
The Promise is not necessarily fulfilled or rejected at this point if the
Promise was resolved by assuming the state of another Promise.
new Promise((resolve) => resolve(true)).then((a) => {});
calls the following callbacks:
init for PROMISE with id 5, trigger id: 1
promise resolve 5 # corresponds to resolve(true)
init for PROMISE with id 6, trigger id: 5 # the Promise returned by then()
before 6 # the then() callback is entered
promise resolve 6 # the then() callback resolves the promise by returning
after 6
async_hooks.executionAsyncResource()#
- Returns: <Object> The resource representing the current execution. Useful to store data within the resource.
Resource objects returned by executionAsyncResource() are most often internal
Node.js handle objects with undocumented APIs. Using any functions or properties
on the object is likely to crash your application and should be avoided.
Using executionAsyncResource() in the top-level execution context will
return an empty object as there is no handle or request object to use,
but having an object representing the top-level can be helpful.
import { open } from 'node:fs';
import { executionAsyncId, executionAsyncResource } from 'node:async_hooks';
console.log(executionAsyncId(), executionAsyncResource()); // 1 {}
open(new URL(import.meta.url), 'r', (err, fd) => {
console.log(executionAsyncId(), executionAsyncResource()); // 7 FSReqWrap
});const { open } = require('node:fs');
const { executionAsyncId, executionAsyncResource } = require('node:async_hooks');
console.log(executionAsyncId(), executionAsyncResource()); // 1 {}
open(__filename, 'r', (err, fd) => {
console.log(executionAsyncId(), executionAsyncResource()); // 7 FSReqWrap
});
This can be used to implement continuation local storage without the
use of a tracking Map to store the metadata:
import { createServer } from 'node:http';
import {
executionAsyncId,
executionAsyncResource,
createHook
} from 'async_hooks';
const sym = Symbol('state'); // Private symbol to avoid pollution
createHook({
init(asyncId, type, triggerAsyncId, resource) {
const cr = executionAsyncResource();
if (cr) {
resource[sym] = cr[sym];
}
}
}).enable();
const server = createServer((req, res) => {
executionAsyncResource()[sym] = { state: req.url };
setTimeout(function() {
res.end(JSON.stringify(executionAsyncResource()[sym]));
}, 100);
}).listen(3000);const { createServer } = require('node:http');
const {
executionAsyncId,
executionAsyncResource,
createHook
} = require('node:async_hooks');
const sym = Symbol('state'); // Private symbol to avoid pollution
createHook({
init(asyncId, type, triggerAsyncId, resource) {
const cr = executionAsyncResource();
if (cr) {
resource[sym] = cr[sym];
}
}
}).enable();
const server = createServer((req, res) => {
executionAsyncResource()[sym] = { state: req.url };
setTimeout(function() {
res.end(JSON.stringify(executionAsyncResource()[sym]));
}, 100);
}).listen(3000);
async_hooks.executionAsyncId()#
- Returns: <number> The
asyncIdof the current execution context. Useful to track when something calls.
import { executionAsyncId } from 'node:async_hooks';
console.log(executionAsyncId()); // 1 - bootstrap
fs.open(path, 'r', (err, fd) => {
console.log(executionAsyncId()); // 6 - open()
});const async_hooks = require('node:async_hooks');
console.log(async_hooks.executionAsyncId()); // 1 - bootstrap
fs.open(path, 'r', (err, fd) => {
console.log(async_hooks.executionAsyncId()); // 6 - open()
});
The ID returned from executionAsyncId() is related to execution timing, not
causality (which is covered by triggerAsyncId()):
const server = net.createServer((conn) => {
// Returns the ID of the server, not of the new connection, because the
// callback runs in the execution scope of the server's MakeCallback().
async_hooks.executionAsyncId();
}).listen(port, () => {
// Returns the ID of a TickObject (process.nextTick()) because all
// callbacks passed to .listen() are wrapped in a nextTick().
async_hooks.executionAsyncId();
});
Promise contexts may not get precise executionAsyncIds by default.
See the section on promise execution tracking.
async_hooks.triggerAsyncId()#
- Returns: <number> The ID of the resource responsible for calling the callback that is currently being executed.
const server = net.createServer((conn) => {
// The resource that caused (or triggered) this callback to be called
// was that of the new connection. Thus the return value of triggerAsyncId()
// is the asyncId of "conn".
async_hooks.triggerAsyncId();
}).listen(port, () => {
// Even though all callbacks passed to .listen() are wrapped in a nextTick()
// the callback itself exists because the call to the server's .listen()
// was made. So the return value would be the ID of the server.
async_hooks.triggerAsyncId();
});
Promise contexts may not get valid triggerAsyncIds by default. See
the section on promise execution tracking.
async_hooks.asyncWrapProviders#
- Returns: A map of provider types to the corresponding numeric id.
This map contains all the event types that might be emitted by the
async_hooks.init()event.
This feature suppresses the deprecated usage of process.binding('async_wrap').Providers.
See: DEP0111
Promise execution tracking#
By default, promise executions are not assigned asyncIds due to the relatively
expensive nature of the promise introspection API provided by
V8. This means that programs using promises or async/await will not get
correct execution and trigger ids for promise callback contexts by default.
import { executionAsyncId, triggerAsyncId } from 'node:async_hooks';
Promise.resolve(1729).then(() => {
console.log(`eid ${executionAsyncId()} tid ${triggerAsyncId()}`);
});
// produces:
// eid 1 tid 0const { executionAsyncId, triggerAsyncId } = require('node:async_hooks');
Promise.resolve(1729).then(() => {
console.log(`eid ${executionAsyncId()} tid ${triggerAsyncId()}`);
});
// produces:
// eid 1 tid 0
Observe that the then() callback claims to have executed in the context of the
outer scope even though there was an asynchronous hop involved. Also,
the triggerAsyncId value is 0, which means that we are missing context about
the resource that caused (triggered) the then() callback to be executed.
Installing async hooks via async_hooks.createHook enables promise execution
tracking:
import { createHook, executionAsyncId, triggerAsyncId } from 'node:async_hooks';
createHook({ init() {} }).enable(); // forces PromiseHooks to be enabled.
Promise.resolve(1729).then(() => {
console.log(`eid ${executionAsyncId()} tid ${triggerAsyncId()}`);
});
// produces:
// eid 7 tid 6const { createHook, executionAsyncId, triggerAsyncId } = require('node:async_hooks');
createHook({ init() {} }).enable(); // forces PromiseHooks to be enabled.
Promise.resolve(1729).then(() => {
console.log(`eid ${executionAsyncId()} tid ${triggerAsyncId()}`);
});
// produces:
// eid 7 tid 6
In this example, adding any actual hook function enabled the tracking of
promises. There are two promises in the example above; the promise created by
Promise.resolve() and the promise returned by the call to then(). In the
example above, the first promise got the asyncId 6 and the latter got
asyncId 7. During the execution of the then() callback, we are executing
in the context of promise with asyncId 7. This promise was triggered by
async resource 6.
Another subtlety with promises is that before and after callbacks are run
only on chained promises. That means promises not created by then()/catch()
will not have the before and after callbacks fired on them. For more details
see the details of the V8 PromiseHooks API.
JavaScript embedder API#
Library developers that handle their own asynchronous resources performing tasks
like I/O, connection pooling, or managing callback queues may use the
AsyncResource JavaScript API so that all the appropriate callbacks are called.
Class: AsyncResource#
The documentation for this class has moved AsyncResource.
Class: AsyncLocalStorage#
The documentation for this class has moved AsyncLocalStorage.
Buffer#
Source Code: lib/buffer.js
Buffer objects are used to represent a fixed-length sequence of bytes. Many
Node.js APIs support Buffers.
The Buffer class is a subclass of JavaScript's Uint8Array class and
extends it with methods that cover additional use cases. Node.js APIs accept
plain Uint8Arrays wherever Buffers are supported as well.
While the Buffer class is available within the global scope, it is still
recommended to explicitly reference it via an import or require statement.
import { Buffer } from 'node:buffer';
// Creates a zero-filled Buffer of length 10.
const buf1 = Buffer.alloc(10);
// Creates a Buffer of length 10,
// filled with bytes which all have the value `1`.
const buf2 = Buffer.alloc(10, 1);
// Creates an uninitialized buffer of length 10.
// This is faster than calling Buffer.alloc() but the returned
// Buffer instance might contain old data that needs to be
// overwritten using fill(), write(), or other functions that fill the Buffer's
// contents.
const buf3 = Buffer.allocUnsafe(10);
// Creates a Buffer containing the bytes [1, 2, 3].
const buf4 = Buffer.from([1, 2, 3]);
// Creates a Buffer containing the bytes [1, 1, 1, 1] – the entries
// are all truncated using `(value & 255)` to fit into the range 0–255.
const buf5 = Buffer.from([257, 257.5, -255, '1']);
// Creates a Buffer containing the UTF-8-encoded bytes for the string 'tést':
// [0x74, 0xc3, 0xa9, 0x73, 0x74] (in hexadecimal notation)
// [116, 195, 169, 115, 116] (in decimal notation)
const buf6 = Buffer.from('tést');
// Creates a Buffer containing the Latin-1 bytes [0x74, 0xe9, 0x73, 0x74].
const buf7 = Buffer.from('tést', 'latin1');const { Buffer } = require('node:buffer');
// Creates a zero-filled Buffer of length 10.
const buf1 = Buffer.alloc(10);
// Creates a Buffer of length 10,
// filled with bytes which all have the value `1`.
const buf2 = Buffer.alloc(10, 1);
// Creates an uninitialized buffer of length 10.
// This is faster than calling Buffer.alloc() but the returned
// Buffer instance might contain old data that needs to be
// overwritten using fill(), write(), or other functions that fill the Buffer's
// contents.
const buf3 = Buffer.allocUnsafe(10);
// Creates a Buffer containing the bytes [1, 2, 3].
const buf4 = Buffer.from([1, 2, 3]);
// Creates a Buffer containing the bytes [1, 1, 1, 1] – the entries
// are all truncated using `(value & 255)` to fit into the range 0–255.
const buf5 = Buffer.from([257, 257.5, -255, '1']);
// Creates a Buffer containing the UTF-8-encoded bytes for the string 'tést':
// [0x74, 0xc3, 0xa9, 0x73, 0x74] (in hexadecimal notation)
// [116, 195, 169, 115, 116] (in decimal notation)
const buf6 = Buffer.from('tést');
// Creates a Buffer containing the Latin-1 bytes [0x74, 0xe9, 0x73, 0x74].
const buf7 = Buffer.from('tést', 'latin1');
Buffers and character encodings#
When converting between Buffers and strings, a character encoding may be
specified. If no character encoding is specified, UTF-8 will be used as the
default.
import { Buffer } from 'node:buffer';
const buf = Buffer.from('hello world', 'utf8');
console.log(buf.toString('hex'));
// Prints: 68656c6c6f20776f726c64
console.log(buf.toString('base64'));
// Prints: aGVsbG8gd29ybGQ=
console.log(Buffer.from('fhqwhgads', 'utf8'));
// Prints: <Buffer 66 68 71 77 68 67 61 64 73>
console.log(Buffer.from('fhqwhgads', 'utf16le'));
// Prints: <Buffer 66 00 68 00 71 00 77 00 68 00 67 00 61 00 64 00 73 00>const { Buffer } = require('node:buffer');
const buf = Buffer.from('hello world', 'utf8');
console.log(buf.toString('hex'));
// Prints: 68656c6c6f20776f726c64
console.log(buf.toString('base64'));
// Prints: aGVsbG8gd29ybGQ=
console.log(Buffer.from('fhqwhgads', 'utf8'));
// Prints: <Buffer 66 68 71 77 68 67 61 64 73>
console.log(Buffer.from('fhqwhgads', 'utf16le'));
// Prints: <Buffer 66 00 68 00 71 00 77 00 68 00 67 00 61 00 64 00 73 00>
Node.js buffers accept all case variations of encoding strings that they
receive. For example, UTF-8 can be specified as 'utf8', 'UTF8', or 'uTf8'.
The character encodings currently supported by Node.js are the following:
-
'utf8'(alias:'utf-8'): Multi-byte encoded Unicode characters. Many web pages and other document formats use UTF-8. This is the default character encoding. When decoding aBufferinto a string that does not exclusively contain valid UTF-8 data, the Unicode replacement characterU+FFFD� will be used to represent those errors. -
'utf16le'(alias:'utf-16le'): Multi-byte encoded Unicode characters. Unlike'utf8', each character in the string will be encoded using either 2 or 4 bytes. Node.js only supports the little-endian variant of UTF-16. -
'latin1': Latin-1 stands for ISO-8859-1. This character encoding only supports the Unicode characters fromU+0000toU+00FF. Each character is encoded using a single byte. Characters that do not fit into that range are truncated and will be mapped to characters in that range.
Converting a Buffer into a string using one of the above is referred to as
decoding, and converting a string into a Buffer is referred to as encoding.
Node.js also supports the following binary-to-text encodings. For
binary-to-text encodings, the naming convention is reversed: Converting a
Buffer into a string is typically referred to as encoding, and converting a
string into a Buffer as decoding.
-
'base64': Base64 encoding. When creating aBufferfrom a string, this encoding will also correctly accept "URL and Filename Safe Alphabet" as specified in RFC 4648, Section 5. Whitespace characters such as spaces, tabs, and new lines contained within the base64-encoded string are ignored. -
'base64url': base64url encoding as specified in RFC 4648, Section 5. When creating aBufferfrom a string, this encoding will also correctly accept regular base64-encoded strings. When encoding aBufferto a string, this encoding will omit padding. -
'hex': Encode each byte as two hexadecimal characters. Data truncation may occur when decoding strings that do not exclusively consist of an even number of hexadecimal characters. See below for an example.
The following legacy character encodings are also supported:
-
'ascii': For 7-bit ASCII data only. When encoding a string into aBuffer, this is equivalent to using'latin1'. When decoding aBufferinto a string, using this encoding will additionally unset the highest bit of each byte before decoding as'latin1'. Generally, there should be no reason to use this encoding, as'utf8'(or, if the data is known to always be ASCII-only,'latin1') will be a better choice when encoding or decoding ASCII-only text. It is only provided for legacy compatibility. -
'binary': Alias for'latin1'. See binary strings for more background on this topic. The name of this encoding can be very misleading, as all of the encodings listed here convert between strings and binary data. For converting between strings andBuffers, typically'utf8'is the right choice. -
'ucs2','ucs-2': Aliases of'utf16le'. UCS-2 used to refer to a variant of UTF-16 that did not support characters that had code points larger than U+FFFF. In Node.js, these code points are always supported.
import { Buffer } from 'node:buffer';
Buffer.from('1ag123', 'hex');
// Prints <Buffer 1a>, data truncated when first non-hexadecimal value
// ('g') encountered.
Buffer.from('1a7', 'hex');
// Prints <Buffer 1a>, data truncated when data ends in single digit ('7').
Buffer.from('1634', 'hex');
// Prints <Buffer 16 34>, all data represented.const { Buffer } = require('node:buffer');
Buffer.from('1ag123', 'hex');
// Prints <Buffer 1a>, data truncated when first non-hexadecimal value
// ('g') encountered.
Buffer.from('1a7', 'hex');
// Prints <Buffer 1a>, data truncated when data ends in single digit ('7').
Buffer.from('1634', 'hex');
// Prints <Buffer 16 34>, all data represented.
Modern Web browsers follow the WHATWG Encoding Standard which aliases
both 'latin1' and 'ISO-8859-1' to 'win-1252'. This means that while doing
something like http.get(), if the returned charset is one of those listed in
the WHATWG specification it is possible that the server actually returned
'win-1252'-encoded data, and using 'latin1' encoding may incorrectly decode
the characters.
Buffers and TypedArrays#
Buffer instances are also JavaScript Uint8Array and TypedArray
instances. All TypedArray methods are available on Buffers. There are,
however, subtle incompatibilities between the Buffer API and the
TypedArray API.
In particular:
- While
TypedArray.prototype.slice()creates a copy of part of theTypedArray,Buffer.prototype.slice()creates a view over the existingBufferwithout copying. This behavior can be surprising, and only exists for legacy compatibility.TypedArray.prototype.subarray()can be used to achieve the behavior ofBuffer.prototype.slice()on bothBuffers and otherTypedArrays and should be preferred. buf.toString()is incompatible with itsTypedArrayequivalent.- A number of methods, e.g.
buf.indexOf(), support additional arguments.
There are two ways to create new TypedArray instances from a Buffer:
- Passing a
Bufferto aTypedArrayconstructor will copy theBuffers contents, interpreted as an array of integers, and not as a byte sequence of the target type.
import { Buffer } from 'node:buffer';
const buf = Buffer.from([1, 2, 3, 4]);
const uint32array = new Uint32Array(buf);
console.log(uint32array);
// Prints: Uint32Array(4) [ 1, 2, 3, 4 ]const { Buffer } = require('node:buffer');
const buf = Buffer.from([1, 2, 3, 4]);
const uint32array = new Uint32Array(buf);
console.log(uint32array);
// Prints: Uint32Array(4) [ 1, 2, 3, 4 ]
- Passing the
Buffers underlyingArrayBufferwill create aTypedArraythat shares its memory with theBuffer.
import { Buffer } from 'node:buffer';
const buf = Buffer.from('hello', 'utf16le');
const uint16array = new Uint16Array(
buf.buffer,
buf.byteOffset,
buf.length / Uint16Array.BYTES_PER_ELEMENT);
console.log(uint16array);
// Prints: Uint16Array(5) [ 104, 101, 108, 108, 111 ]const { Buffer } = require('node:buffer');
const buf = Buffer.from('hello', 'utf16le');
const uint16array = new Uint16Array(
buf.buffer,
buf.byteOffset,
buf.length / Uint16Array.BYTES_PER_ELEMENT);
console.log(uint16array);
// Prints: Uint16Array(5) [ 104, 101, 108, 108, 111 ]
It is possible to create a new Buffer that shares the same allocated
memory as a TypedArray instance by using the TypedArray object's
.buffer property in the same way. Buffer.from()
behaves like new Uint8Array() in this context.
import { Buffer } from 'node:buffer';
const arr = new Uint16Array(2);
arr[0] = 5000;
arr[1] = 4000;
// Copies the contents of `arr`.
const buf1 = Buffer.from(arr);
// Shares memory with `arr`.
const buf2 = Buffer.from(arr.buffer);
console.log(buf1);
// Prints: <Buffer 88 a0>
console.log(buf2);
// Prints: <Buffer 88 13 a0 0f>
arr[1] = 6000;
console.log(buf1);
// Prints: <Buffer 88 a0>
console.log(buf2);
// Prints: <Buffer 88 13 70 17>const { Buffer } = require('node:buffer');
const arr = new Uint16Array(2);
arr[0] = 5000;
arr[1] = 4000;
// Copies the contents of `arr`.
const buf1 = Buffer.from(arr);
// Shares memory with `arr`.
const buf2 = Buffer.from(arr.buffer);
console.log(buf1);
// Prints: <Buffer 88 a0>
console.log(buf2);
// Prints: <Buffer 88 13 a0 0f>
arr[1] = 6000;
console.log(buf1);
// Prints: <Buffer 88 a0>
console.log(buf2);
// Prints: <Buffer 88 13 70 17>
When creating a Buffer using a TypedArray's .buffer, it is
possible to use only a portion of the underlying ArrayBuffer by passing in
byteOffset and length parameters.
import { Buffer } from 'node:buffer';
const arr = new Uint16Array(20);
const buf = Buffer.from(arr.buffer, 0, 16);
console.log(buf.length);
// Prints: 16const { Buffer } = require('node:buffer');
const arr = new Uint16Array(20);
const buf = Buffer.from(arr.buffer, 0, 16);
console.log(buf.length);
// Prints: 16
The Buffer.from() and TypedArray.from() have different signatures and
implementations. Specifically, the TypedArray variants accept a second
argument that is a mapping function that is invoked on every element of the
typed array:
TypedArray.from(source[, mapFn[, thisArg]])
The Buffer.from() method, however, does not support the use of a mapping
function:
Buffers and iteration#
Buffer instances can be iterated over using for..of syntax:
import { Buffer } from 'node:buffer';
const buf = Buffer.from([1, 2, 3]);
for (const b of buf) {
console.log(b);
}
// Prints:
// 1
// 2
// 3const { Buffer } = require('node:buffer');
const buf = Buffer.from([1, 2, 3]);
for (const b of buf) {
console.log(b);
}
// Prints:
// 1
// 2
// 3
Additionally, the buf.values(), buf.keys(), and
buf.entries() methods can be used to create iterators.
Class: Blob#
A Blob encapsulates immutable, raw data that can be safely shared across
multiple worker threads.
new buffer.Blob([sources[, options]])#
sources<string[]> | <ArrayBuffer[]> | <TypedArray[]> | <DataView[]> | <Blob[]> An array of string, <ArrayBuffer>, <TypedArray>, <DataView>, or <Blob> objects, or any mix of such objects, that will be stored within theBlob.options<Object>endings<string> One of either'transparent'or'native'. When set to'native', line endings in string source parts will be converted to the platform native line-ending as specified byrequire('node:os').EOL.type<string> The Blob content-type. The intent is fortypeto convey the MIME media type of the data, however no validation of the type format is performed.
Creates a new Blob object containing a concatenation of the given sources.
<ArrayBuffer>, <TypedArray>, <DataView>, and <Buffer> sources are copied into the 'Blob' and can therefore be safely modified after the 'Blob' is created.
String sources are encoded as UTF-8 byte sequences and copied into the Blob. Unmatched surrogate pairs within each string part will be replaced by Unicode U+FFFD replacement characters.
blob.arrayBuffer()#
- Returns: <Promise>
Returns a promise that fulfills with an <ArrayBuffer> containing a copy of
the Blob data.
blob.size#
The total size of the Blob in bytes.
blob.slice([start[, end[, type]]])#
start<number> The starting index.end<number> The ending index.type<string> The content-type for the newBlob
Creates and returns a new Blob containing a subset of this Blob objects
data. The original Blob is not altered.
blob.stream()#
- Returns: <ReadableStream>
Returns a new ReadableStream that allows the content of the Blob to be read.
blob.text()#
- Returns: <Promise>
Returns a promise that fulfills with the contents of the Blob decoded as a
UTF-8 string.
blob.type#
- Type: <string>
The content-type of the Blob.
Blob objects and MessageChannel#
Once a <Blob> object is created, it can be sent via MessagePort to multiple
destinations without transferring or immediately copying the data. The data
contained by the Blob is copied only when the arrayBuffer() or text()
methods are called.
import { Blob, Buffer } from 'node:buffer';
import { setTimeout as delay } from 'node:timers/promises';
const blob = new Blob(['hello there']);
const mc1 = new MessageChannel();
const mc2 = new MessageChannel();
mc1.port1.onmessage = async ({ data }) => {
console.log(await data.arrayBuffer());
mc1.port1.close();
};
mc2.port1.onmessage = async ({ data }) => {
await delay(1000);
console.log(await data.arrayBuffer());
mc2.port1.close();
};
mc1.port2.postMessage(blob);
mc2.port2.postMessage(blob);
// The Blob is still usable after posting.
blob.text().then(console.log);const { Blob, Buffer } = require('node:buffer');
const { setTimeout: delay } = require('node:timers/promises');
const blob = new Blob(['hello there']);
const mc1 = new MessageChannel();
const mc2 = new MessageChannel();
mc1.port1.onmessage = async ({ data }) => {
console.log(await data.arrayBuffer());
mc1.port1.close();
};
mc2.port1.onmessage = async ({ data }) => {
await delay(1000);
console.log(await data.arrayBuffer());
mc2.port1.close();
};
mc1.port2.postMessage(blob);
mc2.port2.postMessage(blob);
// The Blob is still usable after posting.
blob.text().then(console.log);
Class: Buffer#
The Buffer class is a global type for dealing with binary data directly.
It can be constructed in a variety of ways.
Static method: Buffer.alloc(size[, fill[, encoding]])#
size<integer> The desired length of the newBuffer.fill<string> | <Buffer> | <Uint8Array> | <integer> A value to pre-fill the newBufferwith. Default:0.encoding<string> Iffillis a string, this is its encoding. Default:'utf8'.
Allocates a new Buffer of size bytes. If fill is undefined, the
Buffer will be zero-filled.
import { Buffer } from 'node:buffer';
const buf = Buffer.alloc(5);
console.log(buf);
// Prints: <Buffer 00 00 00 00 00>const { Buffer } = require('node:buffer');
const buf = Buffer.alloc(5);
console.log(buf);
// Prints: <Buffer 00 00 00 00 00>
If size is larger than
buffer.constants.MAX_LENGTH or smaller than 0, ERR_INVALID_ARG_VALUE
is thrown.
If fill is specified, the allocated Buffer will be initialized by calling
buf.fill(fill).
import { Buffer } from 'node:buffer';
const buf = Buffer.alloc(5, 'a');
console.log(buf);
// Prints: <Buffer 61 61 61 61 61>const { Buffer } = require('node:buffer');
const buf = Buffer.alloc(5, 'a');
console.log(buf);
// Prints: <Buffer 61 61 61 61 61>
If both fill and encoding are specified, the allocated Buffer will be
initialized by calling buf.fill(fill, encoding).
import { Buffer } from 'node:buffer';
const buf = Buffer.alloc(11, 'aGVsbG8gd29ybGQ=', 'base64');
console.log(buf);
// Prints: <Buffer 68 65 6c 6c 6f 20 77 6f 72 6c 64>const { Buffer } = require('node:buffer');
const buf = Buffer.alloc(11, 'aGVsbG8gd29ybGQ=', 'base64');
console.log(buf);
// Prints: <Buffer 68 65 6c 6c 6f 20 77 6f 72 6c 64>
Calling Buffer.alloc() can be measurably slower than the alternative
Buffer.allocUnsafe() but ensures that the newly created Buffer instance
contents will never contain sensitive data from previous allocations, including
data that might not have been allocated for Buffers.
A TypeError will be thrown if size is not a number.
Static method: Buffer.allocUnsafe(size)#
size<integer> The desired length of the newBuffer.
Allocates a new Buffer of size bytes. If size is larger than
buffer.constants.MAX_LENGTH or smaller than 0, ERR_INVALID_ARG_VALUE
is thrown.
The underlying memory for Buffer instances created in this way is not
initialized. The contents of the newly created Buffer are unknown and
may contain sensitive data. Use Buffer.alloc() instead to initialize
Buffer instances with zeroes.
import { Buffer } from 'node:buffer';
const buf = Buffer.allocUnsafe(10);
console.log(buf);
// Prints (contents may vary): <Buffer a0 8b 28 3f 01 00 00 00 50 32>
buf.fill(0);
console.log(buf);
// Prints: <Buffer 00 00 00 00 00 00 00 00 00 00>const { Buffer } = require('node:buffer');
const buf = Buffer.allocUnsafe(10);
console.log(buf);
// Prints (contents may vary): <Buffer a0 8b 28 3f 01 00 00 00 50 32>
buf.fill(0);
console.log(buf);
// Prints: <Buffer 00 00 00 00 00 00 00 00 00 00>
A TypeError will be thrown if size is not a number.
The Buffer module pre-allocates an internal Buffer instance of
size Buffer.poolSize that is used as a pool for the fast allocation of new
Buffer instances created using Buffer.allocUnsafe(),
Buffer.from(array), Buffer.concat(), and the deprecated
new Buffer(size) constructor only when size is less than or equal
to Buffer.poolSize >> 1 (floor of Buffer.poolSize divided by two).
Use of this pre-allocated internal memory pool is a key difference between
calling Buffer.alloc(size, fill) vs. Buffer.allocUnsafe(size).fill(fill).
Specifically, Buffer.alloc(size, fill) will never use the internal Buffer
pool, while Buffer.allocUnsafe(size).fill(fill) will use the internal
Buffer pool if size is less than or equal to half Buffer.poolSize. The
difference is subtle but can be important when an application requires the
additional performance that Buffer.allocUnsafe() provides.
Static method: Buffer.allocUnsafeSlow(size)#
size<integer> The desired length of the newBuffer.
Allocates a new Buffer of size bytes. If size is larger than
buffer.constants.MAX_LENGTH or smaller than 0, ERR_INVALID_ARG_VALUE
is thrown. A zero-length Buffer is created if size is 0.
The underlying memory for Buffer instances created in this way is not
initialized. The contents of the newly created Buffer are unknown and
may contain sensitive data. Use buf.fill(0) to initialize
such Buffer instances with zeroes.
When using Buffer.allocUnsafe() to allocate new Buffer instances,
allocations under 4 KiB are sliced from a single pre-allocated Buffer. This
allows applications to avoid the garbage collection overhead of creating many
individually allocated Buffer instances. This approach improves both
performance and memory usage by eliminating the need to track and clean up as
many individual ArrayBuffer objects.
However, in the case where a developer may need to retain a small chunk of
memory from a pool for an indeterminate amount of time, it may be appropriate
to create an un-pooled Buffer instance using Buffer.allocUnsafeSlow() and
then copying out the relevant bits.
import { Buffer } from 'node:buffer';
// Need to keep around a few small chunks of memory.
const store = [];
socket.on('readable', () => {
let data;
while (null !== (data = readable.read())) {
// Allocate for retained data.
const sb = Buffer.allocUnsafeSlow(10);
// Copy the data into the new allocation.
data.copy(sb, 0, 0, 10);
store.push(sb);
}
});const { Buffer } = require('node:buffer');
// Need to keep around a few small chunks of memory.
const store = [];
socket.on('readable', () => {
let data;
while (null !== (data = readable.read())) {
// Allocate for retained data.
const sb = Buffer.allocUnsafeSlow(10);
// Copy the data into the new allocation.
data.copy(sb, 0, 0, 10);
store.push(sb);
}
});
A TypeError will be thrown if size is not a number.
Static method: Buffer.byteLength(string[, encoding])#
string<string> | <Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> | <SharedArrayBuffer> A value to calculate the length of.encoding<string> Ifstringis a string, this is its encoding. Default:'utf8'.- Returns: <integer> The number of bytes contained within
string.
Returns the byte length of a string when encoded using encoding.
This is not the same as String.prototype.length, which does not account
for the encoding that is used to convert the string into bytes.
For 'base64', 'base64url', and 'hex', this function assumes valid input.
For strings that contain non-base64/hex-encoded data (e.g. whitespace), the
return value might be greater than the length of a Buffer created from the
string.
import { Buffer } from 'node:buffer';
const str = '\u00bd + \u00bc = \u00be';
console.log(`${str}: ${str.length} characters, ` +
`${Buffer.byteLength(str, 'utf8')} bytes`);
// Prints: ½ + ¼ = ¾: 9 characters, 12 bytesconst { Buffer } = require('node:buffer');
const str = '\u00bd + \u00bc = \u00be';
console.log(`${str}: ${str.length} characters, ` +
`${Buffer.byteLength(str, 'utf8')} bytes`);
// Prints: ½ + ¼ = ¾: 9 characters, 12 bytes
When string is a Buffer/DataView/TypedArray/ArrayBuffer/
SharedArrayBuffer, the byte length as reported by .byteLength
is returned.
Static method: Buffer.compare(buf1, buf2)#
buf1<Buffer> | <Uint8Array>buf2<Buffer> | <Uint8Array>- Returns: <integer> Either
-1,0, or1, depending on the result of the comparison. Seebuf.compare()for details.
Compares buf1 to buf2, typically for the purpose of sorting arrays of
Buffer instances. This is equivalent to calling
buf1.compare(buf2).
import { Buffer } from 'node:buffer';
const buf1 = Buffer.from('1234');
const buf2 = Buffer.from('0123');
const arr = [buf1, buf2];
console.log(arr.sort(Buffer.compare));
// Prints: [ <Buffer 30 31 32 33>, <Buffer 31 32 33 34> ]
// (This result is equal to: [buf2, buf1].)const { Buffer } = require('node:buffer');
const buf1 = Buffer.from('1234');
const buf2 = Buffer.from('0123');
const arr = [buf1, buf2];
console.log(arr.sort(Buffer.compare));
// Prints: [ <Buffer 30 31 32 33>, <Buffer 31 32 33 34> ]
// (This result is equal to: [buf2, buf1].)
Static method: Buffer.concat(list[, totalLength])#
list<Buffer[]> | <Uint8Array[]> List ofBufferorUint8Arrayinstances to concatenate.totalLength<integer> Total length of theBufferinstances inlistwhen concatenated.- Returns: <Buffer>
Returns a new Buffer which is the result of concatenating all the Buffer
instances in the list together.
If the list has no items, or if the totalLength is 0, then a new zero-length
Buffer is returned.
If totalLength is not provided, it is calculated from the Buffer instances
in list by adding their lengths.
If totalLength is provided, it is coerced to an unsigned integer. If the
combined length of the Buffers in list exceeds totalLength, the result is
truncated to totalLength.
import { Buffer } from 'node:buffer';
// Create a single `Buffer` from a list of three `Buffer` instances.
const buf1 = Buffer.alloc(10);
const buf2 = Buffer.alloc(14);
const buf3 = Buffer.alloc(18);
const totalLength = buf1.length + buf2.length + buf3.length;
console.log(totalLength);
// Prints: 42
const bufA = Buffer.concat([buf1, buf2, buf3], totalLength);
console.log(bufA);
// Prints: <Buffer 00 00 00 00 ...>
console.log(bufA.length);
// Prints: 42const { Buffer } = require('node:buffer');
// Create a single `Buffer` from a list of three `Buffer` instances.
const buf1 = Buffer.alloc(10);
const buf2 = Buffer.alloc(14);
const buf3 = Buffer.alloc(18);
const totalLength = buf1.length + buf2.length + buf3.length;
console.log(totalLength);
// Prints: 42
const bufA = Buffer.concat([buf1, buf2, buf3], totalLength);
console.log(bufA);
// Prints: <Buffer 00 00 00 00 ...>
console.log(bufA.length);
// Prints: 42
Buffer.concat() may also use the internal Buffer pool like
Buffer.allocUnsafe() does.
Static method: Buffer.from(array)#
array<integer[]>
Allocates a new Buffer using an array of bytes in the range 0 – 255.
Array entries outside that range will be truncated to fit into it.
import { Buffer } from 'node:buffer';
// Creates a new Buffer containing the UTF-8 bytes of the string 'buffer'.
const buf = Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]);const { Buffer } = require('node:buffer');
// Creates a new Buffer containing the UTF-8 bytes of the string 'buffer'.
const buf = Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]);
A TypeError will be thrown if array is not an Array or another type
appropriate for Buffer.from() variants.
Buffer.from(array) and Buffer.from(string) may also use the internal
Buffer pool like Buffer.allocUnsafe() does.
Static method: Buffer.from(arrayBuffer[, byteOffset[, length]])#
arrayBuffer<ArrayBuffer> | <SharedArrayBuffer> AnArrayBuffer,SharedArrayBuffer, for example the.bufferproperty of aTypedArray.byteOffset<integer> Index of first byte to expose. Default:0.length<integer> Number of bytes to expose. Default:arrayBuffer.byteLength - byteOffset.
This creates a view of the ArrayBuffer without copying the underlying
memory. For example, when passed a reference to the .buffer property of a
TypedArray instance, the newly created Buffer will share the same
allocated memory as the TypedArray's underlying ArrayBuffer.
import { Buffer } from 'node:buffer';
const arr = new Uint16Array(2);
arr[0] = 5000;
arr[1] = 4000;
// Shares memory with `arr`.
const buf = Buffer.from(arr.buffer);
console.log(buf);
// Prints: <Buffer 88 13 a0 0f>
// Changing the original Uint16Array changes the Buffer also.
arr[1] = 6000;
console.log(buf);
// Prints: <Buffer 88 13 70 17>const { Buffer } = require('node:buffer');
const arr = new Uint16Array(2);
arr[0] = 5000;
arr[1] = 4000;
// Shares memory with `arr`.
const buf = Buffer.from(arr.buffer);
console.log(buf);
// Prints: <Buffer 88 13 a0 0f>
// Changing the original Uint16Array changes the Buffer also.
arr[1] = 6000;
console.log(buf);
// Prints: <Buffer 88 13 70 17>
The optional byteOffset and length arguments specify a memory range within
the arrayBuffer that will be shared by the Buffer.
import { Buffer } from 'node:buffer';
const ab = new ArrayBuffer(10);
const buf = Buffer.from(ab, 0, 2);
console.log(buf.length);
// Prints: 2const { Buffer } = require('node:buffer');
const ab = new ArrayBuffer(10);
const buf = Buffer.from(ab, 0, 2);
console.log(buf.length);
// Prints: 2
A TypeError will be thrown if arrayBuffer is not an ArrayBuffer or a
SharedArrayBuffer or another type appropriate for Buffer.from()
variants.
It is important to remember that a backing ArrayBuffer can cover a range
of memory that extends beyond the bounds of a TypedArray view. A new
Buffer created using the buffer property of a TypedArray may extend
beyond the range of the TypedArray:
import { Buffer } from 'node:buffer';
const arrA = Uint8Array.from([0x63, 0x64, 0x65, 0x66]); // 4 elements
const arrB = new Uint8Array(arrA.buffer, 1, 2); // 2 elements
console.log(arrA.buffer === arrB.buffer); // true
const buf = Buffer.from(arrB.buffer);
console.log(buf);
// Prints: <Buffer 63 64 65 66>const { Buffer } = require('node:buffer');
const arrA = Uint8Array.from([0x63, 0x64, 0x65, 0x66]); // 4 elements
const arrB = new Uint8Array(arrA.buffer, 1, 2); // 2 elements
console.log(arrA.buffer === arrB.buffer); // true
const buf = Buffer.from(arrB.buffer);
console.log(buf);
// Prints: <Buffer 63 64 65 66>
Static method: Buffer.from(buffer)#
buffer<Buffer> | <Uint8Array> An existingBufferorUint8Arrayfrom which to copy data.
Copies the passed buffer data onto a new Buffer instance.
import { Buffer } from 'node:buffer';
const buf1 = Buffer.from('buffer');
const buf2 = Buffer.from(buf1);
buf1[0] = 0x61;
console.log(buf1.toString());
// Prints: auffer
console.log(buf2.toString());
// Prints: bufferconst { Buffer } = require('node:buffer');
const buf1 = Buffer.from('buffer');
const buf2 = Buffer.from(buf1);
buf1[0] = 0x61;
console.log(buf1.toString());
// Prints: auffer
console.log(buf2.toString());
// Prints: buffer
A TypeError will be thrown if buffer is not a Buffer or another type
appropriate for Buffer.from() variants.
Static method: Buffer.from(object[, offsetOrEncoding[, length]])#
object<Object> An object supportingSymbol.toPrimitiveorvalueOf().offsetOrEncoding<integer> | <string> A byte-offset or encoding.length<integer> A length.
For objects whose valueOf() function returns a value not strictly equal to
object, returns Buffer.from(object.valueOf(), offsetOrEncoding, length).
import { Buffer } from 'node:buffer';
const buf = Buffer.from(new String('this is a test'));
// Prints: <Buffer 74 68 69 73 20 69 73 20 61 20 74 65 73 74>const { Buffer } = require('node:buffer');
const buf = Buffer.from(new String('this is a test'));
// Prints: <Buffer 74 68 69 73 20 69 73 20 61 20 74 65 73 74>
For objects that support Symbol.toPrimitive, returns
Buffer.from(object[Symbol.toPrimitive]('string'), offsetOrEncoding).
import { Buffer } from 'node:buffer';
class Foo {
[Symbol.toPrimitive]() {
return 'this is a test';
}
}
const buf = Buffer.from(new Foo(), 'utf8');
// Prints: <Buffer 74 68 69 73 20 69 73 20 61 20 74 65 73 74>const { Buffer } = require('node:buffer');
class Foo {
[Symbol.toPrimitive]() {
return 'this is a test';
}
}
const buf = Buffer.from(new Foo(), 'utf8');
// Prints: <Buffer 74 68 69 73 20 69 73 20 61 20 74 65 73 74>
A TypeError will be thrown if object does not have the mentioned methods or
is not of another type appropriate for Buffer.from() variants.
Static method: Buffer.from(string[, encoding])#
Creates a new Buffer containing string. The encoding parameter identifies
the character encoding to be used when converting string into bytes.
import { Buffer } from 'node:buffer';
const buf1 = Buffer.from('this is a tést');
const buf2 = Buffer.from('7468697320697320612074c3a97374', 'hex');
console.log(buf1.toString());
// Prints: this is a tést
console.log(buf2.toString());
// Prints: this is a tést
console.log(buf1.toString('latin1'));
// Prints: this is a téstconst { Buffer } = require('node:buffer');
const buf1 = Buffer.from('this is a tést');
const buf2 = Buffer.from('7468697320697320612074c3a97374', 'hex');
console.log(buf1.toString());
// Prints: this is a tést
console.log(buf2.toString());
// Prints: this is a tést
console.log(buf1.toString('latin1'));
// Prints: this is a tést
A TypeError will be thrown if string is not a string or another type
appropriate for Buffer.from() variants.
Static method: Buffer.isBuffer(obj)#
Returns true if obj is a Buffer, false otherwise.
import { Buffer } from 'node:buffer';
Buffer.isBuffer(Buffer.alloc(10)); // true
Buffer.isBuffer(Buffer.from('foo')); // true
Buffer.isBuffer('a string'); // false
Buffer.isBuffer([]); // false
Buffer.isBuffer(new Uint8Array(1024)); // falseconst { Buffer } = require('node:buffer');
Buffer.isBuffer(Buffer.alloc(10)); // true
Buffer.isBuffer(Buffer.from('foo')); // true
Buffer.isBuffer('a string'); // false
Buffer.isBuffer([]); // false
Buffer.isBuffer(new Uint8Array(1024)); // false
Static method: Buffer.isEncoding(encoding)#
Returns true if encoding is the name of a supported character encoding,
or false otherwise.
import { Buffer } from 'node:buffer';
console.log(Buffer.isEncoding('utf8'));
// Prints: true
console.log(Buffer.isEncoding('hex'));
// Prints: true
console.log(Buffer.isEncoding('utf/8'));
// Prints: false
console.log(Buffer.isEncoding(''));
// Prints: falseconst { Buffer } = require('node:buffer');
console.log(Buffer.isEncoding('utf8'));
// Prints: true
console.log(Buffer.isEncoding('hex'));
// Prints: true
console.log(Buffer.isEncoding('utf/8'));
// Prints: false
console.log(Buffer.isEncoding(''));
// Prints: false
Class property: Buffer.poolSize#
- <integer> Default:
8192
This is the size (in bytes) of pre-allocated internal Buffer instances used
for pooling. This value may be modified.
buf[index]#
index<integer>
The index operator [index] can be used to get and set the octet at position
index in buf. The values refer to individual bytes, so the legal value
range is between 0x00 and 0xFF (hex) or 0 and 255 (decimal).
This operator is inherited from Uint8Array, so its behavior on out-of-bounds
access is the same as Uint8Array. In other words, buf[index] returns
undefined when index is negative or greater or equal to buf.length, and
buf[index] = value does not modify the buffer if index is negative or
>= buf.length.
import { Buffer } from 'node:buffer';
// Copy an ASCII string into a `Buffer` one byte at a time.
// (This only works for ASCII-only strings. In general, one should use
// `Buffer.from()` to perform this conversion.)
const str = 'Node.js';
const buf = Buffer.allocUnsafe(str.length);
for (let i = 0; i < str.length; i++) {
buf[i] = str.charCodeAt(i);
}
console.log(buf.toString('utf8'));
// Prints: Node.jsconst { Buffer } = require('node:buffer');
// Copy an ASCII string into a `Buffer` one byte at a time.
// (This only works for ASCII-only strings. In general, one should use
// `Buffer.from()` to perform this conversion.)
const str = 'Node.js';
const buf = Buffer.allocUnsafe(str.length);
for (let i = 0; i < str.length; i++) {
buf[i] = str.charCodeAt(i);
}
console.log(buf.toString('utf8'));
// Prints: Node.js
buf.buffer#
- <ArrayBuffer> The underlying
ArrayBufferobject based on which thisBufferobject is created.
This ArrayBuffer is not guaranteed to correspond exactly to the original
Buffer. See the notes on buf.byteOffset for details.
import { Buffer } from 'node:buffer';
const arrayBuffer = new ArrayBuffer(16);
const buffer = Buffer.from(arrayBuffer);
console.log(buffer.buffer === arrayBuffer);
// Prints: trueconst { Buffer } = require('node:buffer');
const arrayBuffer = new ArrayBuffer(16);
const buffer = Buffer.from(arrayBuffer);
console.log(buffer.buffer === arrayBuffer);
// Prints: true
buf.byteOffset#
- <integer> The
byteOffsetof theBuffers underlyingArrayBufferobject.
When setting byteOffset in Buffer.from(ArrayBuffer, byteOffset, length),
or sometimes when allocating a Buffer smaller than Buffer.poolSize, the
buffer does not start from a zero offset on the underlying ArrayBuffer.
This can cause problems when accessing the underlying ArrayBuffer directly
using buf.buffer, as other parts of the ArrayBuffer may be unrelated
to the Buffer object itself.
A common issue when creating a TypedArray object that shares its memory with
a Buffer is that in this case one needs to specify the byteOffset correctly:
import { Buffer } from 'node:buffer';
// Create a buffer smaller than `Buffer.poolSize`.
const nodeBuffer = Buffer.from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
// When casting the Node.js Buffer to an Int8Array, use the byteOffset
// to refer only to the part of `nodeBuffer.buffer` that contains the memory
// for `nodeBuffer`.
new Int8Array(nodeBuffer.buffer, nodeBuffer.byteOffset, nodeBuffer.length);const { Buffer } = require('node:buffer');
// Create a buffer smaller than `Buffer.poolSize`.
const nodeBuffer = Buffer.from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
// When casting the Node.js Buffer to an Int8Array, use the byteOffset
// to refer only to the part of `nodeBuffer.buffer` that contains the memory
// for `nodeBuffer`.
new Int8Array(nodeBuffer.buffer, nodeBuffer.byteOffset, nodeBuffer.length);
buf.compare(target[, targetStart[, targetEnd[, sourceStart[, sourceEnd]]]])#
target<Buffer> | <Uint8Array> ABufferorUint8Arraywith which to comparebuf.targetStart<integer> The offset withintargetat which to begin comparison. Default:0.targetEnd<integer> The offset withintargetat which to end comparison (not inclusive). Default:target.length.sourceStart<integer> The offset withinbufat which to begin comparison. Default:0.sourceEnd<integer> The offset withinbufat which to end comparison (not inclusive). Default:buf.length.- Returns: <integer>
Compares buf with target and returns a number indicating whether buf
comes before, after, or is the same as target in sort order.
Comparison is based on the actual sequence of bytes in each Buffer.
0is returned iftargetis the same asbuf1is returned iftargetshould come beforebufwhen sorted.-1is returned iftargetshould come afterbufwhen sorted.
import { Buffer } from 'node:buffer';
const buf1 = Buffer.from('ABC');
const buf2 = Buffer.from('BCD');
const buf3 = Buffer.from('ABCD');
console.log(buf1.compare(buf1));
// Prints: 0
console.log(buf1.compare(buf2));
// Prints: -1
console.log(buf1.compare(buf3));
// Prints: -1
console.log(buf2.compare(buf1));
// Prints: 1
console.log(buf2.compare(buf3));
// Prints: 1
console.log([buf1, buf2, buf3].sort(Buffer.compare));
// Prints: [ <Buffer 41 42 43>, <Buffer 41 42 43 44>, <Buffer 42 43 44> ]
// (This result is equal to: [buf1, buf3, buf2].)const { Buffer } = require('node:buffer');
const buf1 = Buffer.from('ABC');
const buf2 = Buffer.from('BCD');
const buf3 = Buffer.from('ABCD');
console.log(buf1.compare(buf1));
// Prints: 0
console.log(buf1.compare(buf2));
// Prints: -1
console.log(buf1.compare(buf3));
// Prints: -1
console.log(buf2.compare(buf1));
// Prints: 1
console.log(buf2.compare(buf3));
// Prints: 1
console.log([buf1, buf2, buf3].sort(Buffer.compare));
// Prints: [ <Buffer 41 42 43>, <Buffer 41 42 43 44>, <Buffer 42 43 44> ]
// (This result is equal to: [buf1, buf3, buf2].)
The optional targetStart, targetEnd, sourceStart, and sourceEnd
arguments can be used to limit the comparison to specific ranges within target
and buf respectively.
import { Buffer } from 'node:buffer';
const buf1 = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8, 9]);
const buf2 = Buffer.from([5, 6, 7, 8, 9, 1, 2, 3, 4]);
console.log(buf1.compare(buf2, 5, 9, 0, 4));
// Prints: 0
console.log(buf1.compare(buf2, 0, 6, 4));
// Prints: -1
console.log(buf1.compare(buf2, 5, 6, 5));
// Prints: 1const { Buffer } = require('node:buffer');
const buf1 = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8, 9]);
const buf2 = Buffer.from([5, 6, 7, 8, 9, 1, 2, 3, 4]);
console.log(buf1.compare(buf2, 5, 9, 0, 4));
// Prints: 0
console.log(buf1.compare(buf2, 0, 6, 4));
// Prints: -1
console.log(buf1.compare(buf2, 5, 6, 5));
// Prints: 1
ERR_OUT_OF_RANGE is thrown if targetStart < 0, sourceStart < 0,
targetEnd > target.byteLength, or sourceEnd > source.byteLength.
buf.copy(target[, targetStart[, sourceStart[, sourceEnd]]])#
target<Buffer> | <Uint8Array> ABufferorUint8Arrayto copy into.targetStart<integer> The offset withintargetat which to begin writing. Default:0.sourceStart<integer> The offset withinbuffrom which to begin copying. Default:0.sourceEnd<integer> The offset withinbufat which to stop copying (not inclusive). Default:buf.length.- Returns: <integer> The number of bytes copied.
Copies data from a region of buf to a region in target, even if the target
memory region overlaps with buf.
TypedArray.prototype.set() performs the same operation, and is available
for all TypedArrays, including Node.js Buffers, although it takes
different function arguments.
import { Buffer } from 'node:buffer';
// Create two `Buffer` instances.
const buf1 = Buffer.allocUnsafe(26);
const buf2 = Buffer.allocUnsafe(26).fill('!');
for (let i = 0; i < 26; i++) {
// 97 is the decimal ASCII value for 'a'.
buf1[i] = i + 97;
}
// Copy `buf1` bytes 16 through 19 into `buf2` starting at byte 8 of `buf2`.
buf1.copy(buf2, 8, 16, 20);
// This is equivalent to:
// buf2.set(buf1.subarray(16, 20), 8);
console.log(buf2.toString('ascii', 0, 25));
// Prints: !!!!!!!!qrst!!!!!!!!!!!!!const { Buffer } = require('node:buffer');
// Create two `Buffer` instances.
const buf1 = Buffer.allocUnsafe(26);
const buf2 = Buffer.allocUnsafe(26).fill('!');
for (let i = 0; i < 26; i++) {
// 97 is the decimal ASCII value for 'a'.
buf1[i] = i + 97;
}
// Copy `buf1` bytes 16 through 19 into `buf2` starting at byte 8 of `buf2`.
buf1.copy(buf2, 8, 16, 20);
// This is equivalent to:
// buf2.set(buf1.subarray(16, 20), 8);
console.log(buf2.toString('ascii', 0, 25));
// Prints: !!!!!!!!qrst!!!!!!!!!!!!!
import { Buffer } from 'node:buffer';
// Create a `Buffer` and copy data from one region to an overlapping region
// within the same `Buffer`.
const buf = Buffer.allocUnsafe(26);
for (let i = 0; i < 26; i++) {
// 97 is the decimal ASCII value for 'a'.
buf[i] = i + 97;
}
buf.copy(buf, 0, 4, 10);
console.log(buf.toString());
// Prints: efghijghijklmnopqrstuvwxyzconst { Buffer } = require('node:buffer');
// Create a `Buffer` and copy data from one region to an overlapping region
// within the same `Buffer`.
const buf = Buffer.allocUnsafe(26);
for (let i = 0; i < 26; i++) {
// 97 is the decimal ASCII value for 'a'.
buf[i] = i + 97;
}
buf.copy(buf, 0, 4, 10);
console.log(buf.toString());
// Prints: efghijghijklmnopqrstuvwxyz
buf.entries()#
- Returns: <Iterator>
Creates and returns an iterator of [index, byte] pairs from the contents
of buf.
import { Buffer } from 'node:buffer';
// Log the entire contents of a `Buffer`.
const buf = Buffer.from('buffer');
for (const pair of buf.entries()) {
console.log(pair);
}
// Prints:
// [0, 98]
// [1, 117]
// [2, 102]
// [3, 102]
// [4, 101]
// [5, 114]const { Buffer } = require('node:buffer');
// Log the entire contents of a `Buffer`.
const buf = Buffer.from('buffer');
for (const pair of buf.entries()) {
console.log(pair);
}
// Prints:
// [0, 98]
// [1, 117]
// [2, 102]
// [3, 102]
// [4, 101]
// [5, 114]
buf.equals(otherBuffer)#
otherBuffer<Buffer> | <Uint8Array> ABufferorUint8Arraywith which to comparebuf.- Returns: <boolean>
Returns true if both buf and otherBuffer have exactly the same bytes,
false otherwise. Equivalent to
buf.compare(otherBuffer) === 0.
import { Buffer } from 'node:buffer';
const buf1 = Buffer.from('ABC');
const buf2 = Buffer.from('414243', 'hex');
const buf3 = Buffer.from('ABCD');
console.log(buf1.equals(buf2));
// Prints: true
console.log(buf1.equals(buf3));
// Prints: falseconst { Buffer } = require('node:buffer');
const buf1 = Buffer.from('ABC');
const buf2 = Buffer.from('414243', 'hex');
const buf3 = Buffer.from('ABCD');
console.log(buf1.equals(buf2));
// Prints: true
console.log(buf1.equals(buf3));
// Prints: false
buf.fill(value[, offset[, end]][, encoding])#
value<string> | <Buffer> | <Uint8Array> | <integer> The value with which to fillbuf.offset<integer> Number of bytes to skip before starting to fillbuf. Default:0.end<integer> Where to stop fillingbuf(not inclusive). Default:buf.length.encoding<string> The encoding forvalueifvalueis a string. Default:'utf8'.- Returns: <Buffer> A reference to
buf.
Fills buf with the specified value. If the offset and end are not given,
the entire buf will be filled:
import { Buffer } from 'node:buffer';
// Fill a `Buffer` with the ASCII character 'h'.
const b = Buffer.allocUnsafe(50).fill('h');
console.log(b.toString());
// Prints: hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhconst { Buffer } = require('node:buffer');
// Fill a `Buffer` with the ASCII character 'h'.
const b = Buffer.allocUnsafe(50).fill('h');
console.log(b.toString());
// Prints: hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
value is coerced to a uint32 value if it is not a string, Buffer, or
integer. If the resulting integer is greater than 255 (decimal), buf will be
filled with value & 255.
If the final write of a fill() operation falls on a multi-byte character,
then only the bytes of that character that fit into buf are written:
import { Buffer } from 'node:buffer';
// Fill a `Buffer` with character that takes up two bytes in UTF-8.
console.log(Buffer.allocUnsafe(5).fill('\u0222'));
// Prints: <Buffer c8 a2 c8 a2 c8>const { Buffer } = require('node:buffer');
// Fill a `Buffer` with character that takes up two bytes in UTF-8.
console.log(Buffer.allocUnsafe(5).fill('\u0222'));
// Prints: <Buffer c8 a2 c8 a2 c8>
If value contains invalid characters, it is truncated; if no valid
fill data remains, an exception is thrown:
import { Buffer } from 'node:buffer';
const buf = Buffer.allocUnsafe(5);
console.log(buf.fill('a'));
// Prints: <Buffer 61 61 61 61 61>
console.log(buf.fill('aazz', 'hex'));
// Prints: <Buffer aa aa aa aa aa>
console.log(buf.fill('zz', 'hex'));
// Throws an exception.const { Buffer } = require('node:buffer');
const buf = Buffer.allocUnsafe(5);
console.log(buf.fill('a'));
// Prints: <Buffer 61 61 61 61 61>
console.log(buf.fill('aazz', 'hex'));
// Prints: <Buffer aa aa aa aa aa>
console.log(buf.fill('zz', 'hex'));
// Throws an exception.
buf.includes(value[, byteOffset][, encoding])#
value<string> | <Buffer> | <Uint8Array> | <integer> What to search for.byteOffset<integer> Where to begin searching inbuf. If negative, then offset is calculated from the end ofbuf. Default:0.encoding<string> Ifvalueis a string, this is its encoding. Default:'utf8'.- Returns: <boolean>
trueifvaluewas found inbuf,falseotherwise.
Equivalent to buf.indexOf() !== -1.
import { Buffer } from 'node:buffer';
const buf = Buffer.from('this is a buffer');
console.log(buf.includes('this'));
// Prints: true
console.log(buf.includes('is'));
// Prints: true
console.log(buf.includes(Buffer.from('a buffer')));
// Prints: true
console.log(buf.includes(97));
// Prints: true (97 is the decimal ASCII value for 'a')
console.log(buf.includes(Buffer.from('a buffer example')));
// Prints: false
console.log(buf.includes(Buffer.from('a buffer example').slice(0, 8)));
// Prints: true
console.log(buf.includes('this', 4));
// Prints: falseconst { Buffer } = require('node:buffer');
const buf = Buffer.from('this is a buffer');
console.log(buf.includes('this'));
// Prints: true
console.log(buf.includes('is'));
// Prints: true
console.log(buf.includes(Buffer.from('a buffer')));
// Prints: true
console.log(buf.includes(97));
// Prints: true (97 is the decimal ASCII value for 'a')
console.log(buf.includes(Buffer.from('a buffer example')));
// Prints: false
console.log(buf.includes(Buffer.from('a buffer example').slice(0, 8)));
// Prints: true
console.log(buf.includes('this', 4));
// Prints: false
buf.indexOf(value[, byteOffset][, encoding])#
value<string> | <Buffer> | <Uint8Array> | <integer> What to search for.byteOffset<integer> Where to begin searching inbuf. If negative, then offset is calculated from the end ofbuf. Default:0.encoding<string> Ifvalueis a string, this is the encoding used to determine the binary representation of the string that will be searched for inbuf. Default:'utf8'.- Returns: <integer> The index of the first occurrence of
valueinbuf, or-1ifbufdoes not containvalue.
If value is:
- a string,
valueis interpreted according to the character encoding inencoding. - a
BufferorUint8Array,valuewill be used in its entirety. To compare a partialBuffer, usebuf.subarray. - a number,
valuewill be interpreted as an unsigned 8-bit integer value between0and255.
import { Buffer } from 'node:buffer';
const buf = Buffer.from('this is a buffer');
console.log(buf.indexOf('this'));
// Prints: 0
console.log(buf.indexOf('is'));
// Prints: 2
console.log(buf.indexOf(Buffer.from('a buffer')));
// Prints: 8
console.log(buf.indexOf(97));
// Prints: 8 (97 is the decimal ASCII value for 'a')
console.log(buf.indexOf(Buffer.from('a buffer example')));
// Prints: -1
console.log(buf.indexOf(Buffer.from('a buffer example').slice(0, 8)));
// Prints: 8
const utf16Buffer = Buffer.from('\u039a\u0391\u03a3\u03a3\u0395', 'utf16le');
console.log(utf16Buffer.indexOf('\u03a3', 0, 'utf16le'));
// Prints: 4
console.log(utf16Buffer.indexOf('\u03a3', -4, 'utf16le'));
// Prints: 6const { Buffer } = require('node:buffer');
const buf = Buffer.from('this is a buffer');
console.log(buf.indexOf('this'));
// Prints: 0
console.log(buf.indexOf('is'));
// Prints: 2
console.log(buf.indexOf(Buffer.from('a buffer')));
// Prints: 8
console.log(buf.indexOf(97));
// Prints: 8 (97 is the decimal ASCII value for 'a')
console.log(buf.indexOf(Buffer.from('a buffer example')));
// Prints: -1
console.log(buf.indexOf(Buffer.from('a buffer example').slice(0, 8)));
// Prints: 8
const utf16Buffer = Buffer.from('\u039a\u0391\u03a3\u03a3\u0395', 'utf16le');
console.log(utf16Buffer.indexOf('\u03a3', 0, 'utf16le'));
// Prints: 4
console.log(utf16Buffer.indexOf('\u03a3', -4, 'utf16le'));
// Prints: 6
If value is not a string, number, or Buffer, this method will throw a
TypeError. If value is a number, it will be coerced to a valid byte value,
an integer between 0 and 255.
If byteOffset is not a number, it will be coerced to a number. If the result
of coercion is NaN or 0, then the entire buffer will be searched. This
behavior matches String.prototype.indexOf().
import { Buffer } from 'node:buffer';
const b = Buffer.from('abcdef');
// Passing a value that's a number, but not a valid byte.
// Prints: 2, equivalent to searching for 99 or 'c'.
console.log(b.indexOf(99.9));
console.log(b.indexOf(256 + 99));
// Passing a byteOffset that coerces to NaN or 0.
// Prints: 1, searching the whole buffer.
console.log(b.indexOf('b', undefined));
console.log(b.indexOf('b', {}));
console.log(b.indexOf('b', null));
console.log(b.indexOf('b', []));const { Buffer } = require('node:buffer');
const b = Buffer.from('abcdef');
// Passing a value that's a number, but not a valid byte.
// Prints: 2, equivalent to searching for 99 or 'c'.
console.log(b.indexOf(99.9));
console.log(b.indexOf(256 + 99));
// Passing a byteOffset that coerces to NaN or 0.
// Prints: 1, searching the whole buffer.
console.log(b.indexOf('b', undefined));
console.log(b.indexOf('b', {}));
console.log(b.indexOf('b', null));
console.log(b.indexOf('b', []));
If value is an empty string or empty Buffer and byteOffset is less
than buf.length, byteOffset will be returned. If value is empty and
byteOffset is at least buf.length, buf.length will be returned.
buf.keys()#
- Returns: <Iterator>
Creates and returns an iterator of buf keys (indices).
import { Buffer } from 'node:buffer';
const buf = Buffer.from('buffer');
for (const key of buf.keys()) {
console.log(key);
}
// Prints:
// 0
// 1
// 2
// 3
// 4
// 5const { Buffer } = require('node:buffer');
const buf = Buffer.from('buffer');
for (const key of buf.keys()) {
console.log(key);
}
// Prints:
// 0
// 1
// 2
// 3
// 4
// 5
buf.lastIndexOf(value[, byteOffset][, encoding])#
value<string> | <Buffer> | <Uint8Array> | <integer> What to search for.byteOffset<integer> Where to begin searching inbuf. If negative, then offset is calculated from the end ofbuf. Default:buf.length - 1.encoding<string> Ifvalueis a string, this is the encoding used to determine the binary representation of the string that will be searched for inbuf. Default:'utf8'.- Returns: <integer> The index of the last occurrence of
valueinbuf, or-1ifbufdoes not containvalue.
Identical to buf.indexOf(), except the last occurrence of value is found
rather than the first occurrence.
import { Buffer } from 'node:buffer';
const buf = Buffer.from('this buffer is a buffer');
console.log(buf.lastIndexOf('this'));
// Prints: 0
console.log(buf.lastIndexOf('buffer'));
// Prints: 17
console.log(buf.lastIndexOf(Buffer.from('buffer')));
// Prints: 17
console.log(buf.lastIndexOf(97));
// Prints: 15 (97 is the decimal ASCII value for 'a')
console.log(buf.lastIndexOf(Buffer.from('yolo')));
// Prints: -1
console.log(buf.lastIndexOf('buffer', 5));
// Prints: 5
console.log(buf.lastIndexOf('buffer', 4));
// Prints: -1
const utf16Buffer = Buffer.from('\u039a\u0391\u03a3\u03a3\u0395', 'utf16le');
console.log(utf16Buffer.lastIndexOf('\u03a3', undefined, 'utf16le'));
// Prints: 6
console.log(utf16Buffer.lastIndexOf('\u03a3', -5, 'utf16le'));
// Prints: 4const { Buffer } = require('node:buffer');
const buf = Buffer.from('this buffer is a buffer');
console.log(buf.lastIndexOf('this'));
// Prints: 0
console.log(buf.lastIndexOf('buffer'));
// Prints: 17
console.log(buf.lastIndexOf(Buffer.from('buffer')));
// Prints: 17
console.log(buf.lastIndexOf(97));
// Prints: 15 (97 is the decimal ASCII value for 'a')
console.log(buf.lastIndexOf(Buffer.from('yolo')));
// Prints: -1
console.log(buf.lastIndexOf('buffer', 5));
// Prints: 5
console.log(buf.lastIndexOf('buffer', 4));
// Prints: -1
const utf16Buffer = Buffer.from('\u039a\u0391\u03a3\u03a3\u0395', 'utf16le');
console.log(utf16Buffer.lastIndexOf('\u03a3', undefined, 'utf16le'));
// Prints: 6
console.log(utf16Buffer.lastIndexOf('\u03a3', -5, 'utf16le'));
// Prints: 4
If value is not a string, number, or Buffer, this method will throw a
TypeError. If value is a number, it will be coerced to a valid byte value,
an integer between 0 and 255.
If byteOffset is not a number, it will be coerced to a number. Any arguments
that coerce to NaN, like {} or undefined, will search the whole buffer.
This behavior matches String.prototype.lastIndexOf().
import { Buffer } from 'node:buffer';
const b = Buffer.from('abcdef');
// Passing a value that's a number, but not a valid byte.
// Prints: 2, equivalent to searching for 99 or 'c'.
console.log(b.lastIndexOf(99.9));
console.log(b.lastIndexOf(256 + 99));
// Passing a byteOffset that coerces to NaN.
// Prints: 1, searching the whole buffer.
console.log(b.lastIndexOf('b', undefined));
console.log(b.lastIndexOf('b', {}));
// Passing a byteOffset that coerces to 0.
// Prints: -1, equivalent to passing 0.
console.log(b.lastIndexOf('b', null));
console.log(b.lastIndexOf('b', []));const { Buffer } = require('node:buffer');
const b = Buffer.from('abcdef');
// Passing a value that's a number, but not a valid byte.
// Prints: 2, equivalent to searching for 99 or 'c'.
console.log(b.lastIndexOf(99.9));
console.log(b.lastIndexOf(256 + 99));
// Passing a byteOffset that coerces to NaN.
// Prints: 1, searching the whole buffer.
console.log(b.lastIndexOf('b', undefined));
console.log(b.lastIndexOf('b', {}));
// Passing a byteOffset that coerces to 0.
// Prints: -1, equivalent to passing 0.
console.log(b.lastIndexOf('b', null));
console.log(b.lastIndexOf('b', []));
If value is an empty string or empty Buffer, byteOffset will be returned.
buf.length#
Returns the number of bytes in buf.
import { Buffer } from 'node:buffer';
// Create a `Buffer` and write a shorter string to it using UTF-8.
const buf = Buffer.alloc(1234);
console.log(buf.length);
// Prints: 1234
buf.write('some string', 0, 'utf8');
console.log(buf.length);
// Prints: 1234const { Buffer } = require('node:buffer');
// Create a `Buffer` and write a shorter string to it using UTF-8.
const buf = Buffer.alloc(1234);
console.log(buf.length);
// Prints: 1234
buf.write('some string', 0, 'utf8');
console.log(buf.length);
// Prints: 1234
buf.parent#
buf.buffer instead.The buf.parent property is a deprecated alias for buf.buffer.
buf.readBigInt64BE([offset])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy:0 <= offset <= buf.length - 8. Default:0.- Returns: <bigint>
Reads a signed, big-endian 64-bit integer from buf at the specified offset.
Integers read from a Buffer are interpreted as two's complement signed
values.
buf.readBigInt64LE([offset])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy:0 <= offset <= buf.length - 8. Default:0.- Returns: <bigint>
Reads a signed, little-endian 64-bit integer from buf at the specified
offset.
Integers read from a Buffer are interpreted as two's complement signed
values.
buf.readBigUInt64BE([offset])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy:0 <= offset <= buf.length - 8. Default:0.- Returns: <bigint>
Reads an unsigned, big-endian 64-bit integer from buf at the specified
offset.
This function is also available under the readBigUint64BE alias.
import { Buffer } from 'node:buffer';
const buf = Buffer.from([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff]);
console.log(buf.readBigUInt64BE(0));
// Prints: 4294967295nconst { Buffer } = require('node:buffer');
const buf = Buffer.from([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff]);
console.log(buf.readBigUInt64BE(0));
// Prints: 4294967295n
buf.readBigUInt64LE([offset])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy:0 <= offset <= buf.length - 8. Default:0.- Returns: <bigint>
Reads an unsigned, little-endian 64-bit integer from buf at the specified
offset.
This function is also available under the readBigUint64LE alias.
import { Buffer } from 'node:buffer';
const buf = Buffer.from([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff]);
console.log(buf.readBigUInt64LE(0));
// Prints: 18446744069414584320nconst { Buffer } = require('node:buffer');
const buf = Buffer.from([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff]);
console.log(buf.readBigUInt64LE(0));
// Prints: 18446744069414584320n
buf.readDoubleBE([offset])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy0 <= offset <= buf.length - 8. Default:0.- Returns: <number>
Reads a 64-bit, big-endian double from buf at the specified offset.
import { Buffer } from 'node:buffer';
const buf = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]);
console.log(buf.readDoubleBE(0));
// Prints: 8.20788039913184e-304const { Buffer } = require('node:buffer');
const buf = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]);
console.log(buf.readDoubleBE(0));
// Prints: 8.20788039913184e-304
buf.readDoubleLE([offset])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy0 <= offset <= buf.length - 8. Default:0.- Returns: <number>
Reads a 64-bit, little-endian double from buf at the specified offset.
import { Buffer } from 'node:buffer';
const buf = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]);
console.log(buf.readDoubleLE(0));
// Prints: 5.447603722011605e-270
console.log(buf.readDoubleLE(1));
// Throws ERR_OUT_OF_RANGE.const { Buffer } = require('node:buffer');
const buf = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]);
console.log(buf.readDoubleLE(0));
// Prints: 5.447603722011605e-270
console.log(buf.readDoubleLE(1));
// Throws ERR_OUT_OF_RANGE.
buf.readFloatBE([offset])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy0 <= offset <= buf.length - 4. Default:0.- Returns: <number>
Reads a 32-bit, big-endian float from buf at the specified offset.
import { Buffer } from 'node:buffer';
const buf = Buffer.from([1, 2, 3, 4]);
console.log(buf.readFloatBE(0));
// Prints: 2.387939260590663e-38const { Buffer } = require('node:buffer');
const buf = Buffer.from([1, 2, 3, 4]);
console.log(buf.readFloatBE(0));
// Prints: 2.387939260590663e-38
buf.readFloatLE([offset])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy0 <= offset <= buf.length - 4. Default:0.- Returns: <number>
Reads a 32-bit, little-endian float from buf at the specified offset.
import { Buffer } from 'node:buffer';
const buf = Buffer.from([1, 2, 3, 4]);
console.log(buf.readFloatLE(0));
// Prints: 1.539989614439558e-36
console.log(buf.readFloatLE(1));
// Throws ERR_OUT_OF_RANGE.const { Buffer } = require('node:buffer');
const buf = Buffer.from([1, 2, 3, 4]);
console.log(buf.readFloatLE(0));
// Prints: 1.539989614439558e-36
console.log(buf.readFloatLE(1));
// Throws ERR_OUT_OF_RANGE.
buf.readInt8([offset])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy0 <= offset <= buf.length - 1. Default:0.- Returns: <integer>
Reads a signed 8-bit integer from buf at the specified offset.
Integers read from a Buffer are interpreted as two's complement signed values.
import { Buffer } from 'node:buffer';
const buf = Buffer.from([-1, 5]);
console.log(buf.readInt8(0));
// Prints: -1
console.log(buf.readInt8(1));
// Prints: 5
console.log(buf.readInt8(2));
// Throws ERR_OUT_OF_RANGE.const { Buffer } = require('node:buffer');
const buf = Buffer.from([-1, 5]);
console.log(buf.readInt8(0));
// Prints: -1
console.log(buf.readInt8(1));
// Prints: 5
console.log(buf.readInt8(2));
// Throws ERR_OUT_OF_RANGE.
buf.readInt16BE([offset])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy0 <= offset <= buf.length - 2. Default:0.- Returns: <integer>
Reads a signed, big-endian 16-bit integer from buf at the specified offset.
Integers read from a Buffer are interpreted as two's complement signed values.
import { Buffer } from 'node:buffer';
const buf = Buffer.from([0, 5]);
console.log(buf.readInt16BE(0));
// Prints: 5const { Buffer } = require('node:buffer');
const buf = Buffer.from([0, 5]);
console.log(buf.readInt16BE(0));
// Prints: 5
buf.readInt16LE([offset])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy0 <= offset <= buf.length - 2. Default:0.- Returns: <integer>
Reads a signed, little-endian 16-bit integer from buf at the specified
offset.
Integers read from a Buffer are interpreted as two's complement signed values.
import { Buffer } from 'node:buffer';
const buf = Buffer.from([0, 5]);
console.log(buf.readInt16LE(0));
// Prints: 1280
console.log(buf.readInt16LE(1));
// Throws ERR_OUT_OF_RANGE.const { Buffer } = require('node:buffer');
const buf = Buffer.from([0, 5]);
console.log(buf.readInt16LE(0));
// Prints: 1280
console.log(buf.readInt16LE(1));
// Throws ERR_OUT_OF_RANGE.
buf.readInt32BE([offset])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy0 <= offset <= buf.length - 4. Default:0.- Returns: <integer>
Reads a signed, big-endian 32-bit integer from buf at the specified offset.
Integers read from a Buffer are interpreted as two's complement signed values.
import { Buffer } from 'node:buffer';
const buf = Buffer.from([0, 0, 0, 5]);
console.log(buf.readInt32BE(0));
// Prints: 5const { Buffer } = require('node:buffer');
const buf = Buffer.from([0, 0, 0, 5]);
console.log(buf.readInt32BE(0));
// Prints: 5
buf.readInt32LE([offset])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy0 <= offset <= buf.length - 4. Default:0.- Returns: <integer>
Reads a signed, little-endian 32-bit integer from buf at the specified
offset.
Integers read from a Buffer are interpreted as two's complement signed values.
import { Buffer } from 'node:buffer';
const buf = Buffer.from([0, 0, 0, 5]);
console.log(buf.readInt32LE(0));
// Prints: 83886080
console.log(buf.readInt32LE(1));
// Throws ERR_OUT_OF_RANGE.const { Buffer } = require('node:buffer');
const buf = Buffer.from([0, 0, 0, 5]);
console.log(buf.readInt32LE(0));
// Prints: 83886080
console.log(buf.readInt32LE(1));
// Throws ERR_OUT_OF_RANGE.
buf.readIntBE(offset, byteLength)#
offset<integer> Number of bytes to skip before starting to read. Must satisfy0 <= offset <= buf.length - byteLength.byteLength<integer> Number of bytes to read. Must satisfy0 < byteLength <= 6.- Returns: <integer>
Reads byteLength number of bytes from buf at the specified offset
and interprets the result as a big-endian, two's complement signed value
supporting up to 48 bits of accuracy.
import { Buffer } from 'node:buffer';
const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]);
console.log(buf.readIntBE(0, 6).toString(16));
// Prints: 1234567890ab
console.log(buf.readIntBE(1, 6).toString(16));
// Throws ERR_OUT_OF_RANGE.
console.log(buf.readIntBE(1, 0).toString(16));
// Throws ERR_OUT_OF_RANGE.const { Buffer } = require('node:buffer');
const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]);
console.log(buf.readIntBE(0, 6).toString(16));
// Prints: 1234567890ab
console.log(buf.readIntBE(1, 6).toString(16));
// Throws ERR_OUT_OF_RANGE.
console.log(buf.readIntBE(1, 0).toString(16));
// Throws ERR_OUT_OF_RANGE.
buf.readIntLE(offset, byteLength)#
offset<integer> Number of bytes to skip before starting to read. Must satisfy0 <= offset <= buf.length - byteLength.byteLength<integer> Number of bytes to read. Must satisfy0 < byteLength <= 6.- Returns: <integer>
Reads byteLength number of bytes from buf at the specified offset
and interprets the result as a little-endian, two's complement signed value
supporting up to 48 bits of accuracy.
import { Buffer } from 'node:buffer';
const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]);
console.log(buf.readIntLE(0, 6).toString(16));
// Prints: -546f87a9cbeeconst { Buffer } = require('node:buffer');
const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]);
console.log(buf.readIntLE(0, 6).toString(16));
// Prints: -546f87a9cbee
buf.readUInt8([offset])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy0 <= offset <= buf.length - 1. Default:0.- Returns: <integer>
Reads an unsigned 8-bit integer from buf at the specified offset.
This function is also available under the readUint8 alias.
import { Buffer } from 'node:buffer';
const buf = Buffer.from([1, -2]);
console.log(buf.readUInt8(0));
// Prints: 1
console.log(buf.readUInt8(1));
// Prints: 254
console.log(buf.readUInt8(2));
// Throws ERR_OUT_OF_RANGE.const { Buffer } = require('node:buffer');
const buf = Buffer.from([1, -2]);
console.log(buf.readUInt8(0));
// Prints: 1
console.log(buf.readUInt8(1));
// Prints: 254
console.log(buf.readUInt8(2));
// Throws ERR_OUT_OF_RANGE.
buf.readUInt16BE([offset])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy0 <= offset <= buf.length - 2. Default:0.- Returns: <integer>
Reads an unsigned, big-endian 16-bit integer from buf at the specified
offset.
This function is also available under the readUint16BE alias.
import { Buffer } from 'node:buffer';
const buf = Buffer.from([0x12, 0x34, 0x56]);
console.log(buf.readUInt16BE(0).toString(16));
// Prints: 1234
console.log(buf.readUInt16BE(1).toString(16));
// Prints: 3456const { Buffer } = require('node:buffer');
const buf = Buffer.from([0x12, 0x34, 0x56]);
console.log(buf.readUInt16BE(0).toString(16));
// Prints: 1234
console.log(buf.readUInt16BE(1).toString(16));
// Prints: 3456
buf.readUInt16LE([offset])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy0 <= offset <= buf.length - 2. Default:0.- Returns: <integer>
Reads an unsigned, little-endian 16-bit integer from buf at the specified
offset.
This function is also available under the readUint16LE alias.
import { Buffer } from 'node:buffer';
const buf = Buffer.from([0x12, 0x34, 0x56]);
console.log(buf.readUInt16LE(0).toString(16));
// Prints: 3412
console.log(buf.readUInt16LE(1).toString(16));
// Prints: 5634
console.log(buf.readUInt16LE(2).toString(16));
// Throws ERR_OUT_OF_RANGE.const { Buffer } = require('node:buffer');
const buf = Buffer.from([0x12, 0x34, 0x56]);
console.log(buf.readUInt16LE(0).toString(16));
// Prints: 3412
console.log(buf.readUInt16LE(1).toString(16));
// Prints: 5634
console.log(buf.readUInt16LE(2).toString(16));
// Throws ERR_OUT_OF_RANGE.
buf.readUInt32BE([offset])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy0 <= offset <= buf.length - 4. Default:0.- Returns: <integer>
Reads an unsigned, big-endian 32-bit integer from buf at the specified
offset.
This function is also available under the readUint32BE alias.
import { Buffer } from 'node:buffer';
const buf = Buffer.from([0x12, 0x34, 0x56, 0x78]);
console.log(buf.readUInt32BE(0).toString(16));
// Prints: 12345678const { Buffer } = require('node:buffer');
const buf = Buffer.from([0x12, 0x34, 0x56, 0x78]);
console.log(buf.readUInt32BE(0).toString(16));
// Prints: 12345678
buf.readUInt32LE([offset])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy0 <= offset <= buf.length - 4. Default:0.- Returns: <integer>
Reads an unsigned, little-endian 32-bit integer from buf at the specified
offset.
This function is also available under the readUint32LE alias.
import { Buffer } from 'node:buffer';
const buf = Buffer.from([0x12, 0x34, 0x56, 0x78]);
console.log(buf.readUInt32LE(0).toString(16));
// Prints: 78563412
console.log(buf.readUInt32LE(1).toString(16));
// Throws ERR_OUT_OF_RANGE.const { Buffer } = require('node:buffer');
const buf = Buffer.from([0x12, 0x34, 0x56, 0x78]);
console.log(buf.readUInt32LE(0).toString(16));
// Prints: 78563412
console.log(buf.readUInt32LE(1).toString(16));
// Throws ERR_OUT_OF_RANGE.
buf.readUIntBE(offset, byteLength)#
offset<integer> Number of bytes to skip before starting to read. Must satisfy0 <= offset <= buf.length - byteLength.byteLength<integer> Number of bytes to read. Must satisfy0 < byteLength <= 6.- Returns: <integer>
Reads byteLength number of bytes from buf at the specified offset
and interprets the result as an unsigned big-endian integer supporting
up to 48 bits of accuracy.
This function is also available under the readUintBE alias.
import { Buffer } from 'node:buffer';
const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]);
console.log(buf.readUIntBE(0, 6).toString(16));
// Prints: 1234567890ab
console.log(buf.readUIntBE(1, 6).toString(16));
// Throws ERR_OUT_OF_RANGE.const { Buffer } = require('node:buffer');
const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]);
console.log(buf.readUIntBE(0, 6).toString(16));
// Prints: 1234567890ab
console.log(buf.readUIntBE(1, 6).toString(16));
// Throws ERR_OUT_OF_RANGE.
buf.readUIntLE(offset, byteLength)#
offset<integer> Number of bytes to skip before starting to read. Must satisfy0 <= offset <= buf.length - byteLength.byteLength<integer> Number of bytes to read. Must satisfy0 < byteLength <= 6.- Returns: <integer>
Reads byteLength number of bytes from buf at the specified offset
and interprets the result as an unsigned, little-endian integer supporting
up to 48 bits of accuracy.
This function is also available under the readUintLE alias.
import { Buffer } from 'node:buffer';
const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]);
console.log(buf.readUIntLE(0, 6).toString(16));
// Prints: ab9078563412const { Buffer } = require('node:buffer');
const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]);
console.log(buf.readUIntLE(0, 6).toString(16));
// Prints: ab9078563412
buf.subarray([start[, end]])#
start<integer> Where the newBufferwill start. Default:0.end<integer> Where the newBufferwill end (not inclusive). Default:buf.length.- Returns: <Buffer>
Returns a new Buffer that references the same memory as the original, but
offset and cropped by the start and end indices.
Specifying end greater than buf.length will return the same result as
that of end equal to buf.length.
This method is inherited from TypedArray.prototype.subarray().
Modifying the new Buffer slice will modify the memory in the original Buffer
because the allocated memory of the two objects overlap.
import { Buffer } from 'node:buffer';
// Create a `Buffer` with the ASCII alphabet, take a slice, and modify one byte
// from the original `Buffer`.
const buf1 = Buffer.allocUnsafe(26);
for (let i = 0; i < 26; i++) {
// 97 is the decimal ASCII value for 'a'.
buf1[i] = i + 97;
}
const buf2 = buf1.subarray(0, 3);
console.log(buf2.toString('ascii', 0, buf2.length));
// Prints: abc
buf1[0] = 33;
console.log(buf2.toString('ascii', 0, buf2.length));
// Prints: !bcconst { Buffer } = require('node:buffer');
// Create a `Buffer` with the ASCII alphabet, take a slice, and modify one byte
// from the original `Buffer`.
const buf1 = Buffer.allocUnsafe(26);
for (let i = 0; i < 26; i++) {
// 97 is the decimal ASCII value for 'a'.
buf1[i] = i + 97;
}
const buf2 = buf1.subarray(0, 3);
console.log(buf2.toString('ascii', 0, buf2.length));
// Prints: abc
buf1[0] = 33;
console.log(buf2.toString('ascii', 0, buf2.length));
// Prints: !bc
Specifying negative indexes causes the slice to be generated relative to the
end of buf rather than the beginning.
import { Buffer } from 'node:buffer';
const buf = Buffer.from('buffer');
console.log(buf.subarray(-6, -1).toString());
// Prints: buffe
// (Equivalent to buf.subarray(0, 5).)
console.log(buf.subarray(-6, -2).toString());
// Prints: buff
// (Equivalent to buf.subarray(0, 4).)
console.log(buf.subarray(-5, -2).toString());
// Prints: uff
// (Equivalent to buf.subarray(1, 4).)const { Buffer } = require('node:buffer');
const buf = Buffer.from('buffer');
console.log(buf.subarray(-6, -1).toString());
// Prints: buffe
// (Equivalent to buf.subarray(0, 5).)
console.log(buf.subarray(-6, -2).toString());
// Prints: buff
// (Equivalent to buf.subarray(0, 4).)
console.log(buf.subarray(-5, -2).toString());
// Prints: uff
// (Equivalent to buf.subarray(1, 4).)
buf.slice([start[, end]])#
start<integer> Where the newBufferwill start. Default:0.end<integer> Where the newBufferwill end (not inclusive). Default:buf.length.- Returns: <Buffer>
buf.subarray instead.Returns a new Buffer that references the same memory as the original, but
offset and cropped by the start and end indices.
This method is not compatible with the Uint8Array.prototype.slice(),
which is a superclass of Buffer. To copy the slice, use
Uint8Array.prototype.slice().
import { Buffer } from 'node:buffer';
const buf = Buffer.from('buffer');
const copiedBuf = Uint8Array.prototype.slice.call(buf);
copiedBuf[0]++;
console.log(copiedBuf.toString());
// Prints: cuffer
console.log(buf.toString());
// Prints: buffer
// With buf.slice(), the original buffer is modified.
const notReallyCopiedBuf = buf.slice();
notReallyCopiedBuf[0]++;
console.log(notReallyCopiedBuf.toString());
// Prints: cuffer
console.log(buf.toString());
// Also prints: cuffer (!)const { Buffer } = require('node:buffer');
const buf = Buffer.from('buffer');
const copiedBuf = Uint8Array.prototype.slice.call(buf);
copiedBuf[0]++;
console.log(copiedBuf.toString());
// Prints: cuffer
console.log(buf.toString());
// Prints: buffer
// With buf.slice(), the original buffer is modified.
const notReallyCopiedBuf = buf.slice();
notReallyCopiedBuf[0]++;
console.log(notReallyCopiedBuf.toString());
// Prints: cuffer
console.log(buf.toString());
// Also prints: cuffer (!)
buf.swap16()#
- Returns: <Buffer> A reference to
buf.
Interprets buf as an array of unsigned 16-bit integers and swaps the
byte order in-place. Throws ERR_INVALID_BUFFER_SIZE if buf.length
is not a multiple of 2.
import { Buffer } from 'node:buffer';
const buf1 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]);
console.log(buf1);
// Prints: <Buffer 01 02 03 04 05 06 07 08>
buf1.swap16();
console.log(buf1);
// Prints: <Buffer 02 01 04 03 06 05 08 07>
const buf2 = Buffer.from([0x1, 0x2, 0x3]);
buf2.swap16();
// Throws ERR_INVALID_BUFFER_SIZE.const { Buffer } = require('node:buffer');
const buf1 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]);
console.log(buf1);
// Prints: <Buffer 01 02 03 04 05 06 07 08>
buf1.swap16();
console.log(buf1);
// Prints: <Buffer 02 01 04 03 06 05 08 07>
const buf2 = Buffer.from([0x1, 0x2, 0x3]);
buf2.swap16();
// Throws ERR_INVALID_BUFFER_SIZE.
One convenient use of buf.swap16() is to perform a fast in-place conversion
between UTF-16 little-endian and UTF-16 big-endian:
import { Buffer } from 'node:buffer';
const buf = Buffer.from('This is little-endian UTF-16', 'utf16le');
buf.swap16(); // Convert to big-endian UTF-16 text.const { Buffer } = require('node:buffer');
const buf = Buffer.from('This is little-endian UTF-16', 'utf16le');
buf.swap16(); // Convert to big-endian UTF-16 text.
buf.swap32()#
- Returns: <Buffer> A reference to
buf.
Interprets buf as an array of unsigned 32-bit integers and swaps the
byte order in-place. Throws ERR_INVALID_BUFFER_SIZE if buf.length
is not a multiple of 4.
import { Buffer } from 'node:buffer';
const buf1 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]);
console.log(buf1);
// Prints: <Buffer 01 02 03 04 05 06 07 08>
buf1.swap32();
console.log(buf1);
// Prints: <Buffer 04 03 02 01 08 07 06 05>
const buf2 = Buffer.from([0x1, 0x2, 0x3]);
buf2.swap32();
// Throws ERR_INVALID_BUFFER_SIZE.const { Buffer } = require('node:buffer');
const buf1 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]);
console.log(buf1);
// Prints: <Buffer 01 02 03 04 05 06 07 08>
buf1.swap32();
console.log(buf1);
// Prints: <Buffer 04 03 02 01 08 07 06 05>
const buf2 = Buffer.from([0x1, 0x2, 0x3]);
buf2.swap32();
// Throws ERR_INVALID_BUFFER_SIZE.
buf.swap64()#
- Returns: <Buffer> A reference to
buf.
Interprets buf as an array of 64-bit numbers and swaps byte order in-place.
Throws ERR_INVALID_BUFFER_SIZE if buf.length is not a multiple of 8.
import { Buffer } from 'node:buffer';
const buf1 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]);
console.log(buf1);
// Prints: <Buffer 01 02 03 04 05 06 07 08>
buf1.swap64();
console.log(buf1);
// Prints: <Buffer 08 07 06 05 04 03 02 01>
const buf2 = Buffer.from([0x1, 0x2, 0x3]);
buf2.swap64();
// Throws ERR_INVALID_BUFFER_SIZE.const { Buffer } = require('node:buffer');
const buf1 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]);
console.log(buf1);
// Prints: <Buffer 01 02 03 04 05 06 07 08>
buf1.swap64();
console.log(buf1);
// Prints: <Buffer 08 07 06 05 04 03 02 01>
const buf2 = Buffer.from([0x1, 0x2, 0x3]);
buf2.swap64();
// Throws ERR_INVALID_BUFFER_SIZE.
buf.toJSON()#
- Returns: <Object>
Returns a JSON representation of buf. JSON.stringify() implicitly calls
this function when stringifying a Buffer instance.
Buffer.from() accepts objects in the format returned from this method.
In particular, Buffer.from(buf.toJSON()) works like Buffer.from(buf).
import { Buffer } from 'node:buffer';
const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5]);
const json = JSON.stringify(buf);
console.log(json);
// Prints: {"type":"Buffer","data":[1,2,3,4,5]}
const copy = JSON.parse(json, (key, value) => {
return value && value.type === 'Buffer' ?
Buffer.from(value) :
value;
});
console.log(copy);
// Prints: <Buffer 01 02 03 04 05>const { Buffer } = require('node:buffer');
const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5]);
const json = JSON.stringify(buf);
console.log(json);
// Prints: {"type":"Buffer","data":[1,2,3,4,5]}
const copy = JSON.parse(json, (key, value) => {
return value && value.type === 'Buffer' ?
Buffer.from(value) :
value;
});
console.log(copy);
// Prints: <Buffer 01 02 03 04 05>
buf.toString([encoding[, start[, end]]])#
encoding<string> The character encoding to use. Default:'utf8'.start<integer> The byte offset to start decoding at. Default:0.end<integer> The byte offset to stop decoding at (not inclusive). Default:buf.length.- Returns: <string>
Decodes buf to a string according to the specified character encoding in
encoding. start and end may be passed to decode only a subset of buf.
If encoding is 'utf8' and a byte sequence in the input is not valid UTF-8,
then each invalid byte is replaced with the replacement character U+FFFD.
The maximum length of a string instance (in UTF-16 code units) is available
as buffer.constants.MAX_STRING_LENGTH.
import { Buffer } from 'node:buffer';
const buf1 = Buffer.allocUnsafe(26);
for (let i = 0; i < 26; i++) {
// 97 is the decimal ASCII value for 'a'.
buf1[i] = i + 97;
}
console.log(buf1.toString('utf8'));
// Prints: abcdefghijklmnopqrstuvwxyz
console.log(buf1.toString('utf8', 0, 5));
// Prints: abcde
const buf2 = Buffer.from('tést');
console.log(buf2.toString('hex'));
// Prints: 74c3a97374
console.log(buf2.toString('utf8', 0, 3));
// Prints: té
console.log(buf2.toString(undefined, 0, 3));
// Prints: téconst { Buffer } = require('node:buffer');
const buf1 = Buffer.allocUnsafe(26);
for (let i = 0; i < 26; i++) {
// 97 is the decimal ASCII value for 'a'.
buf1[i] = i + 97;
}
console.log(buf1.toString('utf8'));
// Prints: abcdefghijklmnopqrstuvwxyz
console.log(buf1.toString('utf8', 0, 5));
// Prints: abcde
const buf2 = Buffer.from('tést');
console.log(buf2.toString('hex'));
// Prints: 74c3a97374
console.log(buf2.toString('utf8', 0, 3));
// Prints: té
console.log(buf2.toString(undefined, 0, 3));
// Prints: té
buf.values()#
- Returns: <Iterator>
Creates and returns an iterator for buf values (bytes). This function is
called automatically when a Buffer is used in a for..of statement.
import { Buffer } from 'node:buffer';
const buf = Buffer.from('buffer');
for (const value of buf.values()) {
console.log(value);
}
// Prints:
// 98
// 117
// 102
// 102
// 101
// 114
for (const value of buf) {
console.log(value);
}
// Prints:
// 98
// 117
// 102
// 102
// 101
// 114const { Buffer } = require('node:buffer');
const buf = Buffer.from('buffer');
for (const value of buf.values()) {
console.log(value);
}
// Prints:
// 98
// 117
// 102
// 102
// 101
// 114
for (const value of buf) {
console.log(value);
}
// Prints:
// 98
// 117
// 102
// 102
// 101
// 114
buf.write(string[, offset[, length]][, encoding])#
string<string> String to write tobuf.offset<integer> Number of bytes to skip before starting to writestring. Default:0.length<integer> Maximum number of bytes to write (written bytes will not exceedbuf.length - offset). Default:buf.length - offset.encoding<string> The character encoding ofstring. Default:'utf8'.- Returns: <integer> Number of bytes written.
Writes string to buf at offset according to the character encoding in
encoding. The length parameter is the number of bytes to write. If buf did
not contain enough space to fit the entire string, only part of string will be
written. However, partially encoded characters will not be written.
import { Buffer } from 'node:buffer';
const buf = Buffer.alloc(256);
const len = buf.write('\u00bd + \u00bc = \u00be', 0);
console.log(`${len} bytes: ${buf.toString('utf8', 0, len)}`);
// Prints: 12 bytes: ½ + ¼ = ¾
const buffer = Buffer.alloc(10);
const length = buffer.write('abcd', 8);
console.log(`${length} bytes: ${buffer.toString('utf8', 8, 10)}`);
// Prints: 2 bytes : abconst { Buffer } = require('node:buffer');
const buf = Buffer.alloc(256);
const len = buf.write('\u00bd + \u00bc = \u00be', 0);
console.log(`${len} bytes: ${buf.toString('utf8', 0, len)}`);
// Prints: 12 bytes: ½ + ¼ = ¾
const buffer = Buffer.alloc(10);
const length = buffer.write('abcd', 8);
console.log(`${length} bytes: ${buffer.toString('utf8', 8, 10)}`);
// Prints: 2 bytes : ab
buf.writeBigInt64BE(value[, offset])#
value<bigint> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy:0 <= offset <= buf.length - 8. Default:0.- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset as big-endian.
value is interpreted and written as a two's complement signed integer.
import { Buffer } from 'node:buffer';
const buf = Buffer.allocUnsafe(8);
buf.writeBigInt64BE(0x0102030405060708n, 0);
console.log(buf);
// Prints: <Buffer 01 02 03 04 05 06 07 08>const { Buffer } = require('node:buffer');
const buf = Buffer.allocUnsafe(8);
buf.writeBigInt64BE(0x0102030405060708n, 0);
console.log(buf);
// Prints: <Buffer 01 02 03 04 05 06 07 08>
buf.writeBigInt64LE(value[, offset])#
value<bigint> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy:0 <= offset <= buf.length - 8. Default:0.- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset as little-endian.
value is interpreted and written as a two's complement signed integer.
import { Buffer } from 'node:buffer';
const buf = Buffer.allocUnsafe(8);
buf.writeBigInt64LE(0x0102030405060708n, 0);
console.log(buf);
// Prints: <Buffer 08 07 06 05 04 03 02 01>const { Buffer } = require('node:buffer');
const buf = Buffer.allocUnsafe(8);
buf.writeBigInt64LE(0x0102030405060708n, 0);
console.log(buf);
// Prints: <Buffer 08 07 06 05 04 03 02 01>
buf.writeBigUInt64BE(value[, offset])#
value<bigint> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy:0 <= offset <= buf.length - 8. Default:0.- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset as big-endian.
This function is also available under the writeBigUint64BE alias.
import { Buffer } from 'node:buffer';
const buf = Buffer.allocUnsafe(8);
buf.writeBigUInt64BE(0xdecafafecacefaden, 0);
console.log(buf);
// Prints: <Buffer de ca fa fe ca ce fa de>const { Buffer } = require('node:buffer');
const buf = Buffer.allocUnsafe(8);
buf.writeBigUInt64BE(0xdecafafecacefaden, 0);
console.log(buf);
// Prints: <Buffer de ca fa fe ca ce fa de>
buf.writeBigUInt64LE(value[, offset])#
value<bigint> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy:0 <= offset <= buf.length - 8. Default:0.- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset as little-endian
import { Buffer } from 'node:buffer';
const buf = Buffer.allocUnsafe(8);
buf.writeBigUInt64LE(0xdecafafecacefaden, 0);
console.log(buf);
// Prints: <Buffer de fa ce ca fe fa ca de>const { Buffer } = require('node:buffer');
const buf = Buffer.allocUnsafe(8);
buf.writeBigUInt64LE(0xdecafafecacefaden, 0);
console.log(buf);
// Prints: <Buffer de fa ce ca fe fa ca de>
This function is also available under the writeBigUint64LE alias.
buf.writeDoubleBE(value[, offset])#
value<number> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy0 <= offset <= buf.length - 8. Default:0.- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset as big-endian. The value
must be a JavaScript number. Behavior is undefined when value is anything
other than a JavaScript number.
import { Buffer } from 'node:buffer';
const buf = Buffer.allocUnsafe(8);
buf.writeDoubleBE(123.456, 0);
console.log(buf);
// Prints: <Buffer 40 5e dd 2f 1a 9f be 77>const { Buffer } = require('node:buffer');
const buf = Buffer.allocUnsafe(8);
buf.writeDoubleBE(123.456, 0);
console.log(buf);
// Prints: <Buffer 40 5e dd 2f 1a 9f be 77>
buf.writeDoubleLE(value[, offset])#
value<number> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy0 <= offset <= buf.length - 8. Default:0.- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset as little-endian. The value
must be a JavaScript number. Behavior is undefined when value is anything
other than a JavaScript number.
import { Buffer } from 'node:buffer';
const buf = Buffer.allocUnsafe(8);
buf.writeDoubleLE(123.456, 0);
console.log(buf);
// Prints: <Buffer 77 be 9f 1a 2f dd 5e 40>const { Buffer } = require('node:buffer');
const buf = Buffer.allocUnsafe(8);
buf.writeDoubleLE(123.456, 0);
console.log(buf);
// Prints: <Buffer 77 be 9f 1a 2f dd 5e 40>
buf.writeFloatBE(value[, offset])#
value<number> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy0 <= offset <= buf.length - 4. Default:0.- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset as big-endian. Behavior is
undefined when value is anything other than a JavaScript number.
import { Buffer } from 'node:buffer';
const buf = Buffer.allocUnsafe(4);
buf.writeFloatBE(0xcafebabe, 0);
console.log(buf);
// Prints: <Buffer 4f 4a fe bb>const { Buffer } = require('node:buffer');
const buf = Buffer.allocUnsafe(4);
buf.writeFloatBE(0xcafebabe, 0);
console.log(buf);
// Prints: <Buffer 4f 4a fe bb>
buf.writeFloatLE(value[, offset])#
value<number> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy0 <= offset <= buf.length - 4. Default:0.- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset as little-endian. Behavior is
undefined when value is anything other than a JavaScript number.
import { Buffer } from 'node:buffer';
const buf = Buffer.allocUnsafe(4);
buf.writeFloatLE(0xcafebabe, 0);
console.log(buf);
// Prints: <Buffer bb fe 4a 4f>const { Buffer } = require('node:buffer');
const buf = Buffer.allocUnsafe(4);
buf.writeFloatLE(0xcafebabe, 0);
console.log(buf);
// Prints: <Buffer bb fe 4a 4f>
buf.writeInt8(value[, offset])#
value<integer> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy0 <= offset <= buf.length - 1. Default:0.- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset. value must be a valid
signed 8-bit integer. Behavior is undefined when value is anything other than
a signed 8-bit integer.
value is interpreted and written as a two's complement signed integer.
import { Buffer } from 'node:buffer';
const buf = Buffer.allocUnsafe(2);
buf.writeInt8(2, 0);
buf.writeInt8(-2, 1);
console.log(buf);
// Prints: <Buffer 02 fe>const { Buffer } = require('node:buffer');
const buf = Buffer.allocUnsafe(2);
buf.writeInt8(2, 0);
buf.writeInt8(-2, 1);
console.log(buf);
// Prints: <Buffer 02 fe>
buf.writeInt16BE(value[, offset])#
value<integer> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy0 <= offset <= buf.length - 2. Default:0.- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset as big-endian. The value
must be a valid signed 16-bit integer. Behavior is undefined when value is
anything other than a signed 16-bit integer.
The value is interpreted and written as a two's complement signed integer.
import { Buffer } from 'node:buffer';
const buf = Buffer.allocUnsafe(2);
buf.writeInt16BE(0x0102, 0);
console.log(buf);
// Prints: <Buffer 01 02>const { Buffer } = require('node:buffer');
const buf = Buffer.allocUnsafe(2);
buf.writeInt16BE(0x0102, 0);
console.log(buf);
// Prints: <Buffer 01 02>
buf.writeInt16LE(value[, offset])#
value<integer> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy0 <= offset <= buf.length - 2. Default:0.- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset as little-endian. The value
must be a valid signed 16-bit integer. Behavior is undefined when value is
anything other than a signed 16-bit integer.
The value is interpreted and written as a two's complement signed integer.
import { Buffer } from 'node:buffer';
const buf = Buffer.allocUnsafe(2);
buf.writeInt16LE(0x0304, 0);
console.log(buf);
// Prints: <Buffer 04 03>const { Buffer } = require('node:buffer');
const buf = Buffer.allocUnsafe(2);
buf.writeInt16LE(0x0304, 0);
console.log(buf);
// Prints: <Buffer 04 03>
buf.writeInt32BE(value[, offset])#
value<integer> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy0 <= offset <= buf.length - 4. Default:0.- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset as big-endian. The value
must be a valid signed 32-bit integer. Behavior is undefined when value is
anything other than a signed 32-bit integer.
The value is interpreted and written as a two's complement signed integer.
import { Buffer } from 'node:buffer';
const buf = Buffer.allocUnsafe(4);
buf.writeInt32BE(0x01020304, 0);
console.log(buf);
// Prints: <Buffer 01 02 03 04>const { Buffer } = require('node:buffer');
const buf = Buffer.allocUnsafe(4);
buf.writeInt32BE(0x01020304, 0);
console.log(buf);
// Prints: <Buffer 01 02 03 04>
buf.writeInt32LE(value[, offset])#
value<integer> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy0 <= offset <= buf.length - 4. Default:0.- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset as little-endian. The value
must be a valid signed 32-bit integer. Behavior is undefined when value is
anything other than a signed 32-bit integer.
The value is interpreted and written as a two's complement signed integer.
import { Buffer } from 'node:buffer';
const buf = Buffer.allocUnsafe(4);
buf.writeInt32LE(0x05060708, 0);
console.log(buf);
// Prints: <Buffer 08 07 06 05>const { Buffer } = require('node:buffer');
const buf = Buffer.allocUnsafe(4);
buf.writeInt32LE(0x05060708, 0);
console.log(buf);
// Prints: <Buffer 08 07 06 05>
buf.writeIntBE(value, offset, byteLength)#
value<integer> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy0 <= offset <= buf.length - byteLength.byteLength<integer> Number of bytes to write. Must satisfy0 < byteLength <= 6.- Returns: <integer>
offsetplus the number of bytes written.
Writes byteLength bytes of value to buf at the specified offset
as big-endian. Supports up to 48 bits of accuracy. Behavior is undefined when
value is anything other than a signed integer.
import { Buffer } from 'node:buffer';
const buf = Buffer.allocUnsafe(6);
buf.writeIntBE(0x1234567890ab, 0, 6);
console.log(buf);
// Prints: <Buffer 12 34 56 78 90 ab>const { Buffer } = require('node:buffer');
const buf = Buffer.allocUnsafe(6);
buf.writeIntBE(0x1234567890ab, 0, 6);
console.log(buf);
// Prints: <Buffer 12 34 56 78 90 ab>
buf.writeIntLE(value, offset, byteLength)#
value<integer> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy0 <= offset <= buf.length - byteLength.byteLength<integer> Number of bytes to write. Must satisfy0 < byteLength <= 6.- Returns: <integer>
offsetplus the number of bytes written.
Writes byteLength bytes of value to buf at the specified offset
as little-endian. Supports up to 48 bits of accuracy. Behavior is undefined
when value is anything other than a signed integer.
import { Buffer } from 'node:buffer';
const buf = Buffer.allocUnsafe(6);
buf.writeIntLE(0x1234567890ab, 0, 6);
console.log(buf);
// Prints: <Buffer ab 90 78 56 34 12>const { Buffer } = require('node:buffer');
const buf = Buffer.allocUnsafe(6);
buf.writeIntLE(0x1234567890ab, 0, 6);
console.log(buf);
// Prints: <Buffer ab 90 78 56 34 12>
buf.writeUInt8(value[, offset])#
value<integer> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy0 <= offset <= buf.length - 1. Default:0.- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset. value must be a
valid unsigned 8-bit integer. Behavior is undefined when value is anything
other than an unsigned 8-bit integer.
This function is also available under the writeUint8 alias.
import { Buffer } from 'node:buffer';
const buf = Buffer.allocUnsafe(4);
buf.writeUInt8(0x3, 0);
buf.writeUInt8(0x4, 1);
buf.writeUInt8(0x23, 2);
buf.writeUInt8(0x42, 3);
console.log(buf);
// Prints: <Buffer 03 04 23 42>const { Buffer } = require('node:buffer');
const buf = Buffer.allocUnsafe(4);
buf.writeUInt8(0x3, 0);
buf.writeUInt8(0x4, 1);
buf.writeUInt8(0x23, 2);
buf.writeUInt8(0x42, 3);
console.log(buf);
// Prints: <Buffer 03 04 23 42>
buf.writeUInt16BE(value[, offset])#
value<integer> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy0 <= offset <= buf.length - 2. Default:0.- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset as big-endian. The value
must be a valid unsigned 16-bit integer. Behavior is undefined when value
is anything other than an unsigned 16-bit integer.
This function is also available under the writeUint16BE alias.
import { Buffer } from 'node:buffer';
const buf = Buffer.allocUnsafe(4);
buf.writeUInt16BE(0xdead, 0);
buf.writeUInt16BE(0xbeef, 2);
console.log(buf);
// Prints: <Buffer de ad be ef>const { Buffer } = require('node:buffer');
const buf = Buffer.allocUnsafe(4);
buf.writeUInt16BE(0xdead, 0);
buf.writeUInt16BE(0xbeef, 2);
console.log(buf);
// Prints: <Buffer de ad be ef>
buf.writeUInt16LE(value[, offset])#
value<integer> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy0 <= offset <= buf.length - 2. Default:0.- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset as little-endian. The value
must be a valid unsigned 16-bit integer. Behavior is undefined when value is
anything other than an unsigned 16-bit integer.
This function is also available under the writeUint16LE alias.
import { Buffer } from 'node:buffer';
const buf = Buffer.allocUnsafe(4);
buf.writeUInt16LE(0xdead, 0);
buf.writeUInt16LE(0xbeef, 2);
console.log(buf);
// Prints: <Buffer ad de ef be>const { Buffer } = require('node:buffer');
const buf = Buffer.allocUnsafe(4);
buf.writeUInt16LE(0xdead, 0);
buf.writeUInt16LE(0xbeef, 2);
console.log(buf);
// Prints: <Buffer ad de ef be>
buf.writeUInt32BE(value[, offset])#
value<integer> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy0 <= offset <= buf.length - 4. Default:0.- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset as big-endian. The value
must be a valid unsigned 32-bit integer. Behavior is undefined when value
is anything other than an unsigned 32-bit integer.
This function is also available under the writeUint32BE alias.
import { Buffer } from 'node:buffer';
const buf = Buffer.allocUnsafe(4);
buf.writeUInt32BE(0xfeedface, 0);
console.log(buf);
// Prints: <Buffer fe ed fa ce>const { Buffer } = require('node:buffer');
const buf = Buffer.allocUnsafe(4);
buf.writeUInt32BE(0xfeedface, 0);
console.log(buf);
// Prints: <Buffer fe ed fa ce>
buf.writeUInt32LE(value[, offset])#
value<integer> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy0 <= offset <= buf.length - 4. Default:0.- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset as little-endian. The value
must be a valid unsigned 32-bit integer. Behavior is undefined when value is
anything other than an unsigned 32-bit integer.
This function is also available under the writeUint32LE alias.
import { Buffer } from 'node:buffer';
const buf = Buffer.allocUnsafe(4);
buf.writeUInt32LE(0xfeedface, 0);
console.log(buf);
// Prints: <Buffer ce fa ed fe>const { Buffer } = require('node:buffer');
const buf = Buffer.allocUnsafe(4);
buf.writeUInt32LE(0xfeedface, 0);
console.log(buf);
// Prints: <Buffer ce fa ed fe>
buf.writeUIntBE(value, offset, byteLength)#
value<integer> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy0 <= offset <= buf.length - byteLength.byteLength<integer> Number of bytes to write. Must satisfy0 < byteLength <= 6.- Returns: <integer>
offsetplus the number of bytes written.
Writes byteLength bytes of value to buf at the specified offset
as big-endian. Supports up to 48 bits of accuracy. Behavior is undefined
when value is anything other than an unsigned integer.
This function is also available under the writeUintBE alias.
import { Buffer } from 'node:buffer';
const buf = Buffer.allocUnsafe(6);
buf.writeUIntBE(0x1234567890ab, 0, 6);
console.log(buf);
// Prints: <Buffer 12 34 56 78 90 ab>const { Buffer } = require('node:buffer');
const buf = Buffer.allocUnsafe(6);
buf.writeUIntBE(0x1234567890ab, 0, 6);
console.log(buf);
// Prints: <Buffer 12 34 56 78 90 ab>
buf.writeUIntLE(value, offset, byteLength)#
value<integer> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy0 <= offset <= buf.length - byteLength.byteLength<integer> Number of bytes to write. Must satisfy0 < byteLength <= 6.- Returns: <integer>
offsetplus the number of bytes written.
Writes byteLength bytes of value to buf at the specified offset
as little-endian. Supports up to 48 bits of accuracy. Behavior is undefined
when value is anything other than an unsigned integer.
This function is also available under the writeUintLE alias.
import { Buffer } from 'node:buffer';
const buf = Buffer.allocUnsafe(6);
buf.writeUIntLE(0x1234567890ab, 0, 6);
console.log(buf);
// Prints: <Buffer ab 90 78 56 34 12>const { Buffer } = require('node:buffer');
const buf = Buffer.allocUnsafe(6);
buf.writeUIntLE(0x1234567890ab, 0, 6);
console.log(buf);
// Prints: <Buffer ab 90 78 56 34 12>
new Buffer(array)#
Buffer.from(array) instead.array<integer[]> An array of bytes to copy from.
See Buffer.from(array).
new Buffer(arrayBuffer[, byteOffset[, length]])#
Buffer.from(arrayBuffer[, byteOffset[, length]])
instead.arrayBuffer<ArrayBuffer> | <SharedArrayBuffer> AnArrayBuffer,SharedArrayBufferor the.bufferproperty of aTypedArray.byteOffset<integer> Index of first byte to expose. Default:0.length<integer> Number of bytes to expose. Default:arrayBuffer.byteLength - byteOffset.
See
Buffer.from(arrayBuffer[, byteOffset[, length]]).
new Buffer(buffer)#
Buffer.from(buffer) instead.buffer<Buffer> | <Uint8Array> An existingBufferorUint8Arrayfrom which to copy data.
See Buffer.from(buffer).
new Buffer(size)#
size<integer> The desired length of the newBuffer.
See Buffer.alloc() and Buffer.allocUnsafe(). This variant of the
constructor is equivalent to Buffer.alloc().
new Buffer(string[, encoding])#
Buffer.from(string[, encoding]) instead.node:buffer module APIs#
While, the Buffer object is available as a global, there are additional
Buffer-related APIs that are available only via the node:buffer module
accessed using require('node:buffer').
buffer.atob(data)#
Buffer.from(data, 'base64') instead.data<any> The Base64-encoded input string.
Decodes a string of Base64-encoded data into bytes, and encodes those bytes into a string using Latin-1 (ISO-8859-1).
The data may be any JavaScript-value that can be coerced into a string.
This function is only provided for compatibility with legacy web platform APIs
and should never be used in new code, because they use strings to represent
binary data and predate the introduction of typed arrays in JavaScript.
For code running using Node.js APIs, converting between base64-encoded strings
and binary data should be performed using Buffer.from(str, 'base64') and
buf.toString('base64').
buffer.btoa(data)#
buf.toString('base64') instead.data<any> An ASCII (Latin1) string.
Decodes a string into bytes using Latin-1 (ISO-8859), and encodes those bytes into a string using Base64.
The data may be any JavaScript-value that can be coerced into a string.
This function is only provided for compatibility with legacy web platform APIs
and should never be used in new code, because they use strings to represent
binary data and predate the introduction of typed arrays in JavaScript.
For code running using Node.js APIs, converting between base64-encoded strings
and binary data should be performed using Buffer.from(str, 'base64') and
buf.toString('base64').
buffer.INSPECT_MAX_BYTES#
- <integer> Default:
50
Returns the maximum number of bytes that will be returned when
buf.inspect() is called. This can be overridden by user modules. See
util.inspect() for more details on buf.inspect() behavior.
buffer.kMaxLength#
- <integer> The largest size allowed for a single
Bufferinstance.
An alias for buffer.constants.MAX_LENGTH.
buffer.kStringMaxLength#
- <integer> The largest length allowed for a single
stringinstance.
An alias for buffer.constants.MAX_STRING_LENGTH.
buffer.resolveObjectURL(id)#
id<string> A'blob:nodedata:...URL string returned by a prior call toURL.createObjectURL().- Returns: <Blob>
Resolves a 'blob:nodedata:...' an associated <Blob> object registered using
a prior call to URL.createObjectURL().
buffer.transcode(source, fromEnc, toEnc)#
source<Buffer> | <Uint8Array> ABufferorUint8Arrayinstance.fromEnc<string> The current encoding.toEnc<string> To target encoding.- Returns: <Buffer>
Re-encodes the given Buffer or Uint8Array instance from one character
encoding to another. Returns a new Buffer instance.
Throws if the fromEnc or toEnc specify invalid character encodings or if
conversion from fromEnc to toEnc is not permitted.
Encodings supported by buffer.transcode() are: 'ascii', 'utf8',
'utf16le', 'ucs2', 'latin1', and 'binary'.
The transcoding process will use substitution characters if a given byte sequence cannot be adequately represented in the target encoding. For instance:
import { Buffer, transcode } from 'node:buffer';
const newBuf = transcode(Buffer.from('€'), 'utf8', 'ascii');
console.log(newBuf.toString('ascii'));
// Prints: '?'const { Buffer, transcode } = require('node:buffer');
const newBuf = transcode(Buffer.from('€'), 'utf8', 'ascii');
console.log(newBuf.toString('ascii'));
// Prints: '?'
Because the Euro (€) sign is not representable in US-ASCII, it is replaced
with ? in the transcoded Buffer.
Class: SlowBuffer#
Buffer.allocUnsafeSlow() instead.See Buffer.allocUnsafeSlow(). This was never a class in the sense that
the constructor always returned a Buffer instance, rather than a SlowBuffer
instance.
new SlowBuffer(size)#
Buffer.allocUnsafeSlow() instead.size<integer> The desired length of the newSlowBuffer.
Buffer constants#
buffer.constants.MAX_LENGTH#
- <integer> The largest size allowed for a single
Bufferinstance.
On 32-bit architectures, this value currently is 230 - 1 (about 1 GiB).
On 64-bit architectures, this value currently is 232 (about 4 GiB).
It reflects v8::TypedArray::kMaxLength under the hood.
This value is also available as buffer.kMaxLength.
buffer.constants.MAX_STRING_LENGTH#
- <integer> The largest length allowed for a single
stringinstance.
Represents the largest length that a string primitive can have, counted
in UTF-16 code units.
This value may depend on the JS engine that is being used.
Buffer.from(), Buffer.alloc(), and Buffer.allocUnsafe()#
In versions of Node.js prior to 6.0.0, Buffer instances were created using the
Buffer constructor function, which allocates the returned Buffer
differently based on what arguments are provided:
- Passing a number as the first argument to
Buffer()(e.g.new Buffer(10)) allocates a newBufferobject of the specified size. Prior to Node.js 8.0.0, the memory allocated for suchBufferinstances is not initialized and can contain sensitive data. SuchBufferinstances must be subsequently initialized by using eitherbuf.fill(0)or by writing to the entireBufferbefore reading data from theBuffer. While this behavior is intentional to improve performance, development experience has demonstrated that a more explicit distinction is required between creating a fast-but-uninitializedBufferversus creating a slower-but-saferBuffer. Since Node.js 8.0.0,Buffer(num)andnew Buffer(num)return aBufferwith initialized memory. - Passing a string, array, or
Bufferas the first argument copies the passed object's data into theBuffer. - Passing an
ArrayBufferor aSharedArrayBufferreturns aBufferthat shares allocated memory with the given array buffer.
Because the behavior of new Buffer() is different depending on the type of the
first argument, security and reliability issues can be inadvertently introduced
into applications when argument validation or Buffer initialization is not
performed.
For example, if an attacker can cause an application to receive a number where
a string is expected, the application may call new Buffer(100)
instead of new Buffer("100"), leading it to allocate a 100 byte buffer instead
of allocating a 3 byte buffer with content "100". This is commonly possible
using JSON API calls. Since JSON distinguishes between numeric and string types,
it allows injection of numbers where a naively written application that does not
validate its input sufficiently might expect to always receive a string.
Before Node.js 8.0.0, the 100 byte buffer might contain
arbitrary pre-existing in-memory data, so may be used to expose in-memory
secrets to a remote attacker. Since Node.js 8.0.0, exposure of memory cannot
occur because the data is zero-filled. However, other attacks are still
possible, such as causing very large buffers to be allocated by the server,
leading to performance degradation or crashing on memory exhaustion.
To make the creation of Buffer instances more reliable and less error-prone,
the various forms of the new Buffer() constructor have been deprecated
and replaced by separate Buffer.from(), Buffer.alloc(), and
Buffer.allocUnsafe() methods.
Developers should migrate all existing uses of the new Buffer() constructors
to one of these new APIs.
Buffer.from(array)returns a newBufferthat contains a copy of the provided octets.Buffer.from(arrayBuffer[, byteOffset[, length]])returns a newBufferthat shares the same allocated memory as the givenArrayBuffer.Buffer.from(buffer)returns a newBufferthat contains a copy of the contents of the givenBuffer.Buffer.from(string[, encoding])returns a newBufferthat contains a copy of the provided string.Buffer.alloc(size[, fill[, encoding]])returns a new initializedBufferof the specified size. This method is slower thanBuffer.allocUnsafe(size)but guarantees that newly createdBufferinstances never contain old data that is potentially sensitive. ATypeErrorwill be thrown ifsizeis not a number.Buffer.allocUnsafe(size)andBuffer.allocUnsafeSlow(size)each return a new uninitializedBufferof the specifiedsize. Because theBufferis uninitialized, the allocated segment of memory might contain old data that is potentially sensitive.
Buffer instances returned by Buffer.allocUnsafe() and
Buffer.from(array) may be allocated off a shared internal memory pool
if size is less than or equal to half Buffer.poolSize. Instances
returned by Buffer.allocUnsafeSlow() never use the shared internal
memory pool.
The --zero-fill-buffers command-line option#
Node.js can be started using the --zero-fill-buffers command-line option to
cause all newly-allocated Buffer instances to be zero-filled upon creation by
default. Without the option, buffers created with Buffer.allocUnsafe(),
Buffer.allocUnsafeSlow(), and new SlowBuffer(size) are not zero-filled.
Use of this flag can have a measurable negative impact on performance. Use the
--zero-fill-buffers option only when necessary to enforce that newly allocated
Buffer instances cannot contain old data that is potentially sensitive.
$ node --zero-fill-buffers
> Buffer.allocUnsafe(5);
<Buffer 00 00 00 00 00>
What makes Buffer.allocUnsafe() and Buffer.allocUnsafeSlow() "unsafe"?#
When calling Buffer.allocUnsafe() and Buffer.allocUnsafeSlow(), the
segment of allocated memory is uninitialized (it is not zeroed-out). While
this design makes the allocation of memory quite fast, the allocated segment of
memory might contain old data that is potentially sensitive. Using a Buffer
created by Buffer.allocUnsafe() without completely overwriting the
memory can allow this old data to be leaked when the Buffer memory is read.
While there are clear performance advantages to using
Buffer.allocUnsafe(), extra care must be taken in order to avoid
introducing security vulnerabilities into an application.
C++ addons#
Addons are dynamically-linked shared objects written in C++. The
require() function can load addons as ordinary Node.js modules.
Addons provide an interface between JavaScript and C/C++ libraries.
There are three options for implementing addons: Node-API, nan, or direct use of internal V8, libuv, and Node.js libraries. Unless there is a need for direct access to functionality which is not exposed by Node-API, use Node-API. Refer to C/C++ addons with Node-API for more information on Node-API.
When not using Node-API, implementing addons is complicated, involving knowledge of several components and APIs:
-
V8: the C++ library Node.js uses to provide the JavaScript implementation. V8 provides the mechanisms for creating objects, calling functions, etc. V8's API is documented mostly in the
v8.hheader file (deps/v8/include/v8.hin the Node.js source tree), which is also available online. -
libuv: The C library that implements the Node.js event loop, its worker threads and all of the asynchronous behaviors of the platform. It also serves as a cross-platform abstraction library, giving easy, POSIX-like access across all major operating systems to many common system tasks, such as interacting with the filesystem, sockets, timers, and system events. libuv also provides a threading abstraction similar to POSIX threads for more sophisticated asynchronous addons that need to move beyond the standard event loop. Addon authors should avoid blocking the event loop with I/O or other time-intensive tasks by offloading work via libuv to non-blocking system operations, worker threads, or a custom use of libuv threads.
-
Internal Node.js libraries. Node.js itself exports C++ APIs that addons can use, the most important of which is the
node::ObjectWrapclass. -
Node.js includes other statically linked libraries including OpenSSL. These other libraries are located in the
deps/directory in the Node.js source tree. Only the libuv, OpenSSL, V8, and zlib symbols are purposefully re-exported by Node.js and may be used to various extents by addons. See Linking to libraries included with Node.js for additional information.
All of the following examples are available for download and may be used as the starting-point for an addon.
Hello world#
This "Hello world" example is a simple addon, written in C++, that is the equivalent of the following JavaScript code:
module.exports.hello = () => 'world';
First, create the file hello.cc:
// hello.cc
#include <node.h>
namespace demo {
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Value;
void Method(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
args.GetReturnValue().Set(String::NewFromUtf8(
isolate, "world").ToLocalChecked());
}
void Initialize(Local<Object> exports) {
NODE_SET_METHOD(exports, "hello", Method);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
} // namespace demo
All Node.js addons must export an initialization function following the pattern:
void Initialize(Local<Object> exports);
NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
There is no semi-colon after NODE_MODULE as it's not a function (see
node.h).
The module_name must match the filename of the final binary (excluding
the .node suffix).
In the hello.cc example, then, the initialization function is Initialize
and the addon module name is addon.
When building addons with node-gyp, using the macro NODE_GYP_MODULE_NAME as
the first parameter of NODE_MODULE() will ensure that the name of the final
binary will be passed to NODE_MODULE().
Context-aware addons#
There are environments in which Node.js addons may need to be loaded multiple
times in multiple contexts. For example, the Electron runtime runs multiple
instances of Node.js in a single process. Each instance will have its own
require() cache, and thus each instance will need a native addon to behave
correctly when loaded via require(). This means that the addon
must support multiple initializations.
A context-aware addon can be constructed by using the macro
NODE_MODULE_INITIALIZER, which expands to the name of a function which Node.js
will expect to find when it loads an addon. An addon can thus be initialized as
in the following example:
using namespace v8;
extern "C" NODE_MODULE_EXPORT void
NODE_MODULE_INITIALIZER(Local<Object> exports,
Local<Value> module,
Local<Context> context) {
/* Perform addon initialization steps here. */
}
Another option is to use the macro NODE_MODULE_INIT(), which will also
construct a context-aware addon. Unlike NODE_MODULE(), which is used to
construct an addon around a given addon initializer function,
NODE_MODULE_INIT() serves as the declaration of such an initializer to be
followed by a function body.
The following three variables may be used inside the function body following an
invocation of NODE_MODULE_INIT():
Local<Object> exports,Local<Value> module, andLocal<Context> context
The choice to build a context-aware addon carries with it the responsibility of carefully managing global static data. Since the addon may be loaded multiple times, potentially even from different threads, any global static data stored in the addon must be properly protected, and must not contain any persistent references to JavaScript objects. The reason for this is that JavaScript objects are only valid in one context, and will likely cause a crash when accessed from the wrong context or from a different thread than the one on which they were created.
The context-aware addon can be structured to avoid global static data by performing the following steps:
- Define a class which will hold per-addon-instance data and which has a static
member of the form
static void DeleteInstance(void* data) { // Cast `data` to an instance of the class and delete it. } - Heap-allocate an instance of this class in the addon initializer. This can be
accomplished using the
newkeyword. - Call
node::AddEnvironmentCleanupHook(), passing it the above-created instance and a pointer toDeleteInstance(). This will ensure the instance is deleted when the environment is torn down. - Store the instance of the class in a
v8::External, and - Pass the
v8::Externalto all methods exposed to JavaScript by passing it tov8::FunctionTemplate::New()orv8::Function::New()which creates the native-backed JavaScript functions. The third parameter ofv8::FunctionTemplate::New()orv8::Function::New()accepts thev8::Externaland makes it available in the native callback using thev8::FunctionCallbackInfo::Data()method.
This will ensure that the per-addon-instance data reaches each binding that can be called from JavaScript. The per-addon-instance data must also be passed into any asynchronous callbacks the addon may create.
The following example illustrates the implementation of a context-aware addon:
#include <node.h>
using namespace v8;
class AddonData {
public:
explicit AddonData(Isolate* isolate):
call_count(0) {
// Ensure this per-addon-instance data is deleted at environment cleanup.
node::AddEnvironmentCleanupHook(isolate, DeleteInstance, this);
}
// Per-addon data.
int call_count;
static void DeleteInstance(void* data) {
delete static_cast<AddonData*>(data);
}
};
static void Method(const v8::FunctionCallbackInfo<v8::Value>& info) {
// Retrieve the per-addon-instance data.
AddonData* data =
reinterpret_cast<AddonData*>(info.Data().As<External>()->Value());
data->call_count++;
info.GetReturnValue().Set((double)data->call_count);
}
// Initialize this addon to be context-aware.
NODE_MODULE_INIT(/* exports, module, context */) {
Isolate* isolate = context->GetIsolate();
// Create a new instance of `AddonData` for this instance of the addon and
// tie its life cycle to that of the Node.js environment.
AddonData* data = new AddonData(isolate);
// Wrap the data in a `v8::External` so we can pass it to the method we
// expose.
Local<External> external = External::New(isolate, data);
// Expose the method `Method` to JavaScript, and make sure it receives the
// per-addon-instance data we created above by passing `external` as the
// third parameter to the `FunctionTemplate` constructor.
exports->Set(context,
String::NewFromUtf8(isolate, "method").ToLocalChecked(),
FunctionTemplate::New(isolate, Method, external)
->GetFunction(context).ToLocalChecked()).FromJust();
}
Worker support#
In order to be loaded from multiple Node.js environments, such as a main thread and a Worker thread, an add-on needs to either:
- Be an Node-API addon, or
- Be declared as context-aware using
NODE_MODULE_INIT()as described above
In order to support Worker threads, addons need to clean up any resources
they may have allocated when such a thread exists. This can be achieved through
the usage of the AddEnvironmentCleanupHook() function:
void AddEnvironmentCleanupHook(v8::Isolate* isolate,
void (*fun)(void* arg),
void* arg);
This function adds a hook that will run before a given Node.js instance shuts
down. If necessary, such hooks can be removed before they are run using
RemoveEnvironmentCleanupHook(), which has the same signature. Callbacks are
run in last-in first-out order.
If necessary, there is an additional pair of AddEnvironmentCleanupHook()
and RemoveEnvironmentCleanupHook() overloads, where the cleanup hook takes a
callback function. This can be used for shutting down asynchronous resources,
such as any libuv handles registered by the addon.
The following addon.cc uses AddEnvironmentCleanupHook:
// addon.cc
#include <node.h>
#include <assert.h>
#include <stdlib.h>
using node::AddEnvironmentCleanupHook;
using v8::HandleScope;
using v8::Isolate;
using v8::Local;
using v8::Object;
// Note: In a real-world application, do not rely on static/global data.
static char cookie[] = "yum yum";
static int cleanup_cb1_called = 0;
static int cleanup_cb2_called = 0;
static void cleanup_cb1(void* arg) {
Isolate* isolate = static_cast<Isolate*>(arg);
HandleScope scope(isolate);
Local<Object> obj = Object::New(isolate);
assert(!obj.IsEmpty()); // assert VM is still alive
assert(obj->IsObject());
cleanup_cb1_called++;
}
static void cleanup_cb2(void* arg) {
assert(arg == static_cast<void*>(cookie));
cleanup_cb2_called++;
}
static void sanity_check(void*) {
assert(cleanup_cb1_called == 1);
assert(cleanup_cb2_called == 1);
}
// Initialize this addon to be context-aware.
NODE_MODULE_INIT(/* exports, module, context */) {
Isolate* isolate = context->GetIsolate();
AddEnvironmentCleanupHook(isolate, sanity_check, nullptr);
AddEnvironmentCleanupHook(isolate, cleanup_cb2, cookie);
AddEnvironmentCleanupHook(isolate, cleanup_cb1, isolate);
}
Test in JavaScript by running:
// test.js
require('./build/Release/addon');
Building#
Once the source code has been written, it must be compiled into the binary
addon.node file. To do so, create a file called binding.gyp in the
top-level of the project describing the build configuration of the module
using a JSON-like format. This file is used by node-gyp, a tool written
specifically to compile Node.js addons.
{
"targets": [
{
"target_name": "addon",
"sources": [ "hello.cc" ]
}
]
}
A version of the node-gyp utility is bundled and distributed with
Node.js as part of npm. This version is not made directly available for
developers to use and is intended only to support the ability to use the
npm install command to compile and install addons. Developers who wish to
use node-gyp directly can install it using the command
npm install -g node-gyp. See the node-gyp installation instructions for
more information, including platform-specific requirements.
Once the binding.gyp file has been created, use node-gyp configure to
generate the appropriate project build files for the current platform. This
will generate either a Makefile (on Unix platforms) or a vcxproj file
(on Windows) in the build/ directory.
Next, invoke the node-gyp build command to generate the compiled addon.node
file. This will be put into the build/Release/ directory.
When using npm install to install a Node.js addon, npm uses its own bundled
version of node-gyp to perform this same set of actions, generating a
compiled version of the addon for the user's platform on demand.
Once built, the binary addon can be used from within Node.js by pointing
require() to the built addon.node module:
// hello.js
const addon = require('./build/Release/addon');
console.log(addon.hello());
// Prints: 'world'
Because the exact path to the compiled addon binary can vary depending on how
it is compiled (i.e. sometimes it may be in ./build/Debug/), addons can use
the bindings package to load the compiled module.
While the bindings package implementation is more sophisticated in how it
locates addon modules, it is essentially using a try…catch pattern similar to:
try {
return require('./build/Release/addon.node');
} catch (err) {
return require('./build/Debug/addon.node');
}
Linking to libraries included with Node.js#
Node.js uses statically linked libraries such as V8, libuv, and OpenSSL. All
addons are required to link to V8 and may link to any of the other dependencies
as well. Typically, this is as simple as including the appropriate
#include <...> statements (e.g. #include <v8.h>) and node-gyp will locate
the appropriate headers automatically. However, there are a few caveats to be
aware of:
-
When
node-gypruns, it will detect the specific release version of Node.js and download either the full source tarball or just the headers. If the full source is downloaded, addons will have complete access to the full set of Node.js dependencies. However, if only the Node.js headers are downloaded, then only the symbols exported by Node.js will be available. -
node-gypcan be run using the--nodedirflag pointing at a local Node.js source image. Using this option, the addon will have access to the full set of dependencies.
Loading addons using require()#
The filename extension of the compiled addon binary is .node (as opposed
to .dll or .so). The require() function is written to look for
files with the .node file extension and initialize those as dynamically-linked
libraries.
When calling require(), the .node extension can usually be
omitted and Node.js will still find and initialize the addon. One caveat,
however, is that Node.js will first attempt to locate and load modules or
JavaScript files that happen to share the same base name. For instance, if
there is a file addon.js in the same directory as the binary addon.node,
then require('addon') will give precedence to the addon.js file
and load it instead.
Native abstractions for Node.js#
Each of the examples illustrated in this document directly use the Node.js and V8 APIs for implementing addons. The V8 API can, and has, changed dramatically from one V8 release to the next (and one major Node.js release to the next). With each change, addons may need to be updated and recompiled in order to continue functioning. The Node.js release schedule is designed to minimize the frequency and impact of such changes but there is little that Node.js can do to ensure stability of the V8 APIs.
The Native Abstractions for Node.js (or nan) provide a set of tools that
addon developers are recommended to use to keep compatibility between past and
future releases of V8 and Node.js. See the nan examples for an
illustration of how it can be used.
Node-API#
Node-API is an API for building native addons. It is independent from the underlying JavaScript runtime (e.g. V8) and is maintained as part of Node.js itself. This API will be Application Binary Interface (ABI) stable across versions of Node.js. It is intended to insulate addons from changes in the underlying JavaScript engine and allow modules compiled for one version to run on later versions of Node.js without recompilation. Addons are built/packaged with the same approach/tools outlined in this document (node-gyp, etc.). The only difference is the set of APIs that are used by the native code. Instead of using the V8 or Native Abstractions for Node.js APIs, the functions available in the Node-API are used.
Creating and maintaining an addon that benefits from the ABI stability provided by Node-API carries with it certain implementation considerations.
To use Node-API in the above "Hello world" example, replace the content of
hello.cc with the following. All other instructions remain the same.
// hello.cc using Node-API
#include <node_api.h>
namespace demo {
napi_value Method(napi_env env, napi_callback_info args) {
napi_value greeting;
napi_status status;
status = napi_create_string_utf8(env, "world", NAPI_AUTO_LENGTH, &greeting);
if (status != napi_ok) return nullptr;
return greeting;
}
napi_value init(napi_env env, napi_value exports) {
napi_status status;
napi_value fn;
status = napi_create_function(env, nullptr, 0, Method, nullptr, &fn);
if (status != napi_ok) return nullptr;
status = napi_set_named_property(env, exports, "hello", fn);
if (status != napi_ok) return nullptr;
return exports;
}
NAPI_MODULE(NODE_GYP_MODULE_NAME, init)
} // namespace demo
The functions available and how to use them are documented in C/C++ addons with Node-API.
Addon examples#
Following are some example addons intended to help developers get started. The examples use the V8 APIs. Refer to the online V8 reference for help with the various V8 calls, and V8's Embedder's Guide for an explanation of several concepts used such as handles, scopes, function templates, etc.
Each of these examples using the following binding.gyp file:
{
"targets": [
{
"target_name": "addon",
"sources": [ "addon.cc" ]
}
]
}
In cases where there is more than one .cc file, simply add the additional
filename to the sources array:
"sources": ["addon.cc", "myexample.cc"]
Once the binding.gyp file is ready, the example addons can be configured and
built using node-gyp:
$ node-gyp configure build
Function arguments#
Addons will typically expose objects and functions that can be accessed from JavaScript running within Node.js. When functions are invoked from JavaScript, the input arguments and return value must be mapped to and from the C/C++ code.
The following example illustrates how to read function arguments passed from JavaScript and how to return a result:
// addon.cc
#include <node.h>
namespace demo {
using v8::Exception;
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::String;
using v8::Value;
// This is the implementation of the "add" method
// Input arguments are passed using the
// const FunctionCallbackInfo<Value>& args struct
void Add(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
// Check the number of arguments passed.
if (args.Length() < 2) {
// Throw an Error that is passed back to JavaScript
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8(isolate,
"Wrong number of arguments").ToLocalChecked()));
return;
}
// Check the argument types
if (!args[0]->IsNumber() || !args[1]->IsNumber()) {
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8(isolate,
"Wrong arguments").ToLocalChecked()));
return;
}
// Perform the operation
double value =
args[0].As<Number>()->Value() + args[1].As<Number>()->Value();
Local<Number> num = Number::New(isolate, value);
// Set the return value (using the passed in
// FunctionCallbackInfo<Value>&)
args.GetReturnValue().Set(num);
}
void Init(Local<Object> exports) {
NODE_SET_METHOD(exports, "add", Add);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, Init)
} // namespace demo
Once compiled, the example addon can be required and used from within Node.js:
// test.js
const addon = require('./build/Release/addon');
console.log('This should be eight:', addon.add(3, 5));
Callbacks#
It is common practice within addons to pass JavaScript functions to a C++ function and execute them from there. The following example illustrates how to invoke such callbacks:
// addon.cc
#include <node.h>
namespace demo {
using v8::Context;
using v8::Function;
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Null;
using v8::Object;
using v8::String;
using v8::Value;
void RunCallback(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
Local<Function> cb = Local<Function>::Cast(args[0]);
const unsigned argc = 1;
Local<Value> argv[argc] = {
String::NewFromUtf8(isolate,
"hello world").ToLocalChecked() };
cb->Call(context, Null(isolate), argc, argv).ToLocalChecked();
}
void Init(Local<Object> exports, Local<Object> module) {
NODE_SET_METHOD(module, "exports", RunCallback);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, Init)
} // namespace demo
This example uses a two-argument form of Init() that receives the full
module object as the second argument. This allows the addon to completely
overwrite exports with a single function instead of adding the function as a
property of exports.
To test it, run the following JavaScript:
// test.js
const addon = require('./build/Release/addon');
addon((msg) => {
console.log(msg);
// Prints: 'hello world'
});
In this example, the callback function is invoked synchronously.
Object factory#
Addons can create and return new objects from within a C++ function as
illustrated in the following example. An object is created and returned with a
property msg that echoes the string passed to createObject():
// addon.cc
#include <node.h>
namespace demo {
using v8::Context;
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Value;
void CreateObject(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
Local<Object> obj = Object::New(isolate);
obj->Set(context,
String::NewFromUtf8(isolate,
"msg").ToLocalChecked(),
args[0]->ToString(context).ToLocalChecked())
.FromJust();
args.GetReturnValue().Set(obj);
}
void Init(Local<Object> exports, Local<Object> module) {
NODE_SET_METHOD(module, "exports", CreateObject);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, Init)
} // namespace demo
To test it in JavaScript:
// test.js
const addon = require('./build/Release/addon');
const obj1 = addon('hello');
const obj2 = addon('world');
console.log(obj1.msg, obj2.msg);
// Prints: 'hello world'
Function factory#
Another common scenario is creating JavaScript functions that wrap C++ functions and returning those back to JavaScript:
// addon.cc
#include <node.h>
namespace demo {
using v8::Context;
using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Value;
void MyFunction(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
args.GetReturnValue().Set(String::NewFromUtf8(
isolate, "hello world").ToLocalChecked());
}
void CreateFunction(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, MyFunction);
Local<Function> fn = tpl->GetFunction(context).ToLocalChecked();
// omit this to make it anonymous
fn->SetName(String::NewFromUtf8(
isolate, "theFunction").ToLocalChecked());
args.GetReturnValue().Set(fn);
}
void Init(Local<Object> exports, Local<Object> module) {
NODE_SET_METHOD(module, "exports", CreateFunction);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, Init)
} // namespace demo
To test:
// test.js
const addon = require('./build/Release/addon');
const fn = addon();
console.log(fn());
// Prints: 'hello world'
Wrapping C++ objects#
It is also possible to wrap C++ objects/classes in a way that allows new
instances to be created using the JavaScript new operator:
// addon.cc
#include <node.h>
#include "myobject.h"
namespace demo {
using v8::Local;
using v8::Object;
void InitAll(Local<Object> exports) {
MyObject::Init(exports);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, InitAll)
} // namespace demo
Then, in myobject.h, the wrapper class inherits from node::ObjectWrap:
// myobject.h
#ifndef MYOBJECT_H
#define MYOBJECT_H
#include <node.h>
#include <node_object_wrap.h>
namespace demo {
class MyObject : public node::ObjectWrap {
public:
static void Init(v8::Local<v8::Object> exports);
private:
explicit MyObject(double value = 0);
~MyObject();
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);
double value_;
};
} // namespace demo
#endif
In myobject.cc, implement the various methods that are to be exposed.
Below, the method plusOne() is exposed by adding it to the constructor's
prototype:
// myobject.cc
#include "myobject.h"
namespace demo {
using v8::Context;
using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Isolate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::ObjectTemplate;
using v8::String;
using v8::Value;
MyObject::MyObject(double value) : value_(value) {
}
MyObject::~MyObject() {
}
void MyObject::Init(Local<Object> exports) {
Isolate* isolate = exports->GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
Local<ObjectTemplate> addon_data_tpl = ObjectTemplate::New(isolate);
addon_data_tpl->SetInternalFieldCount(1); // 1 field for the MyObject::New()
Local<Object> addon_data =
addon_data_tpl->NewInstance(context).ToLocalChecked();
// Prepare constructor template
Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New, addon_data);
tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
// Prototype
NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne);
Local<Function> constructor = tpl->GetFunction(context).ToLocalChecked();
addon_data->SetInternalField(0, constructor);
exports->Set(context, String::NewFromUtf8(
isolate, "MyObject").ToLocalChecked(),
constructor).FromJust();
}
void MyObject::New(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
if (args.IsConstructCall()) {
// Invoked as constructor: `new MyObject(...)`
double value = args[0]->IsUndefined() ?
0 : args[0]->NumberValue(context).FromMaybe(0);
MyObject* obj = new MyObject(value);
obj->Wrap(args.This());
args.GetReturnValue().Set(args.This());
} else {
// Invoked as plain function `MyObject(...)`, turn into construct call.
const int argc = 1;
Local<Value> argv[argc] = { args[0] };
Local<Function> cons =
args.Data().As<Object>()->GetInternalField(0).As<Function>();
Local<Object> result =
cons->NewInstance(context, argc, argv).ToLocalChecked();
args.GetReturnValue().Set(result);
}
}
void MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder());
obj->value_ += 1;
args.GetReturnValue().Set(Number::New(isolate, obj->value_));
}
} // namespace demo
To build this example, the myobject.cc file must be added to the
binding.gyp:
{
"targets": [
{
"target_name": "addon",
"sources": [
"addon.cc",
"myobject.cc"
]
}
]
}
Test it with:
// test.js
const addon = require('./build/Release/addon');
const obj = new addon.MyObject(10);
console.log(obj.plusOne());
// Prints: 11
console.log(obj.plusOne());
// Prints: 12
console.log(obj.plusOne());
// Prints: 13
The destructor for a wrapper object will run when the object is garbage-collected. For destructor testing, there are command-line flags that can be used to make it possible to force garbage collection. These flags are provided by the underlying V8 JavaScript engine. They are subject to change or removal at any time. They are not documented by Node.js or V8, and they should never be used outside of testing.
During shutdown of the process or worker threads destructors are not called by the JS engine. Therefore it's the responsibility of the user to track these objects and ensure proper destruction to avoid resource leaks.
Factory of wrapped objects#
Alternatively, it is possible to use a factory pattern to avoid explicitly
creating object instances using the JavaScript new operator:
const obj = addon.createObject();
// instead of:
// const obj = new addon.Object();
First, the createObject() method is implemented in addon.cc:
// addon.cc
#include <node.h>
#include "myobject.h"
namespace demo {
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Value;
void CreateObject(const FunctionCallbackInfo<Value>& args) {
MyObject::NewInstance(args);
}
void InitAll(Local<Object> exports, Local<Object> module) {
MyObject::Init(exports->GetIsolate());
NODE_SET_METHOD(module, "exports", CreateObject);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, InitAll)
} // namespace demo
In myobject.h, the static method NewInstance() is added to handle
instantiating the object. This method takes the place of using new in
JavaScript:
// myobject.h
#ifndef MYOBJECT_H
#define MYOBJECT_H
#include <node.h>
#include <node_object_wrap.h>
namespace demo {
class MyObject : public node::ObjectWrap {
public:
static void Init(v8::Isolate* isolate);
static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);
private:
explicit MyObject(double value = 0);
~MyObject();
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);
static v8::Global<v8::Function> constructor;
double value_;
};
} // namespace demo
#endif
The implementation in myobject.cc is similar to the previous example:
// myobject.cc
#include <node.h>
#include "myobject.h"
namespace demo {
using node::AddEnvironmentCleanupHook;
using v8::Context;
using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Global;
using v8::Isolate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::String;
using v8::Value;
// Warning! This is not thread-safe, this addon cannot be used for worker
// threads.
Global<Function> MyObject::constructor;
MyObject::MyObject(double value) : value_(value) {
}
MyObject::~MyObject() {
}
void MyObject::Init(Isolate* isolate) {
// Prepare constructor template
Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);
tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
// Prototype
NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne);
Local<Context> context = isolate->GetCurrentContext();
constructor.Reset(isolate, tpl->GetFunction(context).ToLocalChecked());
AddEnvironmentCleanupHook(isolate, [](void*) {
constructor.Reset();
}, nullptr);
}
void MyObject::New(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
if (args.IsConstructCall()) {
// Invoked as constructor: `new MyObject(...)`
double value = args[0]->IsUndefined() ?
0 : args[0]->NumberValue(context).FromMaybe(0);
MyObject* obj = new MyObject(value);
obj->Wrap(args.This());
args.GetReturnValue().Set(args.This());
} else {
// Invoked as plain function `MyObject(...)`, turn into construct call.
const int argc = 1;
Local<Value> argv[argc] = { args[0] };
Local<Function> cons = Local<Function>::New(isolate, constructor);
Local<Object> instance =
cons->NewInstance(context, argc, argv).ToLocalChecked();
args.GetReturnValue().Set(instance);
}
}
void MyObject::NewInstance(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
const unsigned argc = 1;
Local<Value> argv[argc] = { args[0] };
Local<Function> cons = Local<Function>::New(isolate, constructor);
Local<Context> context = isolate->GetCurrentContext();
Local<Object> instance =
cons->NewInstance(context, argc, argv).ToLocalChecked();
args.GetReturnValue().Set(instance);
}
void MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder());
obj->value_ += 1;
args.GetReturnValue().Set(Number::New(isolate, obj->value_));
}
} // namespace demo
Once again, to build this example, the myobject.cc file must be added to the
binding.gyp:
{
"targets": [
{
"target_name": "addon",
"sources": [
"addon.cc",
"myobject.cc"
]
}
]
}
Test it with:
// test.js
const createObject = require('./build/Release/addon');
const obj = createObject(10);
console.log(obj.plusOne());
// Prints: 11
console.log(obj.plusOne());
// Prints: 12
console.log(obj.plusOne());
// Prints: 13
const obj2 = createObject(20);
console.log(obj2.plusOne());
// Prints: 21
console.log(obj2.plusOne());
// Prints: 22
console.log(obj2.plusOne());
// Prints: 23
Passing wrapped objects around#
In addition to wrapping and returning C++ objects, it is possible to pass
wrapped objects around by unwrapping them with the Node.js helper function
node::ObjectWrap::Unwrap. The following examples shows a function add()
that can take two MyObject objects as input arguments:
// addon.cc
#include <node.h>
#include <node_object_wrap.h>
#include "myobject.h"
namespace demo {
using v8::Context;
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::String;
using v8::Value;
void CreateObject(const FunctionCallbackInfo<Value>& args) {
MyObject::NewInstance(args);
}
void Add(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
MyObject* obj1 = node::ObjectWrap::Unwrap<MyObject>(
args[0]->ToObject(context).ToLocalChecked());
MyObject* obj2 = node::ObjectWrap::Unwrap<MyObject>(
args[1]->ToObject(context).ToLocalChecked());
double sum = obj1->value() + obj2->value();
args.GetReturnValue().Set(Number::New(isolate, sum));
}
void InitAll(Local<Object> exports) {
MyObject::Init(exports->GetIsolate());
NODE_SET_METHOD(exports, "createObject", CreateObject);
NODE_SET_METHOD(exports, "add", Add);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, InitAll)
} // namespace demo
In myobject.h, a new public method is added to allow access to private values
after unwrapping the object.
// myobject.h
#ifndef MYOBJECT_H
#define MYOBJECT_H
#include <node.h>
#include <node_object_wrap.h>
namespace demo {
class MyObject : public node::ObjectWrap {
public:
static void Init(v8::Isolate* isolate);
static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);
inline double value() const { return value_; }
private:
explicit MyObject(double value = 0);
~MyObject();
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
static v8::Global<v8::Function> constructor;
double value_;
};
} // namespace demo
#endif
The implementation of myobject.cc is similar to before:
// myobject.cc
#include <node.h>
#include "myobject.h"
namespace demo {
using node::AddEnvironmentCleanupHook;
using v8::Context;
using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Global;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Value;
// Warning! This is not thread-safe, this addon cannot be used for worker
// threads.
Global<Function> MyObject::constructor;
MyObject::MyObject(double value) : value_(value) {
}
MyObject::~MyObject() {
}
void MyObject::Init(Isolate* isolate) {
// Prepare constructor template
Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);
tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
Local<Context> context = isolate->GetCurrentContext();
constructor.Reset(isolate, tpl->GetFunction(context).ToLocalChecked());
AddEnvironmentCleanupHook(isolate, [](void*) {
constructor.Reset();
}, nullptr);
}
void MyObject::New(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
if (args.IsConstructCall()) {
// Invoked as constructor: `new MyObject(...)`
double value = args[0]->IsUndefined() ?
0 : args[0]->NumberValue(context).FromMaybe(0);
MyObject* obj = new MyObject(value);
obj->Wrap(args.This());
args.GetReturnValue().Set(args.This());
} else {
// Invoked as plain function `MyObject(...)`, turn into construct call.
const int argc = 1;
Local<Value> argv[argc] = { args[0] };
Local<Function> cons = Local<Function>::New(isolate, constructor);
Local<Object> instance =
cons->NewInstance(context, argc, argv).ToLocalChecked();
args.GetReturnValue().Set(instance);
}
}
void MyObject::NewInstance(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
const unsigned argc = 1;
Local<Value> argv[argc] = { args[0] };
Local<Function> cons = Local<Function>::New(isolate, constructor);
Local<Context> context = isolate->GetCurrentContext();
Local<Object> instance =
cons->NewInstance(context, argc, argv).ToLocalChecked();
args.GetReturnValue().Set(instance);
}
} // namespace demo
Test it with:
// test.js
const addon = require('./build/Release/addon');
const obj1 = addon.createObject(10);
const obj2 = addon.createObject(20);
const result = addon.add(obj1, obj2);
console.log(result);
// Prints: 30Node-API#
Node-API (formerly N-API) is an API for building native Addons. It is independent from the underlying JavaScript runtime (for example, V8) and is maintained as part of Node.js itself. This API will be Application Binary Interface (ABI) stable across versions of Node.js. It is intended to insulate addons from changes in the underlying JavaScript engine and allow modules compiled for one major version to run on later major versions of Node.js without recompilation. The ABI Stability guide provides a more in-depth explanation.
Addons are built/packaged with the same approach/tools outlined in the section titled C++ Addons. The only difference is the set of APIs that are used by the native code. Instead of using the V8 or Native Abstractions for Node.js APIs, the functions available in Node-API are used.
APIs exposed by Node-API are generally used to create and manipulate JavaScript values. Concepts and operations generally map to ideas specified in the ECMA-262 Language Specification. The APIs have the following properties:
- All Node-API calls return a status code of type
napi_status. This status indicates whether the API call succeeded or failed. - The API's return value is passed via an out parameter.
- All JavaScript values are abstracted behind an opaque type named
napi_value. - In case of an error status code, additional information can be obtained
using
napi_get_last_error_info. More information can be found in the error handling section Error handling.
Node-API is a C API that ensures ABI stability across Node.js versions
and different compiler levels. A C++ API can be easier to use.
To support using C++, the project maintains a
C++ wrapper module called node-addon-api.
This wrapper provides an inlineable C++ API. Binaries built
with node-addon-api will depend on the symbols for the Node-API C-based
functions exported by Node.js. node-addon-api is a more
efficient way to write code that calls Node-API. Take, for example, the
following node-addon-api code. The first section shows the
node-addon-api code and the second section shows what actually gets
used in the addon.
Object obj = Object::New(env);
obj["foo"] = String::New(env, "bar");
napi_status status;
napi_value object, string;
status = napi_create_object(env, &object);
if (status != napi_ok) {
napi_throw_error(env, ...);
return;
}
status = napi_create_string_utf8(env, "bar", NAPI_AUTO_LENGTH, &string);
if (status != napi_ok) {
napi_throw_error(env, ...);
return;
}
status = napi_set_named_property(env, object, "foo", string);
if (status != napi_ok) {
napi_throw_error(env, ...);
return;
}
The end result is that the addon only uses the exported C APIs. As a result, it still gets the benefits of the ABI stability provided by the C API.
When using node-addon-api instead of the C APIs, start with the API docs
for node-addon-api.
The Node-API Resource offers
an excellent orientation and tips for developers just getting started with
Node-API and node-addon-api.
Implications of ABI stability#
Although Node-API provides an ABI stability guarantee, other parts of Node.js do not, and any external libraries used from the addon may not. In particular, none of the following APIs provide an ABI stability guarantee across major versions:
-
the Node.js C++ APIs available via any of
#include <node.h> #include <node_buffer.h> #include <node_version.h> #include <node_object_wrap.h> -
the libuv APIs which are also included with Node.js and available via
#include <uv.h> -
the V8 API available via
#include <v8.h>
Thus, for an addon to remain ABI-compatible across Node.js major versions, it must use Node-API exclusively by restricting itself to using
#include <node_api.h>
and by checking, for all external libraries that it uses, that the external library makes ABI stability guarantees similar to Node-API.
Building#
Unlike modules written in JavaScript, developing and deploying Node.js native addons using Node-API requires an additional set of tools. Besides the basic tools required to develop for Node.js, the native addon developer requires a toolchain that can compile C and C++ code into a binary. In addition, depending upon how the native addon is deployed, the user of the native addon will also need to have a C/C++ toolchain installed.
For Linux developers, the necessary C/C++ toolchain packages are readily available. GCC is widely used in the Node.js community to build and test across a variety of platforms. For many developers, the LLVM compiler infrastructure is also a good choice.