- Assertion Testing
- Async Hooks
- Buffer
- C++ Addons
- C/C++ Addons - N-API
- Child Processes
- Cluster
- Command Line Options
- Console
- Crypto
- Debugger
- Deprecated APIs
- DNS
- Domain
- ECMAScript Modules
- Errors
- Events
- File System
- Globals
- HTTP
- HTTP/2
- HTTPS
- Inspector
- Internationalization
- Modules
- Net
- OS
- Path
- Performance Hooks
- Process
- Punycode
- Query Strings
- Readline
- REPL
- Stream
- String Decoder
- Timers
- TLS/SSL
- Tracing
- TTY
- UDP/Datagram
- URL
- Utilities
- V8
- VM
- ZLIB
Node.js v8.17.0 Documentation
Table of Contents
- About this Documentation
- Usage
- Assert
- Strict mode
- Legacy mode
- assert(value[, message])
- assert.deepEqual(actual, expected[, message])
- assert.deepStrictEqual(actual, expected[, message])
- assert.doesNotReject(block[, error][, message])
- assert.doesNotThrow(block[, error][, message])
- assert.equal(actual, expected[, message])
- assert.fail(message)
- assert.fail(actual, expected[, message[, operator[, stackStartFunction]]])
- assert.ifError(value)
- 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.strictEqual(actual, expected[, message])
- assert.rejects(block[, error][, message])
- assert.throws(block[, error][, message])
- Caveats
- Async Hooks
- Buffer
Buffer.from(),Buffer.alloc(), andBuffer.allocUnsafe()- Buffers and Character Encodings
- Buffers and TypedArray
- Buffers and iteration
- Class: Buffer
- new Buffer(array)
- new Buffer(arrayBuffer[, byteOffset[, length]])
- new Buffer(buffer)
- new Buffer(size)
- new Buffer(string[, encoding])
- Class Method: Buffer.alloc(size[, fill[, encoding]])
- Class Method: Buffer.allocUnsafe(size)
- Class Method: Buffer.allocUnsafeSlow(size)
- Class Method: Buffer.byteLength(string[, encoding])
- Class Method: Buffer.compare(buf1, buf2)
- Class Method: Buffer.concat(list[, totalLength])
- Class Method: Buffer.from(array)
- Class Method: Buffer.from(arrayBuffer[, byteOffset[, length]])
- Class Method: Buffer.from(buffer)
- Class Method: Buffer.from(string[, encoding])
- Class Method: Buffer.from(object[, offsetOrEncoding[, length]])
- Class Method: Buffer.isBuffer(obj)
- Class Method: Buffer.isEncoding(encoding)
- Class Property: Buffer.poolSize
- buf[index]
- buf.buffer
- buf.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.length
- buf.parent
- buf.readDoubleBE(offset[, noAssert])
- buf.readDoubleLE(offset[, noAssert])
- buf.readFloatBE(offset[, noAssert])
- buf.readFloatLE(offset[, noAssert])
- buf.readInt8(offset[, noAssert])
- buf.readInt16BE(offset[, noAssert])
- buf.readInt16LE(offset[, noAssert])
- buf.readInt32BE(offset[, noAssert])
- buf.readInt32LE(offset[, noAssert])
- buf.readIntBE(offset, byteLength[, noAssert])
- buf.readIntLE(offset, byteLength[, noAssert])
- buf.readUInt8(offset[, noAssert])
- buf.readUInt16BE(offset[, noAssert])
- buf.readUInt16LE(offset[, noAssert])
- buf.readUInt32BE(offset[, noAssert])
- buf.readUInt32LE(offset[, noAssert])
- buf.readUIntBE(offset, byteLength[, noAssert])
- buf.readUIntLE(offset, byteLength[, noAssert])
- 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.writeDoubleBE(value, offset[, noAssert])
- buf.writeDoubleLE(value, offset[, noAssert])
- buf.writeFloatBE(value, offset[, noAssert])
- buf.writeFloatLE(value, offset[, noAssert])
- buf.writeInt8(value, offset[, noAssert])
- buf.writeInt16BE(value, offset[, noAssert])
- buf.writeInt16LE(value, offset[, noAssert])
- buf.writeInt32BE(value, offset[, noAssert])
- buf.writeInt32LE(value, offset[, noAssert])
- buf.writeIntBE(value, offset, byteLength[, noAssert])
- buf.writeIntLE(value, offset, byteLength[, noAssert])
- buf.writeUInt8(value, offset[, noAssert])
- buf.writeUInt16BE(value, offset[, noAssert])
- buf.writeUInt16LE(value, offset[, noAssert])
- buf.writeUInt32BE(value, offset[, noAssert])
- buf.writeUInt32LE(value, offset[, noAssert])
- buf.writeUIntBE(value, offset, byteLength[, noAssert])
- buf.writeUIntLE(value, offset, byteLength[, noAssert])
- buffer.INSPECT_MAX_BYTES
- buffer.kMaxLength
- buffer.transcode(source, fromEnc, toEnc)
- Class: SlowBuffer
- Buffer Constants
- C++ Addons
- N-API
- Usage
- N-API Version Matrix
- Basic N-API Data Types
- Error Handling
- Object Lifetime management
- Module registration
- Working with JavaScript Values
- Enum types
- Object Creation Functions
- Functions to convert from C types to N-API
- Functions to convert from N-API to C types
- napi_get_array_length
- napi_get_arraybuffer_info
- napi_get_buffer_info
- napi_get_prototype
- napi_get_typedarray_info
- napi_get_dataview_info
- napi_get_value_bool
- napi_get_value_double
- napi_get_value_external
- napi_get_value_int32
- napi_get_value_int64
- napi_get_value_string_latin1
- napi_get_value_string_utf8
- napi_get_value_string_utf16
- napi_get_value_uint32
- Functions to get global instances
- Working with JavaScript Values - Abstract Operations
- Working with JavaScript Properties
- 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
- Child Process
- Asynchronous Process Creation
- Synchronous Process Creation
- Class: ChildProcess
- Event: 'close'
- Event: 'disconnect'
- Event: 'error'
- Event: 'exit'
- Event: 'message'
- subprocess.channel
- subprocess.connected
- subprocess.disconnect()
- subprocess.kill([signal])
- subprocess.killed
- subprocess.pid
- subprocess.send(message[, sendHandle[, options]][, callback])
- subprocess.stderr
- subprocess.stdin
- subprocess.stdio
- subprocess.stdout
maxBufferand Unicode- Shell Requirements
- Default Windows Shell
- Cluster
- How It Works
- Class: Worker
- Event: 'disconnect'
- Event: 'error'
- Event: 'exit'
- Event: 'listening'
- Event: 'message'
- Event: 'online'
- worker.disconnect()
- worker.exitedAfterDisconnect
- worker.id
- worker.isConnected()
- worker.isDead()
- worker.kill([signal='SIGTERM'])
- worker.process
- worker.send(message[, sendHandle][, callback])
- worker.suicide
- Event: 'disconnect'
- Event: 'exit'
- Event: 'fork'
- Event: 'listening'
- Event: 'message'
- Event: 'online'
- Event: 'setup'
- cluster.disconnect([callback])
- cluster.fork([env])
- cluster.isMaster
- cluster.isWorker
- cluster.schedulingPolicy
- cluster.settings
- cluster.setupMaster([settings])
- cluster.worker
- cluster.workers
- Command Line Options
- Synopsis
- Options
-v,--version-h,--help-e,--eval "script"-p,--print "script"-c,--check-i,--interactive-r,--require module--inspect[=[host:]port]--inspect-brk[=[host:]port]--inspect-port=[host:]port--no-deprecation--trace-deprecation--throw-deprecation--pending-deprecation--no-warnings--expose-http2--abort-on-uncaught-exception--trace-warnings--redirect-warnings=file--trace-sync-io--force-async-hooks-checks--trace-events-enabled--trace-event-categories--trace-event-file-pattern--zero-fill-buffers--preserve-symlinks--track-heap-objects--prof-process--v8-options--tls-cipher-list=list--enable-fips--force-fips--openssl-config=file--use-openssl-ca,--use-bundled-ca--icu-data-dir=file-----max-http-header-size=size
- Environment Variables
NODE_DEBUG=module[,…]NODE_PATH=path[:…]NODE_DISABLE_COLORS=1NODE_ICU_DATA=fileNODE_NO_WARNINGS=1NODE_NO_HTTP2=1NODE_OPTIONS=options...NODE_PENDING_DEPRECATION=1NODE_PRESERVE_SYMLINKS=1NODE_REPL_HISTORY=fileNODE_EXTRA_CA_CERTS=fileOPENSSL_CONF=fileSSL_CERT_DIR=dirSSL_CERT_FILE=fileNODE_REDIRECT_WARNINGS=fileUV_THREADPOOL_SIZE=size
- Console
- Class: Console
- new Console(stdout[, stderr])
- console.assert(value[, message][, ...args])
- console.clear()
- console.count([label])
- console.countReset([label='default'])
- console.debug(data[, ...args])
- console.dir(obj[, options])
- console.error([data][, ...args])
- console.group([...label])
- console.groupCollapsed()
- console.groupEnd()
- console.info([data][, ...args])
- console.log([data][, ...args])
- console.time(label)
- console.timeEnd(label)
- console.trace([message][, ...args])
- console.warn([data][, ...args])
- Inspector only methods
- Class: Console
- Crypto
- Determining if crypto support is unavailable
- Class: Certificate
- Class: Cipher
- Class: Decipher
- Class: DiffieHellman
- diffieHellman.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: ECDH
- Class: Hash
- Class: Hmac
- Class: Sign
- Class: Verify
cryptomodule methods and properties- crypto.constants
- crypto.DEFAULT_ENCODING
- crypto.fips
- crypto.createCipher(algorithm, password[, options])
- crypto.createCipheriv(algorithm, key, iv[, options])
- crypto.createCredentials(details)
- crypto.createDecipher(algorithm, password[, options])
- crypto.createDecipheriv(algorithm, key, iv[, options])
- crypto.createDiffieHellman(prime[, primeEncoding][, generator][, generatorEncoding])
- crypto.createDiffieHellman(primeLength[, generator])
- crypto.createECDH(curveName)
- crypto.createHash(algorithm[, options])
- crypto.createHmac(algorithm, key[, options])
- crypto.createSign(algorithm[, options])
- crypto.createVerify(algorithm[, options])
- crypto.getCiphers()
- crypto.getCurves()
- crypto.getDiffieHellman(groupName)
- crypto.getHashes()
- 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.setEngine(engine[, flags])
- crypto.timingSafeEqual(a, b)
- Notes
- Crypto Constants
- Debugger
- Deprecated APIs
- Un-deprecation
- List of Deprecated APIs
- DEP0001: http.OutgoingMessage.prototype.flush
- DEP0002: require('_linklist')
- DEP0003: _writableState.buffer
- DEP0004: CryptoStream.prototype.readyState
- DEP0005: Buffer() constructor
- DEP0006: child_process options.customFds
- DEP0007: cluster worker.suicide
- DEP0008: require('constants')
- DEP0009: crypto.pbkdf2 without digest
- DEP0010: crypto.createCredentials
- DEP0011: crypto.Credentials
- DEP0012: Domain.dispose
- DEP0013: fs asynchronous function without callback
- DEP0014: fs.read legacy String interface
- DEP0015: fs.readSync legacy 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('sys')
- DEP0026: util.print()
- DEP0027: util.puts()
- DEP0028: util.debug()
- DEP0029: util.error()
- DEP0030: SlowBuffer
- DEP0031: ecdh.setPublicKey()
- DEP0032: domain module
- 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: punycode module
- DEP0041: NODE_REPL_HISTORY_FILE environment 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_MAGIC and NODE_REPL_MODE=magic
- DEP0066: outgoingMessage._headers, outgoingMessage._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()
- DEP0076: tls.parseCertString()
- DEP0079: Custom inspection function on Objects via .inspect()
- DEP0085: AsyncHooks Sensitive API
- DEP0086: Remove runInAsyncIdScope
- DEP0089: require('assert')
- DEP0098: AsyncHooks Embedder AsyncResource.emit<Before,After> APIs
- 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.resolveCname(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.resolveAny(hostname, callback)
- dns.reverse(ip, callback)
- dns.setServers(servers)
- Error codes
- Implementation considerations
- Domain
- ECMAScript Modules
- Errors
- Error Propagation and Interception
- Class: Error
- Class: AssertionError
- Class: RangeError
- Class: ReferenceError
- Class: SyntaxError
- Class: TypeError
- Exceptions vs. Errors
- System Errors
- Node.js Error Codes
- ERR_ARG_NOT_ITERABLE
- ERR_ASYNC_CALLBACK
- ERR_ASYNC_TYPE
- ERR_ENCODING_INVALID_ENCODED_DATA
- ERR_ENCODING_NOT_SUPPORTED
- ERR_FALSY_VALUE_REJECTION
- ERR_HTTP_HEADERS_SENT
- ERR_HTTP_INVALID_CHAR
- ERR_HTTP_INVALID_STATUS_CODE
- ERR_HTTP_TRAILER_INVALID
- ERR_HTTP2_ALREADY_SHUTDOWN
- ERR_HTTP2_ALTSVC_INVALID_ORIGIN
- ERR_HTTP2_ALTSVC_LENGTH
- ERR_HTTP2_CONNECT_AUTHORITY
- ERR_HTTP2_CONNECT_PATH
- ERR_HTTP2_CONNECT_SCHEME
- ERR_HTTP2_FRAME_ERROR
- ERR_HTTP2_GOAWAY_SESSION
- ERR_HTTP2_HEADER_REQUIRED
- ERR_HTTP2_HEADER_SINGLE_VALUE
- ERR_HTTP2_HEADERS_AFTER_RESPOND
- ERR_HTTP2_HEADERS_OBJECT
- ERR_HTTP2_HEADERS_SENT
- ERR_HTTP2_INFO_HEADERS_AFTER_RESPOND
- ERR_HTTP2_INFO_STATUS_NOT_ALLOWED
- ERR_HTTP2_INVALID_CONNECTION_HEADERS
- ERR_HTTP2_INVALID_HEADER_VALUE
- ERR_HTTP2_INVALID_INFO_STATUS
- ERR_HTTP2_INVALID_ORIGIN
- ERR_HTTP2_INVALID_PACKED_SETTINGS_LENGTH
- ERR_HTTP2_INVALID_PSEUDOHEADER
- ERR_HTTP2_INVALID_SESSION
- ERR_HTTP2_INVALID_SETTING_VALUE
- ERR_HTTP2_INVALID_STREAM
- ERR_HTTP2_MAX_PENDING_SETTINGS_ACK
- ERR_HTTP2_NESTED_PUSH
- ERR_HTTP2_NO_SOCKET_MANIPULATION
- ERR_HTTP2_ORIGIN_LENGTH
- ERR_HTTP2_OUT_OF_STREAMS
- ERR_HTTP2_PAYLOAD_FORBIDDEN
- ERR_HTTP2_PING_CANCEL
- ERR_HTTP2_PING_LENGTH
- ERR_HTTP2_PSEUDOHEADER_NOT_ALLOWED
- ERR_HTTP2_PUSH_DISABLED
- ERR_HTTP2_SEND_FILE
- ERR_HTTP2_SESSION_ERROR
- ERR_HTTP2_SETTINGS_CANCEL
- ERR_HTTP2_SOCKET_BOUND
- ERR_HTTP2_SOCKET_UNBOUND
- ERR_HTTP2_STATUS_101
- ERR_HTTP2_STATUS_INVALID
- ERR_HTTP2_STREAM_CANCEL
- ERR_HTTP2_STREAM_ERROR
- ERR_HTTP2_STREAM_SELF_DEPENDENCY
- ERR_HTTP2_TRAILERS_ALREADY_SENT
- ERR_HTTP2_TRAILERS_NOT_READY
- ERR_HTTP2_UNSUPPORTED_PROTOCOL
- ERR_INDEX_OUT_OF_RANGE
- ERR_INVALID_ARG_TYPE
- ERR_INVALID_ASYNC_ID
- ERR_INVALID_CALLBACK
- ERR_INVALID_FILE_URL_HOST
- ERR_INVALID_FILE_URL_PATH
- ERR_INVALID_HANDLE_TYPE
- ERR_INVALID_OPT_VALUE
- ERR_INVALID_PERFORMANCE_MARK
- ERR_INVALID_PROTOCOL
- ERR_INVALID_SYNC_FORK_INPUT
- ERR_INVALID_THIS
- ERR_INVALID_TUPLE
- ERR_INVALID_URL
- ERR_INVALID_URL_SCHEME
- ERR_IPC_CHANNEL_CLOSED
- ERR_IPC_DISCONNECTED
- ERR_IPC_ONE_PIPE
- ERR_IPC_SYNC_FORK
- ERR_MISSING_ARGS
- ERR_MISSING_DYNAMIC_INSTANTIATE_HOOK
- ERR_MISSING_MODULE
- ERR_MODULE_RESOLUTION_LEGACY
- ERR_MULTIPLE_CALLBACK
- ERR_NAPI_CONS_FUNCTION
- ERR_NAPI_CONS_PROTOTYPE_OBJECT
- ERR_NAPI_INVALID_DATAVIEW_ARGS
- ERR_NAPI_INVALID_TYPEDARRAY_ALIGNMENT
- ERR_NAPI_INVALID_TYPEDARRAY_LENGTH
- ERR_NAPI_TSFN_CALL_JS
- ERR_NAPI_TSFN_GET_UNDEFINED
- ERR_NAPI_TSFN_START_IDLE_LOOP
- ERR_NAPI_TSFN_STOP_IDLE_LOOP
- ERR_NO_ICU
- ERR_SOCKET_ALREADY_BOUND
- ERR_SOCKET_BAD_PORT
- ERR_SOCKET_BAD_TYPE
- ERR_SOCKET_CANNOT_SEND
- ERR_SOCKET_CLOSED
- ERR_SOCKET_DGRAM_NOT_RUNNING
- ERR_STDERR_CLOSE
- ERR_STDOUT_CLOSE
- ERR_TLS_CERT_ALTNAME_INVALID
- ERR_TLS_DH_PARAM_SIZE
- ERR_TLS_HANDSHAKE_TIMEOUT
- ERR_TLS_RENEGOTIATION_FAILED
- ERR_TLS_REQUIRED_SERVER_NAME
- ERR_TLS_SESSION_ATTACK
- ERR_TRANSFORM_ALREADY_TRANSFORMING
- ERR_TRANSFORM_WITH_LENGTH_0
- ERR_UNKNOWN_SIGNAL
- ERR_UNKNOWN_STDIN_TYPE
- ERR_UNKNOWN_STREAM_TYPE
- ERR_V8BREAKITERATOR
- ERR_VALID_PERFORMANCE_ENTRY_TYPE
- ERR_VALUE_OUT_OF_RANGE
- Events
- Passing arguments and
thisto listeners - Asynchronous vs. Synchronous
- Handling events only once
- Error events
- Class: EventEmitter
- Event: 'newListener'
- Event: 'removeListener'
- EventEmitter.listenerCount(emitter, eventName)
- EventEmitter.defaultMaxListeners
- emitter.addListener(eventName, listener)
- emitter.emit(eventName[, ...args])
- emitter.eventNames()
- emitter.getMaxListeners()
- emitter.listenerCount(eventName)
- emitter.listeners(eventName)
- 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)
- Passing arguments and
- File System
- Threadpool Usage
- WHATWG URL object support
- Buffer API
- Class: fs.FSWatcher
- Class: fs.ReadStream
- Class: fs.Stats
- Class: fs.WriteStream
- fs.access(path[, mode], callback)
- fs.accessSync(path[, mode])
- fs.appendFile(file, data[, options], callback)
- fs.appendFileSync(file, data[, options])
- fs.chmod(path, mode, callback)
- fs.chmodSync(path, mode)
- fs.chown(path, uid, gid, callback)
- fs.chownSync(path, uid, gid)
- fs.close(fd, callback)
- fs.closeSync(fd)
- fs.constants
- fs.copyFile(src, dest[, flags], callback)
- fs.copyFileSync(src, dest[, flags])
- fs.createReadStream(path[, options])
- fs.createWriteStream(path[, options])
- fs.exists(path, callback)
- fs.existsSync(path)
- fs.fchmod(fd, mode, callback)
- fs.fchmodSync(fd, mode)
- fs.fchown(fd, uid, gid, callback)
- fs.fchownSync(fd, uid, gid)
- fs.fdatasync(fd, callback)
- fs.fdatasyncSync(fd)
- fs.fstat(fd, callback)
- fs.fstatSync(fd)
- fs.fsync(fd, callback)
- fs.fsyncSync(fd)
- fs.ftruncate(fd[, len], callback)
- fs.ftruncateSync(fd[, len])
- fs.futimes(fd, atime, mtime, callback)
- fs.futimesSync(fd, atime, mtime)
- fs.lchmod(path, mode, callback)
- fs.lchmodSync(path, mode)
- fs.lchown(path, uid, gid, callback)
- fs.lchownSync(path, uid, gid)
- fs.link(existingPath, newPath, callback)
- fs.linkSync(existingPath, newPath)
- fs.lstat(path, callback)
- fs.lstatSync(path)
- fs.mkdir(path[, mode], callback)
- fs.mkdirSync(path[, mode])
- fs.mkdtemp(prefix[, options], callback)
- fs.mkdtempSync(prefix[, options])
- fs.open(path, flags[, mode], callback)
- fs.openSync(path, flags[, mode])
- fs.read(fd, buffer, offset, length, position, callback)
- fs.readdir(path[, options], callback)
- fs.readdirSync(path[, options])
- fs.readFile(path[, options], callback)
- fs.readFileSync(path[, options])
- fs.readlink(path[, options], callback)
- fs.readlinkSync(path[, options])
- fs.readSync(fd, buffer, offset, length, position)
- fs.realpath(path[, options], callback)
- fs.realpathSync(path[, options])
- fs.rename(oldPath, newPath, callback)
- fs.renameSync(oldPath, newPath)
- fs.rmdir(path, callback)
- fs.rmdirSync(path)
- fs.stat(path, callback)
- fs.statSync(path)
- fs.symlink(target, path[, type], callback)
- fs.symlinkSync(target, path[, type])
- fs.truncate(path[, len], callback)
- fs.truncateSync(path[, len])
- fs.unlink(path, callback)
- fs.unlinkSync(path)
- fs.unwatchFile(filename[, listener])
- fs.utimes(path, atime, mtime, callback)
- fs.utimesSync(path, atime, mtime)
- fs.watch(filename[, options][, listener])
- fs.watchFile(filename[, options], listener)
- fs.write(fd, buffer[, offset[, length[, position]]], callback)
- fs.write(fd, string[, position[, encoding]], callback)
- fs.writeFile(file, data[, options], callback)
- fs.writeFileSync(file, data[, options])
- fs.writeSync(fd, buffer[, offset[, length[, position]]])
- fs.writeSync(fd, string[, position[, encoding]])
- FS Constants
- Global Objects
- HTTP
- Class: http.Agent
- Class: http.ClientRequest
- Event: 'abort'
- Event: 'connect'
- Event: 'continue'
- Event: 'response'
- Event: 'socket'
- Event: 'timeout'
- Event: 'upgrade'
- request.abort()
- request.aborted
- request.connection
- request.end([data[, encoding]][, callback])
- request.flushHeaders()
- request.getHeader(name)
- request.removeHeader(name)
- request.setHeader(name, value)
- request.setNoDelay([noDelay])
- request.setSocketKeepAlive([enable][, initialDelay])
- request.setTimeout(timeout[, callback])
- request.socket
- request.write(chunk[, encoding][, callback])
- Class: http.Server
- Event: 'checkContinue'
- Event: 'checkExpectation'
- Event: 'clientError'
- Event: 'close'
- Event: 'connect'
- Event: 'connection'
- Event: 'request'
- Event: 'upgrade'
- server.close([callback])
- server.listen()
- server.listening
- server.maxHeadersCount
- server.headersTimeout
- server.setTimeout([msecs][, callback])
- server.timeout
- server.keepAliveTimeout
- Class: http.ServerResponse
- Event: 'close'
- Event: 'finish'
- response.addTrailers(headers)
- response.connection
- response.end([data][, encoding][, callback])
- response.finished
- response.getHeader(name)
- response.getHeaderNames()
- response.getHeaders()
- response.hasHeader(name)
- response.headersSent
- response.removeHeader(name)
- response.sendDate
- response.setHeader(name, value)
- response.setTimeout(msecs[, callback])
- response.socket
- response.statusCode
- response.statusMessage
- response.write(chunk[, encoding][, callback])
- response.writeContinue()
- response.writeHead(statusCode[, statusMessage][, headers])
- Class: http.IncomingMessage
- Event: 'aborted'
- Event: 'close'
- message.aborted
- message.complete
- message.destroy([error])
- message.headers
- message.httpVersion
- message.method
- message.rawHeaders
- message.rawTrailers
- message.setTimeout(msecs, callback)
- message.socket
- message.statusCode
- message.statusMessage
- message.trailers
- message.url
- http.METHODS
- http.STATUS_CODES
- http.createServer([requestListener])
- http.get(options[, callback])
- http.globalAgent
- http.maxHeaderSize
- http.request(options[, callback])
- HTTP/2
- Core API
- Server-side example
- Client-side example
- Class: Http2Session
- Http2Session and Sockets
- Event: 'close'
- Event: 'connect'
- Event: 'error'
- Event: 'frameError'
- Event: 'goaway'
- Event: 'localSettings'
- Event: 'ping'
- Event: 'remoteSettings'
- Event: 'stream'
- Event: 'timeout'
- http2session.alpnProtocol
- http2session.close([callback])
- http2session.closed
- http2session.connecting
- http2session.destroy([error,][code])
- http2session.destroyed
- http2session.encrypted
- http2session.goaway([code, [lastStreamID, [opaqueData]]])
- http2session.localSettings
- http2session.originSet
- http2session.pendingSettingsAck
- http2session.ping([payload, ]callback)
- http2session.ref()
- http2session.remoteSettings
- http2session.setTimeout(msecs, callback)
- http2session.socket
- http2session.state
- http2session.settings(settings)
- http2session.type
- http2session.unref()
- Class: ServerHttp2Session
- Class: ClientHttp2Session
- Class: Http2Stream
- Http2Stream Lifecycle
- Event: 'aborted'
- Event: 'close'
- Event: 'error'
- Event: 'frameError'
- Event: 'timeout'
- Event: 'trailers'
- Event: 'wantTrailers'
- http2stream.aborted
- http2stream.close(code[, callback])
- http2stream.closed
- http2stream.destroyed
- http2stream.endAfterHeaders
- http2stream.pending
- http2stream.priority(options)
- http2stream.rstCode
- http2stream.sentHeaders
- http2stream.sentInfoHeaders
- http2stream.sentTrailers
- http2stream.session
- http2stream.setTimeout(msecs, callback)
- http2stream.state
- http2stream.sendTrailers(headers)
- Class: ClientHttp2Stream
- Class: ServerHttp2Stream
- Class: Http2Server
- Class: Http2SecureServer
- http2.createServer(options[, onRequestHandler])
- http2.createSecureServer(options[, onRequestHandler])
- http2.connect(authority[, options][, listener])
- http2.constants
- http2.getDefaultSettings()
- http2.getPackedSettings(settings)
- http2.getUnpackedSettings(buf)
- Headers Object
- Settings Object
- Using
options.selectPadding - Error Handling
- Invalid character handling in header names and values
- Push streams on the client
- Supporting the CONNECT method
- Compatibility API
- ALPN negotiation
- Class: http2.Http2ServerRequest
- Class: http2.Http2ServerResponse
- Event: 'close'
- Event: 'finish'
- response.addTrailers(headers)
- response.connection
- response.end([data][, encoding][, callback])
- response.finished
- response.getHeader(name)
- response.getHeaderNames()
- response.getHeaders()
- response.hasHeader(name)
- response.headersSent
- response.removeHeader(name)
- response.sendDate
- response.setHeader(name, value)
- response.setTimeout(msecs[, callback])
- response.socket
- response.statusCode
- response.statusMessage
- response.stream
- response.write(chunk[, encoding][, callback])
- response.writeContinue()
- response.writeHead(statusCode[, statusMessage][, headers])
- response.createPushResponse(headers, callback)
- Collecting HTTP/2 Performance Metrics
- Core API
- HTTPS
- Inspector
- Internationalization Support
- Modules
- Net
- IPC Support
- Class: net.Server
- Class: net.Socket
- new net.Socket([options])
- Event: 'close'
- Event: 'connect'
- Event: 'data'
- Event: 'drain'
- Event: 'end'
- Event: 'error'
- Event: 'lookup'
- Event: 'timeout'
- socket.address()
- socket.bufferSize
- socket.bytesRead
- socket.bytesWritten
- socket.connect()
- socket.connecting
- socket.destroy([exception])
- socket.destroyed
- socket.end([data][, encoding])
- socket.localAddress
- socket.localPort
- socket.pause()
- socket.ref()
- socket.remoteAddress
- socket.remoteFamily
- socket.remotePort
- socket.resume()
- socket.setEncoding([encoding])
- socket.setKeepAlive([enable][, initialDelay])
- socket.setNoDelay([noDelay])
- socket.setTimeout(timeout[, callback])
- socket.unref()
- socket.write(data[, encoding][, callback])
- net.connect()
- net.createConnection()
- net.createServer([options][, connectionListener])
- net.isIP(input)
- net.isIPv4(input)
- net.isIPv6(input)
- OS
- Path
- Performance Timing API
- Class: Performance
- performance.clearEntries(name)
- performance.clearFunctions([name])
- performance.clearGC()
- performance.clearMarks([name])
- performance.clearMeasures([name])
- performance.getEntries()
- performance.getEntriesByName(name[, type])
- performance.getEntriesByType(type)
- performance.mark([name])
- performance.maxEntries
- performance.measure(name, startMark, endMark)
- performance.nodeTiming
- performance.now()
- performance.timeOrigin
- performance.timerify(fn)
- Class: PerformanceEntry
- Class: PerformanceNodeTiming extends PerformanceEntry
- performanceNodeTiming.bootstrapComplete
- performanceNodeTiming.clusterSetupEnd
- performanceNodeTiming.clusterSetupStart
- performanceNodeTiming.loopExit
- performanceNodeTiming.loopStart
- performanceNodeTiming.moduleLoadEnd
- performanceNodeTiming.moduleLoadStart
- performanceNodeTiming.nodeStart
- performanceNodeTiming.preloadModuleLoadEnd
- performanceNodeTiming.preloadModuleLoadStart
- performanceNodeTiming.thirdPartyMainEnd
- performanceNodeTiming.thirdPartyMainStart
- performanceNodeTiming.v8Start
- Class: PerformanceObserver(callback)
- Examples
- Class: Performance
- Process
- Process Events
- process.abort()
- process.arch
- process.argv
- process.argv0
- process.channel
- process.chdir(directory)
- process.config
- process.connected
- process.cpuUsage([previousValue])
- process.cwd()
- process.debugPort
- process.disconnect()
- process.emitWarning(warning[, options])
- process.emitWarning(warning[, type[, code]][, ctor])
- process.env
- process.execArgv
- process.execPath
- process.exit([code])
- process.exitCode
- process.getegid()
- process.geteuid()
- process.getgid()
- process.getgroups()
- process.getuid()
- process.hrtime([time])
- process.initgroups(user, extra_group)
- process.kill(pid[, signal])
- process.mainModule
- process.memoryUsage()
- process.nextTick(callback[, ...args])
- process.noDeprecation
- process.pid
- process.platform
- process.ppid
- process.release
- process.send(message[, sendHandle[, options]][, callback])
- process.setegid(id)
- process.seteuid(id)
- process.setgid(id)
- process.setgroups(groups)
- process.setuid(id)
- process.stderr
- process.stdin
- process.stdout
- process.throwDeprecation
- process.title
- process.traceDeprecation
- process.umask([mask])
- process.uptime()
- process.version
- process.versions
- Exit Codes
- Punycode
- Query String
- Readline
- REPL
- 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.end([chunk][, encoding][, callback])
- writable.setDefaultEncoding(encoding)
- writable.uncork()
- writable.writableHighWaterMark
- writable.write(chunk[, encoding][, callback])
- writable.destroy([error])
- Class: stream.Writable
- Readable Streams
- Two Modes
- Three States
- Choose One
- Class: stream.Readable
- Event: 'close'
- Event: 'data'
- Event: 'end'
- Event: 'error'
- Event: 'readable'
- readable.isPaused()
- readable.pause()
- readable.pipe(destination[, options])
- readable.readableHighWaterMark
- readable.read([size])
- readable.resume()
- readable.setEncoding(encoding)
- readable.unpipe([destination])
- readable.unshift(chunk)
- readable.wrap(stream)
- readable.destroy([error])
- Duplex and Transform Streams
- Writable Streams
- API for Stream Implementers
- Additional Notes
- String Decoder
- Timers
- TLS (SSL)
- TLS/SSL Concepts
- Modifying the Default TLS Cipher suite
- Class: tls.Server
- Class: tls.TLSSocket
- new tls.TLSSocket(socket[, options])
- Event: 'OCSPResponse'
- Event: 'secureConnect'
- tlsSocket.address()
- tlsSocket.authorizationError
- tlsSocket.authorized
- tlsSocket.disableRenegotiation()
- tlsSocket.encrypted
- tlsSocket.getCipher()
- tlsSocket.getEphemeralKeyInfo()
- tlsSocket.getFinished()
- tlsSocket.getPeerCertificate([detailed])
- tlsSocket.getPeerFinished()
- tlsSocket.getProtocol()
- tlsSocket.getSession()
- tlsSocket.getTLSTicket()
- tlsSocket.localAddress
- tlsSocket.localPort
- tlsSocket.remoteAddress
- tlsSocket.remoteFamily
- tlsSocket.remotePort
- tlsSocket.renegotiate(options, callback)
- tlsSocket.setMaxSendFragment(size)
- tls.checkServerIdentity(host, cert)
- tls.connect(options[, callback])
- tls.connect(path[, options][, callback])
- tls.connect(port[, host][, options][, callback])
- tls.createSecureContext(options)
- tls.createServer([options][, secureConnectionListener])
- tls.getCiphers()
- tls.DEFAULT_ECDH_CURVE
- Deprecated APIs
- Tracing
- TTY
- UDP / Datagram Sockets
- Class: dgram.Socket
- Event: 'close'
- Event: 'error'
- Event: 'listening'
- Event: 'message'
- socket.addMembership(multicastAddress[, multicastInterface])
- socket.address()
- socket.bind([port][, address][, callback])
- socket.bind(options[, callback])
- socket.close([callback])
- socket.dropMembership(multicastAddress[, multicastInterface])
- socket.getRecvBufferSize()
- socket.getSendBufferSize()
- socket.ref()
- 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()
- Change to asynchronous
socket.bind()behavior
dgrammodule functions
- Class: dgram.Socket
- URL
- URL Strings and URL Objects
- The WHATWG URL API
- Class: URL
- Class: URLSearchParams
- Constructor: new URLSearchParams()
- Constructor: new URLSearchParams(string)
- Constructor: new URLSearchParams(obj)
- Constructor: 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[@@iterator]()
- url.domainToASCII(domain)
- url.domainToUnicode(domain)
- url.format(URL[, options])
- Legacy URL API
- Percent-Encoding in URLs
- Util
- util.callbackify(original)
- util.debuglog(section)
- util.deprecate(function, string)
- util.format(format[, ...args])
- util.getSystemErrorName(err)
- util.inherits(constructor, superConstructor)
- util.inspect(object[, options])
- util.promisify(original)
- Class: util.TextDecoder
- Class: util.TextEncoder
- Deprecated APIs
- util._extend(target, source)
- util.debug(string)
- util.error([...strings])
- 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)
- util.print([...strings])
- util.puts([...strings])
- V8
- v8.cachedDataVersionTag()
- v8.getHeapSpaceStatistics()
- v8.getHeapStatistics()
- v8.setFlagsFromString(string)
- Serialization API
- v8.serialize(value)
- v8.deserialize(buffer)
- class: v8.Serializer
- new 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.Deserializer
- new 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
- VM (Executing JavaScript)
- Class: vm.Script
- vm.createContext([sandbox])
- vm.isContext(sandbox)
- vm.runInContext(code, contextifiedSandbox[, options])
- vm.runInDebugContext(code)
- vm.runInNewContext(code[, sandbox][, options])
- vm.runInThisContext(code[, options])
- Example: Running an HTTP Server within a VM
- What does it mean to "contextify" an object?
- Zlib
- Threadpool Usage
- Compressing HTTP requests and responses
- Memory Usage Tuning
- Flushing
- Constants
- Class Options
- Class: zlib.Deflate
- Class: zlib.DeflateRaw
- Class: zlib.Gunzip
- Class: zlib.Gzip
- Class: zlib.Inflate
- Class: zlib.InflateRaw
- Class: zlib.Unzip
- Class: zlib.Zlib
- zlib.constants
- zlib.createDeflate([options])
- zlib.createDeflateRaw([options])
- zlib.createGunzip([options])
- zlib.createGzip([options])
- zlib.createInflate([options])
- zlib.createInflateRaw([options])
- zlib.createUnzip([options])
- Convenience Methods
- 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#
The goal of this documentation is to comprehensively explain the Node.js API, both from a reference as well as a conceptual point of view. Each section describes a built-in module or high-level concept.
Where appropriate, property types, method arguments, and the arguments provided to event handlers are detailed in a list underneath the topic heading.
Contributing#
If errors are found in this documentation, please submit an issue or see the contributing guide for directions on how to submit a patch.
Every file is generated based on the corresponding .md file in the
doc/api/ folder in Node.js's source tree. The documentation is generated
using the tools/doc/generate.js program. An HTML template is located at
doc/template.html.
Stability Index#
Throughout the documentation are indications of a section's stability. The Node.js API is still somewhat changing, and as it matures, certain parts are more reliable than others. Some 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 and in the process of being redesigned.
The stability indices are as follows:
Note: Caution must be used when making use of Experimental features,
particularly within modules that may be used as dependencies (or dependencies
of dependencies) within a Node.js application. End users may not be aware that
experimental features are being used, and therefore may experience unexpected
failures or behavior changes when API modifications occur. To help avoid such
surprises, Experimental features may require a command-line flag to
explicitly enable them, or may cause a process warning to be emitted.
By default, such warnings are printed to stderr and may be handled by
attaching a listener to the process.on('warning') event.
JSON Output#
Every .html document has a corresponding .json document presenting
the same information in a structured manner. This feature is
experimental, and added for the benefit of IDEs and other utilities that
wish to do programmatic things with the documentation.
Syscalls and man pages#
System calls like open(2) and read(2) define the interface between user programs
and the underlying operating system. Node functions which simply wrap a syscall,
like fs.open(), will document that. The docs link to the corresponding man
pages (short for manual pages) which describe how the syscalls work.
Some syscalls, like lchown(2), are BSD-specific. That means, for
example, that fs.lchown() only works on macOS and other BSD-derived systems,
and is not available on Linux.
Most Unix syscalls have Windows equivalents, but behavior may differ on Windows relative to Linux and macOS. For an example of the subtle ways in which it's sometimes impossible to replace Unix syscall semantics on Windows, see Node.js issue 4760.
Usage#
node [options] [V8 options] [script.js | -e "script" | - ] [arguments]
Please see the Command Line Options document for information about different options and ways to run scripts with Node.js.
Example#
An example of a web server written with Node.js which responds with
'Hello World!':
Commands displayed in this document are shown starting with $ or >
to replicate how they would appear in a user's terminal.
Do not include the $ and > characters. They are there to
indicate the start of each command.
There are many tutorials and examples that follow this
convention: $ or > for commands run as a regular user, and #
for commands that should be executed as an administrator.
Lines that don’t start with $ or > character are typically showing
the output of the previous command.
Firstly, make sure to have downloaded and installed Node.js. See this guide for further install information.
Now, create an empty project folder called projects, then navigate into it.
The project folder can be named based on the user's current project title, but
this example will use projects as the project folder.
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.
In Node.js it is considered good style to use
hyphens (-) or underscores (_) to separate
multiple words in filenames.
Open hello-world.js in any preferred text editor and
paste in the following content:
const http = require('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 enter the following command:
$ node hello-world.js
An output like this should appear in the terminal to indicate Node.js server is running:
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.
Many of the examples in the documentation can be run similarly.
Assert#
The assert module provides a simple set of assertion tests that can be used to
test invariants.
A strict and a legacy mode exist, while it is recommended to only use
strict mode.
For more information about the used equality comparisons see MDN's guide on equality comparisons and sameness.
Strict mode#
When using the strict mode, any assert function will use the equality used in
the strict function mode. So assert.deepEqual() will, for example, work the
same as assert.deepStrictEqual().
It can be accessed using:
const assert = require('assert').strict;
Legacy mode#
When accessing assert directly instead of using the strict property, the
Abstract Equality Comparison will be used for any function without "strict"
in its name, such as assert.deepEqual().
It can be accessed using:
const assert = require('assert');
It is recommended to use the strict mode instead as the
Abstract Equality Comparison can often have surprising results. This is
especially true for assert.deepEqual(), where the comparison rules are
lax:
// WARNING: This does not throw an AssertionError!
assert.deepEqual(/a/gi, new Date());
assert(value[, message])#
value<any>message<any>
An alias of assert.ok().
assert.deepEqual(actual, expected[, message])#
actual<any>expected<any>message<any>
Strict mode
An alias of assert.deepStrictEqual().
Legacy mode
assert.deepStrictEqual() instead.Tests for deep equality between the actual and expected parameters.
Primitive values are compared with the Abstract Equality Comparison
( == ).
Only enumerable "own" properties are considered. The
assert.deepEqual() implementation does not test the
[[Prototype]] of objects, attached symbols, or
non-enumerable properties — for such checks, consider using
assert.deepStrictEqual() instead. This can lead to some
potentially surprising results. For example, the following example does not
throw an AssertionError because the properties on the RegExp object are
not enumerable:
// WARNING: This does not throw an AssertionError!
assert.deepEqual(/a/gi, new Date());
An exception is made for Map and Set. Maps and Sets have their
contained items compared too, as expected.
"Deep" equality means that the enumerable "own" properties of child objects are evaluated also:
const assert = require('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, object is equal to itself
assert.deepEqual(obj1, obj2);
// AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } }
// values of b are different
assert.deepEqual(obj1, obj3);
// OK, objects are equal
assert.deepEqual(obj1, obj4);
// AssertionError: { a: { b: 1 } } deepEqual {}
// Prototypes are ignored
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.
assert.deepStrictEqual(actual, expected[, message])#
actual<any>expected<any>message<any>
Generally identical to assert.deepEqual() with a few exceptions:
Comparison details#
- Primitive values are compared using the Strict Equality Comparison
(
===). - Set values and Map keys are compared using the SameValueZero comparison. (Which means they are free of the caveats).
- Type tags of objects should be the same.
[[Prototype]]of objects are compared using the Strict Equality Comparison.- Only enumerable "own" properties are considered.
Errormessages are always compared, even though this property is non-enumerable.- Object wrappers are compared both as objects and unwrapped values.
- Object properties are compared unordered.
- Map keys and Set items are compared unordered.
- Recursion stops when both sides differ or both sides encounter a circular reference.
const assert = require('assert').strict;
assert.deepEqual({ a: 1 }, { a: '1' });
// OK, because 1 == '1'
assert.deepStrictEqual({ a: 1 }, { a: '1' });
// AssertionError: { a: 1 } deepStrictEqual { a: '1' }
// because 1 !== '1' using strict equality
// The following objects don't have own properties
const date = new Date();
const object = {};
const fakeDate = {};
Object.setPrototypeOf(fakeDate, Date.prototype);
assert.deepEqual(object, fakeDate);
// OK, doesn't check [[Prototype]]
assert.deepStrictEqual(object, fakeDate);
// AssertionError: {} deepStrictEqual Date {}
// Different [[Prototype]]
assert.deepEqual(date, fakeDate);
// OK, doesn't check type tags
assert.deepStrictEqual(date, fakeDate);
// AssertionError: 2017-03-11T14:25:31.849Z deepStrictEqual Date {}
// Different type tags
assert.deepStrictEqual(new Number(1), new Number(2));
// Fails because the wrapped number is unwrapped and compared as well.
assert.deepStrictEqual(new String('foo'), Object('foo'));
// OK because the object and the string are identical when unwrapped.
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.
assert.doesNotReject(block[, error][, message])#
block<Function>error<RegExp> | <Function>message<any>
Awaits for the promise returned by function block to complete and not be
rejected. See assert.rejects() for more details.
When assert.doesNotReject() is called, it will immediately call the block
function, and awaits for completion.
Besides the async nature to await the completion behaves identical to
[assert.doesNotThrow()][].
(async () => {
await assert.doesNotReject(
async () => {
throw new TypeError('Wrong value');
},
SyntaxError
);
})();
assert.doesNotReject(
() => Promise.reject(new TypeError('Wrong value')),
SyntaxError
).then(() => {
// ...
});
assert.doesNotThrow(block[, error][, message])#
block<Function>error<RegExp> | <Function>message<any>
Asserts that the function block does not throw an error. See
assert.throws() for more details.
Please note: Using assert.doesNotThrow() is actually not useful because there
is no benefit by 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 block
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.
The following, for instance, will throw the TypeError because there is no
matching error type in the assertion:
assert.doesNotThrow(
() => {
throw new TypeError('Wrong value');
},
SyntaxError
);
However, the following will result in an AssertionError with the message
'Got unwanted exception (TypeError)..':
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:
assert.doesNotThrow(
() => {
throw new TypeError('Wrong value');
},
TypeError,
'Whoops'
);
// Throws: AssertionError: Got unwanted exception (TypeError). Whoops
assert.equal(actual, expected[, message])#
actual<any>expected<any>message<any>
Strict mode
An alias of assert.strictEqual().
Legacy mode
assert.strictEqual() instead.Tests shallow, coercive equality between the actual and expected parameters
using the Abstract Equality Comparison ( == ).
const assert = require('assert');
assert.equal(1, 1);
// OK, 1 == 1
assert.equal(1, '1');
// OK, 1 == '1'
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.
assert.fail(message)#
assert.fail(actual, expected[, message[, operator[, stackStartFunction]]])#
actual<any>expected<any>message<any>operator<string> Default:'!='stackStartFunction<Function> Default:assert.fail
Throws an AssertionError. 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 only it will be used as the error
message, the other arguments will be stored as properties on the thrown object.
If stackStartFunction is provided, all stack frames above that function will
be removed from stacktrace (see Error.captureStackTrace).
const assert = require('assert').strict;
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
Note: In the last two cases actual, expected, and operator have no
influence on the error message.
assert.fail();
// AssertionError [ERR_ASSERTION]: Failed
assert.fail('boom');
// AssertionError [ERR_ASSERTION]: boom
assert.fail('a', 'b');
// AssertionError [ERR_ASSERTION]: 'a' != 'b'
Example use of stackStartFunction for truncating the exception's stacktrace:
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 truthy. This is useful when testing the error
argument in callbacks.
const assert = require('assert').strict;
assert.ifError(null);
// OK
assert.ifError(0);
// OK
assert.ifError(1);
// Throws 1
assert.ifError('error');
// Throws 'error'
assert.ifError(new Error());
// Throws Error
assert.notDeepEqual(actual, expected[, message])#
actual<any>expected<any>message<any>
Strict mode
An alias of assert.notDeepStrictEqual().
Legacy mode
assert.notDeepStrictEqual() instead.Tests for any deep inequality. Opposite of assert.deepEqual().
const assert = require('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: obj1 and obj2 are not deeply equal
assert.notDeepEqual(obj1, obj3);
// AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } }
assert.notDeepEqual(obj1, obj4);
// OK: obj1 and obj4 are not deeply equal
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.
assert.notDeepStrictEqual(actual, expected[, message])#
actual<any>expected<any>message<any>
Tests for deep strict inequality. Opposite of assert.deepStrictEqual().
const assert = require('assert').strict;
assert.notDeepEqual({ a: 1 }, { a: '1' });
// AssertionError: { a: 1 } notDeepEqual { a: '1' }
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.
assert.notEqual(actual, expected[, message])#
actual<any>expected<any>message<any>
Strict mode
An alias of assert.notStrictEqual().
Legacy mode
assert.notStrictEqual() instead.Tests shallow, coercive inequality with the Abstract Equality Comparison
( != ).
const assert = require('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.
assert.notStrictEqual(actual, expected[, message])#
actual<any>expected<any>message<any>
Tests strict inequality as determined by the Strict Equality Comparison
( !== ).
const assert = require('assert').strict;
assert.notStrictEqual(1, 2);
// OK
assert.notStrictEqual(1, 1);
// AssertionError: 1 !== 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.
assert.ok(value[, message])#
value<any>message<any>
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.
const assert = require('assert').strict;
assert.ok(true);
// OK
assert.ok(1);
// OK
assert.ok(false);
// throws "AssertionError: false == true"
assert.ok(0);
// throws "AssertionError: 0 == true"
assert.ok(false, 'it\'s false');
// throws "AssertionError: it's false"
assert.strictEqual(actual, expected[, message])#
actual<any>expected<any>message<any>
Tests strict equality as determined by the Strict Equality Comparison
( === ).
const assert = require('assert').strict;
assert.strictEqual(1, 2);
// AssertionError: 1 === 2
assert.strictEqual(1, 1);
// OK
assert.strictEqual(1, '1');
// AssertionError: 1 === '1'
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.
assert.rejects(block[, error][, message])#
block<Function>error<RegExp> | <Function> | <Object>message<any>
Awaits for promise returned by function block to be rejected.
When assert.rejects() is called, it will immediately call the block
function, and awaits for completion.
Besides the async nature to await the completion behaves identical to
assert.throws().
If specified, error can be a constructor, RegExp, a validation
function, or an object where each property will be tested for.
If specified, message will be the message provided by the AssertionError if
the block fails to reject.
(async () => {
await assert.rejects(
async () => {
throw new Error('Wrong value');
},
Error
);
})();
assert.rejects(
() => Promise.reject(new Error('Wrong value')),
Error
).then(() => {
// ...
});
assert.throws(block[, error][, message])#
block<Function>error<RegExp> | <Function> | <object>message<any>
Expects the function block to throw an error.
If specified, error can be a constructor, RegExp, a validation
function, or an object where each property will be tested for.
If specified, message will be the message provided by the AssertionError if
the block fails to throw.
Validate instanceof using constructor:
assert.throws(
() => {
throw new Error('Wrong value');
},
Error
);
Validate error message using RegExp:
assert.throws(
() => {
throw new Error('Wrong value');
},
/value/
);
Custom error validation:
assert.throws(
() => {
throw new Error('Wrong value');
},
function(err) {
if ((err instanceof Error) && /value/.test(err)) {
return true;
}
},
'unexpected error'
);
Custom error object / error instance:
assert.throws(
() => {
const err = new TypeError('Wrong value');
err.code = 404;
throw err;
},
{
name: 'TypeError',
message: 'Wrong value'
// Note that only properties on the error object will be tested!
}
);
Note that error can not 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 below carefully if using a string as the second argument gets
considered:
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.
// In that case both cases do not throw as neither is going to try to
// match for the error message thrown by the input function!
assert.throws(throwingFirst, 'Second');
assert.throws(throwingSecond, 'Second');
// 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:
assert.throws(throwingSecond, /Second$/);
// Does not throw because the error messages match.
assert.throws(throwingFirst, /Second$/);
// Throws a error:
// Error: First
// at throwingFirst (repl:2:9)
Due to the confusing notation, it is recommended not to use a string as the second argument. This might lead to difficult-to-spot errors.
Caveats#
For the following cases, consider using ES2015 Object.is(),
which uses the SameValueZero comparison.
const a = 0;
const b = -a;
assert.notStrictEqual(a, b);
// AssertionError: 0 !== -0
// Strict Equality Comparison doesn't distinguish between -0 and +0...
assert(!Object.is(a, b));
// but Object.is() does!
const str1 = 'foo';
const str2 = 'foo';
assert.strictEqual(str1 / 1, str2 / 1);
// AssertionError: NaN === NaN
// Strict Equality Comparison can't be used to check NaN...
assert(Object.is(str1 / 1, str2 / 1));
// but Object.is() can!
For more information, see MDN's guide on equality comparisons and sameness.
Async Hooks#
The async_hooks module provides an API to register callbacks tracking the
lifetime of asynchronous resources created inside a Node.js application.
It can be accessed using:
const async_hooks = require('async_hooks');
Terminology#
An asynchronous resource represents an object with an associated callback.
This callback may be called multiple times, for example, 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.
Public API#
Overview#
Following is a simple overview of the public API.
const async_hooks = require('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 (e.g. TCPWrap), and will be called exactly 1
// time for requests (e.g. FSReqWrap).
function before(asyncId) { }
// after is called just after the resource's callback has finished.
function after(asyncId) { }
// destroy is called when an AsyncWrap instance 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.
- 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.
const async_hooks = require('async_hooks');
const asyncHook = async_hooks.createHook({
init(asyncId, type, triggerAsyncId, resource) { },
destroy(asyncId) { }
});
Note that 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());
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 AsyncHooks callbacks#
Because printing to the console is an asynchronous operation, console.log()
will cause the AsyncHooks callbacks to be called. Using console.log() or
similar asynchronous operations inside an AsyncHooks callback function will thus
cause an infinite recursion. An easy solution to this when debugging is to use a
synchronous logging operation such as fs.writeSync(1, msg). This will print to
stdout because 1 is the file descriptor for stdout and will not invoke
AsyncHooks recursively because it is synchronous.
const fs = require('fs');
const util = require('util');
function debug(...args) {
// use a function like this one when debugging inside an AsyncHooks callback
fs.writeSync(1, `${util.format(...args)}\n`);
}
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 AsyncHooks itself. The logging should then be skipped when it was the logging itself that caused AsyncHooks callback to call. By doing this the otherwise infinite recursion is broken.
asyncHook.enable()#
- Returns: <AsyncHook> A reference to
asyncHook.
Enable the callbacks for a given AsyncHook instance. If no callbacks are
provided enabling is a noop.
The AsyncHook instance is disabled by default. If the AsyncHook instance
should be enabled immediately after creation, the following pattern can be used.
const async_hooks = require('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.
require('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 process.
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.
FSEVENTWRAP, FSREQWRAP, GETADDRINFOREQWRAP, GETNAMEINFOREQWRAP, HTTPPARSER,
JSSTREAM, PIPECONNECTWRAP, PIPEWRAP, PROCESSWRAP, QUERYWRAP, SHUTDOWNWRAP,
SIGNALWRAP, STATWATCHER, TCPCONNECTWRAP, TCPSERVERWRAP, TCPWRAP, TIMERWRAP,
TTYWRAP, UDPSENDWRAP, UDPWRAP, WRITEWRAP, ZLIB, SSLCONNECTION, PBKDF2REQUEST,
RANDOMBYTESREQUEST, TLSWRAP, Timeout, Immediate, TickObject
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.
Note: 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.
triggerId#
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:
async_hooks.createHook({
init(asyncId, type, triggerAsyncId) {
const eid = async_hooks.executionAsyncId();
fs.writeSync(
1, `${type}(${asyncId}): trigger: ${triggerAsyncId} execution: ${eid}\n`);
}
}).enable();
require('net').createServer((conn) => {}).listen(8080);
Output when hitting the server with nc localhost 8080:
TCPSERVERWRAP(2): trigger: 1 execution: 1
TCPWRAP(4): trigger: 2 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 (side note: a executionAsyncId() of 0
means it's 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 hostname used when looking up the IP address for the
hostname in net.Server.listen(). The API for accessing this information is
currently not considered public, 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 the case of Promises, the resource object will have promise property
that refers to the Promise that is being initialized, and a isChainedPromise
property, set to true if the promise has a parent promise, and false
otherwise. For example, in the case of b = a.then(handler), a is considered
a parent Promise of b. Here, b is considered a chained promise.
Note: 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.
let indent = 0;
async_hooks.createHook({
init(asyncId, type, triggerAsyncId) {
const eid = async_hooks.executionAsyncId();
const indentStr = ' '.repeat(indent);
fs.writeSync(
1,
`${indentStr}${type}(${asyncId}):` +
` trigger: ${triggerAsyncId} execution: ${eid}\n`);
},
before(asyncId) {
const indentStr = ' '.repeat(indent);
fs.writeSync(1, `${indentStr}before: ${asyncId}\n`);
indent += 2;
},
after(asyncId) {
indent -= 2;
const indentStr = ' '.repeat(indent);
fs.writeSync(1, `${indentStr}after: ${asyncId}\n`);
},
destroy(asyncId) {
const indentStr = ' '.repeat(indent);
fs.writeSync(1, `${indentStr}destroy: ${asyncId}\n`);
},
}).enable();
require('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(2): trigger: 1 execution: 1
TickObject(3): trigger: 2 execution: 1
before: 3
Timeout(4): trigger: 3 execution: 3
TIMERWRAP(5): trigger: 3 execution: 3
after: 3
destroy: 3
before: 5
before: 4
TTYWRAP(6): trigger: 4 execution: 4
SIGNALWRAP(7): trigger: 4 execution: 4
TTYWRAP(8): trigger: 4 execution: 4
>>> 4
TickObject(9): trigger: 4 execution: 4
after: 4
after: 5
before: 9
after: 9
destroy: 4
destroy: 9
destroy: 5
Note: 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:
TTYWRAP(6) -> Timeout(4) -> TIMERWRAP(5) -> TickObject(3) -> root(1)
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
hostname is a synchronous operation, but to maintain a completely asynchronous
API the user's callback is placed in a process.nextTick().
The graph only shows when a resource was created, not why, so to track
the why use triggerAsyncId.
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.
Note: 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().
Note: 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).
Note that resolve() does not do any observable synchronous work.
Note: This does not necessarily mean that the Promise is fulfilled or
rejected at this point, if the Promise was resolved by assuming the state
of another Promise.
For example:
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.executionAsyncId()#
- Returns: <number> The
asyncIdof the current execution context. Useful to track when something calls.
For example:
const async_hooks = require('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()). For example:
const server = net.createServer(function onConnection(conn) {
// Returns the ID of the server, not of the new connection, because the
// onConnection callback runs in the execution scope of the server's
// MakeCallback().
async_hooks.executionAsyncId();
}).listen(port, function onListening() {
// Returns the ID of a TickObject (i.e. process.nextTick()) because all
// callbacks passed to .listen() are wrapped in a nextTick().
async_hooks.executionAsyncId();
});
Note that 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.
For example:
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();
});
Note that promise contexts may not get valid triggerAsyncIds by default. See the section on promise execution tracking.
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.
Here's an example:
const ah = require('async_hooks');
Promise.resolve(1729).then(() => {
console.log(`eid ${ah.executionAsyncId()} tid ${ah.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 note that
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. Example:
const ah = require('async_hooks');
ah.createHook({ init() {} }).enable(); // forces PromiseHooks to be enabled.
Promise.resolve(1729).then(() => {
console.log(`eid ${ah.executionAsyncId()} tid ${ah.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 AsyncWrap
JavaScript API so that all the appropriate callbacks are called.
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.
const { AsyncResource, executionAsyncId } = require('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();
// Call AsyncHooks before callbacks.
// Deprecated: Use asyncResource.runInAsyncScope instead.
asyncResource.emitBefore();
// Call AsyncHooks after callbacks.
// Deprecated: Use asyncResource.runInAsyncScope instead.
asyncResource.emitAfter();
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> Disables automaticemitDestroywhen the object is garbage collected. This usually does not need to be set (even ifemitDestroyis called manually), unless the resource's asyncId is retrieved and the sensitive API'semitDestroyis called with it. 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();
}
}
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.emitBefore()#
asyncResource.runInAsyncScope() instead.- Returns: <undefined>
Call all before callbacks to notify that a new asynchronous execution context
is being entered. If nested calls to emitBefore() are made, the stack of
asyncIds will be tracked and properly unwound.
before and after calls must be unwound in the same order that they
are called. Otherwise, an unrecoverable exception will occur and the process
will abort. For this reason, the emitBefore and emitAfter APIs are
considered deprecated. Please use runInAsyncScope, as it provides a much safer
alternative.
asyncResource.emitAfter()#
asyncResource.runInAsyncScope() instead.- Returns: <undefined>
Call all after callbacks. If nested calls to emitBefore() were made, then
make sure the stack is unwound properly. Otherwise an error will be thrown.
If the user's callback throws an exception, emitAfter() will automatically be
called for all asyncIds on the stack if the error is handled by a domain or
'uncaughtException' handler.
before and after calls must be unwound in the same order that they
are called. Otherwise, an unrecoverable exception will occur and the process
will abort. For this reason, the emitBefore and emitAfter APIs are
considered deprecated. Please use runInAsyncScope, as it provides a much safer
alternative.
asyncResource.emitDestroy()#
- Returns: <undefined>
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.
Buffer#
Prior to the introduction of TypedArray, the JavaScript language had no
mechanism for reading or manipulating streams of binary data. The Buffer class
was introduced as part of the Node.js API to enable interaction with octet
streams in TCP streams, file system operations, and other contexts.
With TypedArray now available, the Buffer class implements the
Uint8Array API in a manner that is more optimized and suitable for Node.js.
Instances of the Buffer class are similar to arrays of integers but
correspond to fixed-sized, raw memory allocations outside the V8 heap.
The size of the Buffer is established when it is created and cannot be
changed.
The Buffer class is within the global scope, making it unlikely that one
would need to ever use require('buffer').Buffer.
Examples:
// Creates a zero-filled Buffer of length 10.
const buf1 = Buffer.alloc(10);
// Creates a Buffer of length 10, filled with 0x1.
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 either fill() or write().
const buf3 = Buffer.allocUnsafe(10);
// Creates a Buffer containing [0x1, 0x2, 0x3].
const buf4 = Buffer.from([1, 2, 3]);
// Creates a Buffer containing UTF-8 bytes [0x74, 0xc3, 0xa9, 0x73, 0x74].
const buf5 = Buffer.from('tést');
// Creates a Buffer containing Latin-1 bytes [0x74, 0xe9, 0x73, 0x74].
const buf6 = Buffer.from('tést', 'latin1');
Buffer.from(), Buffer.alloc(), and Buffer.allocUnsafe()#
In versions of Node.js prior to v6, 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 theBuffercompletely. 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. Starting in Node.js 8.0.0,Buffer(num)andnew Buffer(num)will 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() changes significantly based on the type
of value passed as the first argument, applications that do not properly
validate the input arguments passed to new Buffer(), or that fail to
appropriately initialize newly allocated Buffer content, can inadvertently
introduce security and reliability issues into their code.
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 newBuffercontaining 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 newBuffercontaining a copy of the contents of the givenBuffer.Buffer.from(string[, encoding])returns a newBuffercontaining a copy of the provided string.Buffer.alloc(size[, fill[, encoding]])returns a "filled"Bufferinstance of the specified size. This method can be significantly slower thanBuffer.allocUnsafe(size)but ensures that newly createdBufferinstances never contain old and potentially sensitive data.Buffer.allocUnsafe(size)andBuffer.allocUnsafeSlow(size)each return a newBufferof the specifiedsizewhose content must be initialized using eitherbuf.fill(0)or written to completely.
Buffer instances returned by Buffer.allocUnsafe() 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
force all newly allocated Buffer instances created using either
new Buffer(size), Buffer.allocUnsafe(), Buffer.allocUnsafeSlow() or
new SlowBuffer(size) to be automatically zero-filled upon creation. Use of
this flag changes the default behavior of these methods and can have a significant
impact on performance. Use of the --zero-fill-buffers option is recommended
only when necessary to enforce that newly allocated Buffer instances cannot
contain potentially sensitive data.
Example:
$ 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.
Buffers and Character Encodings#
Buffer instances are commonly used to represent sequences of encoded characters
such as UTF-8, UCS2, Base64, or even Hex-encoded data. It is possible to
convert back and forth between Buffer instances and ordinary JavaScript strings
by using an explicit character encoding.
Example:
const buf = Buffer.from('hello world', 'ascii');
// Prints: 68656c6c6f20776f726c64
console.log(buf.toString('hex'));
// Prints: aGVsbG8gd29ybGQ=
console.log(buf.toString('base64'));
The character encodings currently supported by Node.js include:
'ascii'- For 7-bit ASCII data only. This encoding is fast and will strip the high bit if set.'utf8'- Multibyte encoded Unicode characters. Many web pages and other document formats use UTF-8.'utf16le'- 2 or 4 bytes, little-endian encoded Unicode characters. Surrogate pairs (U+10000 to U+10FFFF) are supported.'ucs2'- Alias of'utf16le'.'base64'- Base64 encoding. When creating aBufferfrom a string, this encoding will also correctly accept "URL and Filename Safe Alphabet" as specified in RFC4648, Section 5.'latin1'- A way of encoding theBufferinto a one-byte encoded string (as defined by the IANA in RFC1345, page 63, to be the Latin-1 supplement block and C0/C1 control codes).'binary'- Alias for'latin1'.'hex'- Encode each byte as two hexadecimal characters.
Note: Today's 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 TypedArray#
Buffer instances are also Uint8Array instances. However, there are subtle
incompatibilities with TypedArray. For example, while
ArrayBuffer#slice() creates a copy of the slice, the implementation of
Buffer#slice() creates a view over the existing Buffer
without copying, making Buffer#slice() far more efficient.
It is also possible to create new TypedArray instances from a Buffer with
the following caveats:
The
Bufferobject's memory is copied to theTypedArray, not shared.The
Bufferobject's memory is interpreted as an array of distinct elements, and not as a byte array of the target type. That is,new Uint32Array(Buffer.from([1, 2, 3, 4]))creates a 4-elementUint32Arraywith elements[1, 2, 3, 4], not aUint32Arraywith a single element[0x1020304]or[0x4030201].
It is possible to create a new Buffer that shares the same allocated memory as
a TypedArray instance by using the TypeArray object's .buffer property.
Example:
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);
// Prints: <Buffer 88 a0>
console.log(buf1);
// Prints: <Buffer 88 13 a0 0f>
console.log(buf2);
arr[1] = 6000;
// Prints: <Buffer 88 a0>
console.log(buf1);
// Prints: <Buffer 88 13 70 17>
console.log(buf2);
Note that 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.
Example:
const arr = new Uint16Array(20);
const buf = Buffer.from(arr.buffer, 0, 16);
// Prints: 16
console.log(buf.length);
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:
Buffer.from(array)Buffer.from(buffer)Buffer.from(arrayBuffer[, byteOffset [, length]])Buffer.from(string[, encoding])
Buffers and iteration#
Buffer instances can be iterated over using for..of syntax:
Example:
const buf = Buffer.from([1, 2, 3]);
// Prints:
// 1
// 2
// 3
for (const b of buf) {
console.log(b);
}
Additionally, the buf.values(), buf.keys(), and
buf.entries() methods can be used to create iterators.
Class: Buffer#
The Buffer class is a global type for dealing with binary data directly.
It can be constructed in a variety of ways.
new Buffer(array)#
Buffer.from(array) instead.array<integer[]> An array of bytes to copy from.
Allocates a new Buffer using an array of octets.
Example:
// Creates a new Buffer containing the UTF-8 bytes of the string 'buffer'
const buf = new Buffer([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]);
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.length - byteOffset.
This creates a view of the ArrayBuffer or SharedArrayBuffer 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.
The optional byteOffset and length arguments specify a memory range within
the arrayBuffer that will be shared by the Buffer.
Example:
const arr = new Uint16Array(2);
arr[0] = 5000;
arr[1] = 4000;
// Shares memory with `arr`
const buf = new Buffer(arr.buffer);
// Prints: <Buffer 88 13 a0 0f>
console.log(buf);
// Changing the original Uint16Array changes the Buffer also
arr[1] = 6000;
// Prints: <Buffer 88 13 70 17>
console.log(buf);
new Buffer(buffer)#
Buffer.from(buffer) instead.buffer<Buffer> | <Uint8Array> An existingBufferorUint8Arrayfrom which to copy data.
Copies the passed buffer data onto a new Buffer instance.
Example:
const buf1 = new Buffer('buffer');
const buf2 = new Buffer(buf1);
buf1[0] = 0x61;
// Prints: auffer
console.log(buf1.toString());
// Prints: buffer
console.log(buf2.toString());
new Buffer(size)#
size<integer> The desired length of the newBuffer.
Allocates a new Buffer of size bytes. If the size is larger than
buffer.constants.MAX_LENGTH or smaller than 0, a RangeError will be
thrown. A zero-length Buffer will be created if size is 0.
Prior to Node.js 8.0.0, the underlying memory for Buffer instances
created in this way is not initialized. The contents of a newly created
Buffer are unknown and may contain sensitive data. Use
Buffer.alloc(size) instead to initialize a Buffer
to zeroes.
Example:
const buf = new Buffer(10);
// Prints: <Buffer 00 00 00 00 00 00 00 00 00 00>
console.log(buf);
new Buffer(string[, encoding])#
Buffer.from(string[, encoding]) instead.Creates a new Buffer containing string. The encoding parameter identifies
the character encoding of string.
Examples:
const buf1 = new Buffer('this is a tést');
// Prints: this is a tést
console.log(buf1.toString());
// Prints: this is a tC)st
console.log(buf1.toString('ascii'));
const buf2 = new Buffer('7468697320697320612074c3a97374', 'hex');
// Prints: this is a tést
console.log(buf2.toString());
Class Method: Buffer.alloc(size[, fill[, encoding]])#
size<integer> The desired length of the newBuffer.fill<string> | <Buffer> | <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.
Example:
const buf = Buffer.alloc(5);
// Prints: <Buffer 00 00 00 00 00>
console.log(buf);
Allocates a new Buffer of size bytes. If the size is larger than
buffer.constants.MAX_LENGTH or smaller than 0, a RangeError will be
thrown. A zero-length Buffer will be created if size is 0.
If fill is specified, the allocated Buffer will be initialized by calling
buf.fill(fill).
Example:
const buf = Buffer.alloc(5, 'a');
// Prints: <Buffer 61 61 61 61 61>
console.log(buf);
If both fill and encoding are specified, the allocated Buffer will be
initialized by calling buf.fill(fill, encoding).
Example:
const buf = Buffer.alloc(11, 'aGVsbG8gd29ybGQ=', 'base64');
// Prints: <Buffer 68 65 6c 6c 6f 20 77 6f 72 6c 64>
console.log(buf);
Calling Buffer.alloc() can be significantly slower than the alternative
Buffer.allocUnsafe() but ensures that the newly created Buffer instance
contents will never contain sensitive data.
A TypeError will be thrown if size is not a number.
Class Method: Buffer.allocUnsafe(size)#
size<integer> The desired length of the newBuffer.
Allocates a new Buffer of size bytes. If the size is larger than
buffer.constants.MAX_LENGTH or smaller than 0, a RangeError will be
thrown. A zero-length Buffer will be 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 Buffer.alloc() instead to initialize
Buffer instances to zeroes.
Example:
const buf = Buffer.allocUnsafe(10);
// Prints: (contents may vary): <Buffer a0 8b 28 3f 01 00 00 00 50 32>
console.log(buf);
buf.fill(0);
// Prints: <Buffer 00 00 00 00 00 00 00 00 00 00>
console.log(buf);
A TypeError will be thrown if size is not a number.
Note that 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() 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.
Class Method: Buffer.allocUnsafeSlow(size)#
size<integer> The desired length of the newBuffer.
Allocates a new Buffer of size bytes. If the size is larger than
buffer.constants.MAX_LENGTH or smaller than 0, a RangeError will be
thrown. A zero-length Buffer will be 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 to zeroes.
When using Buffer.allocUnsafe() to allocate new Buffer instances,
allocations under 4KB are, by default, 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 cleanup as
many Persistent 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() then
copy out the relevant bits.
Example:
// Need to keep around a few small chunks of memory
const store = [];
socket.on('readable', () => {
const data = socket.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);
});
Use of Buffer.allocUnsafeSlow() should be used only as a last resort after
a developer has observed undue memory retention in their applications.
A TypeError will be thrown if size is not a number.
Class 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 actual byte length of a string. This is not the same as
String.prototype.length since that returns the number of characters in
a string.
Note: For 'base64' 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.
Example:
const str = '\u00bd + \u00bc = \u00be';
// Prints: ½ + ¼ = ¾: 9 characters, 12 bytes
console.log(`${str}: ${str.length} characters, ` +
`${Buffer.byteLength(str, 'utf8')} bytes`);
When string is a Buffer/DataView/TypedArray/ArrayBuffer/
SharedArrayBuffer, the actual byte length is returned.
Class Method: Buffer.compare(buf1, buf2)#
buf1<Buffer> | <Uint8Array>buf2<Buffer> | <Uint8Array>- Returns: <integer>
Compares buf1 to buf2 typically for the purpose of sorting arrays of
Buffer instances. This is equivalent to calling
buf1.compare(buf2).
Example:
const buf1 = Buffer.from('1234');
const buf2 = Buffer.from('0123');
const arr = [buf1, buf2];
// Prints: [ <Buffer 30 31 32 33>, <Buffer 31 32 33 34> ]
// (This result is equal to: [buf2, buf1])
console.log(arr.sort(Buffer.compare));
Class Method: Buffer.concat(list[, totalLength])#
list<Array> List ofBufferorUint8Arrayinstances to concat.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. This however causes an additional loop to be executed in order to
calculate the totalLength, so it is faster to provide the length explicitly if
it is already known.
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.
Example: 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;
// Prints: 42
console.log(totalLength);
const bufA = Buffer.concat([buf1, buf2, buf3], totalLength);
// Prints: <Buffer 00 00 00 00 ...>
console.log(bufA);
// Prints: 42
console.log(bufA.length);
Class Method: Buffer.from(array)#
array<Array>
Allocates a new Buffer using an array of octets.
Example:
// Creates a new Buffer containing 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.
Class Method: Buffer.from(arrayBuffer[, byteOffset[, length]])#
arrayBuffer<ArrayBuffer> | <SharedArrayBuffer> AnArrayBuffer,SharedArrayBuffer, or the.bufferproperty of aTypedArray.byteOffset<integer> Index of first byte to expose. Default:0.length<integer> Number of bytes to expose. Default:arrayBuffer.length - 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.
Example:
const arr = new Uint16Array(2);
arr[0] = 5000;
arr[1] = 4000;
// Shares memory with `arr`
const buf = Buffer.from(arr.buffer);
// Prints: <Buffer 88 13 a0 0f>
console.log(buf);
// Changing the original Uint16Array changes the Buffer also
arr[1] = 6000;
// Prints: <Buffer 88 13 70 17>
console.log(buf);
The optional byteOffset and length arguments specify a memory range within
the arrayBuffer that will be shared by the Buffer.
Example:
const ab = new ArrayBuffer(10);
const buf = Buffer.from(ab, 0, 2);
// Prints: 2
console.log(buf.length);
A TypeError will be thrown if arrayBuffer is not an ArrayBuffer or a
SharedArrayBuffer.
Class Method: Buffer.from(buffer)#
buffer<Buffer> | <Uint8Array> An existingBufferorUint8Arrayfrom which to copy data.
Copies the passed buffer data onto a new Buffer instance.
Example:
const buf1 = Buffer.from('buffer');
const buf2 = Buffer.from(buf1);
buf1[0] = 0x61;
// Prints: auffer
console.log(buf1.toString());
// Prints: buffer
console.log(buf2.toString());
A TypeError will be thrown if buffer is not a Buffer.
Class Method: Buffer.from(string[, encoding])#
Creates a new Buffer containing string. The encoding parameter identifies
the character encoding of string.
Examples:
const buf1 = Buffer.from('this is a tést');
// Prints: this is a tést
console.log(buf1.toString());
// Prints: this is a tC)st
console.log(buf1.toString('ascii'));
const buf2 = Buffer.from('7468697320697320612074c3a97374', 'hex');
// Prints: this is a tést
console.log(buf2.toString());
A TypeError will be thrown if string is not a string.
Class Method: Buffer.from(object[, offsetOrEncoding[, length]])#
object<Object> An object supportingSymbol.toPrimitiveorvalueOf()offsetOrEncoding<number> | <string> A byte-offset or encoding, depending on the value returned either byobject.valueOf()orobject[Symbol.toPrimitive]().length<number> A length, depending on the value returned either byobject.valueOf()orobject[Symbol.toPrimitive]().
For objects whose valueOf() function returns a value not strictly equal to
object, returns Buffer.from(object.valueOf(), offsetOrEncoding, length).
For example:
const buf = Buffer.from(new String('this is a test'));
// <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](), offsetOrEncoding, length).
For example:
class Foo {
[Symbol.toPrimitive]() {
return 'this is a test';
}
}
const buf = Buffer.from(new Foo(), 'utf8');
// <Buffer 74 68 69 73 20 69 73 20 61 20 74 65 73 74>
Class Method: Buffer.isBuffer(obj)#
Returns true if obj is a Buffer, false otherwise.
Class Method: Buffer.isEncoding(encoding)#
Returns true if encoding contains a supported character encoding, or false
otherwise.
Class Property: Buffer.poolSize#
- <integer> Default:
8192
This is the number of bytes used to determine the size of pre-allocated, internal
Buffer instances used for pooling. This value may be modified.
buf[index]#
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 - that is, getting returns undefined and
setting does nothing.
Example: Copy an ASCII string into a Buffer, one byte at a time
const str = 'Node.js';
const buf = Buffer.allocUnsafe(str.length);
for (let i = 0; i < str.length; i++) {
buf[i] = str.charCodeAt(i);
}
// Prints: Node.js
console.log(buf.toString('ascii'));
buf.buffer#
The buffer property references the underlying ArrayBuffer object based on
which this Buffer object is created.
const arrayBuffer = new ArrayBuffer(16);
const buffer = Buffer.from(arrayBuffer);
console.log(buffer.buffer === arrayBuffer);
// Prints: true
buf.compare(target[, targetStart[, targetEnd[, sourceStart[, sourceEnd]]]])#
target<Buffer> | <Uint8Array> ABufferorUint8Arrayto compare to.targetStart<integer> The offset withintargetat which to begin comparison. Default:0.targetEnd<integer> The offset withtargetat 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.
Examples:
const buf1 = Buffer.from('ABC');
const buf2 = Buffer.from('BCD');
const buf3 = Buffer.from('ABCD');
// Prints: 0
console.log(buf1.compare(buf1));
// Prints: -1
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: [ <Buffer 41 42 43>, <Buffer 41 42 43 44>, <Buffer 42 43 44> ]
// (This result is equal to: [buf1, buf3, buf2])
console.log([buf1, buf2, buf3].sort(Buffer.compare));
The optional targetStart, targetEnd, sourceStart, and sourceEnd
arguments can be used to limit the comparison to specific ranges within target
and buf respectively.
Examples:
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]);
// Prints: 0
console.log(buf1.compare(buf2, 5, 9, 0, 4));
// Prints: -1
console.log(buf1.compare(buf2, 0, 6, 4));
// Prints: 1
console.log(buf1.compare(buf2, 5, 6, 5));
A RangeError will be 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 copying to. Default:0.sourceStart<integer> The offset withinbufat which to begin copying from. 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.
Example: Create two Buffer instances, buf1 and buf2, and copy buf1 from
byte 16 through byte 19 into buf2, starting at the 8th byte in buf2
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;
}
buf1.copy(buf2, 8, 16, 20);
// Prints: !!!!!!!!qrst!!!!!!!!!!!!!
console.log(buf2.toString('ascii', 0, 25));
Example: Create a single 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);
// Prints: efghijghijklmnopqrstuvwxyz
console.log(buf.toString());
buf.entries()#
- Returns: <Iterator>
Creates and returns an iterator of [index, byte] pairs from the contents of
buf.
Example: Log the entire contents of a Buffer
const buf = Buffer.from('buffer');
// Prints:
// [0, 98]
// [1, 117]
// [2, 102]
// [3, 102]
// [4, 101]
// [5, 114]
for (const pair of buf.entries()) {
console.log(pair);
}
buf.equals(otherBuffer)#
otherBuffer<Buffer> ABufferorUint8Arrayto compare to.- Returns: <boolean>
Returns true if both buf and otherBuffer have exactly the same bytes,
false otherwise.
Examples:
const buf1 = Buffer.from('ABC');
const buf2 = Buffer.from('414243', 'hex');
const buf3 = Buffer.from('ABCD');
// Prints: true
console.log(buf1.equals(buf2));
// Prints: false
console.log(buf1.equals(buf3));
buf.fill(value[, offset[, end]][, encoding])#
value<string> | <Buffer> | <integer> The value to fillbufwith.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> Ifvalueis a string, this is its encoding. 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. This is meant to be a small simplification to
allow the creation and filling of a Buffer to be done on a single line.
Example: Fill a Buffer with the ASCII character 'h'
const b = Buffer.allocUnsafe(50).fill('h');
// Prints: hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
console.log(b.toString());
value is coerced to a uint32 value if it is not a String or Integer.
If the final write of a fill() operation falls on a multi-byte character,
then only the first bytes of that character that fit into buf are written.
Example: Fill a Buffer with a two-byte character
// Prints: <Buffer c8 a2 c8>
console.log(Buffer.allocUnsafe(3).fill('\u0222'));
If value contains invalid characters, it is truncated.
If no valid fill data remains, then the buffer is either zero-filled or no filling is performed, depending on the input type. That behavior is dictated by compatibility reasons and was changed to throwing an exception in Node.js v10, so it's not recommended to rely on that.
const buf = Buffer.allocUnsafe(5);
// Prints: <Buffer 61 61 61 61 61>
console.log(buf.fill('a'));
// Prints: <Buffer aa aa aa aa aa>
console.log(buf.fill('aazz', 'hex'));
// Prints: <Buffer aa aa aa aa aa>
console.log(buf.fill('zz', 'hex'));
buf.includes(value[, byteOffset][, encoding])#
value<string> | <Buffer> | <integer> What to search for.byteOffset<integer> Where to begin searching inbuf. Default:0.encoding<string> Ifvalueis a string, this is its encoding. Default:'utf8'.- Returns: <boolean>
trueifvaluewas found inbuf,falseotherwise.
Equivalent to buf.indexOf() !== -1.
Examples:
const buf = Buffer.from('this is a buffer');
// Prints: true
console.log(buf.includes('this'));
// Prints: true
console.log(buf.includes('is'));
// Prints: true
console.log(buf.includes(Buffer.from('a buffer')));
// Prints: true
// (97 is the decimal ASCII value for 'a')
console.log(buf.includes(97));
// Prints: false
console.log(buf.includes(Buffer.from('a buffer example')));
// Prints: true
console.log(buf.includes(Buffer.from('a buffer example').slice(0, 8)));
// Prints: false
console.log(buf.includes('this', 4));
buf.indexOf(value[, byteOffset][, encoding])#
value<string> | <Buffer> | <Uint8Array> | <integer> What to search for.byteOffset<integer> Where to begin searching inbuf. 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.slice(). - a number,
valuewill be interpreted as an unsigned 8-bit integer value between0and255.
Examples:
const buf = Buffer.from('this is a buffer');
// Prints: 0
console.log(buf.indexOf('this'));
// Prints: 2
console.log(buf.indexOf('is'));
// Prints: 8
console.log(buf.indexOf(Buffer.from('a buffer')));
// Prints: 8
// (97 is the decimal ASCII value for 'a')
console.log(buf.indexOf(97));
// Prints: -1
console.log(buf.indexOf(Buffer.from('a buffer example')));
// Prints: 8
console.log(buf.indexOf(Buffer.from('a buffer example').slice(0, 8)));
const utf16Buffer = Buffer.from('\u039a\u0391\u03a3\u03a3\u0395', 'ucs2');
// Prints: 4
console.log(utf16Buffer.indexOf('\u03a3', 0, 'ucs2'));
// Prints: 6
console.log(utf16Buffer.indexOf('\u03a3', -4, 'ucs2'));
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 or 0, like {}, [], null or undefined, will search
the whole buffer. This behavior matches String#indexOf().
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).
Example:
const buf = Buffer.from('buffer');
// Prints:
// 0
// 1
// 2
// 3
// 4
// 5
for (const key of buf.keys()) {
console.log(key);
}
buf.lastIndexOf(value[, byteOffset][, encoding])#
value<string> | <Buffer> | <Uint8Array> | <integer> What to search for.byteOffset<integer> Where to begin searching inbuf. 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.
Examples:
const buf = Buffer.from('this buffer is a buffer');
// Prints: 0
console.log(buf.lastIndexOf('this'));
// Prints: 17
console.log(buf.lastIndexOf('buffer'));
// Prints: 17
console.log(buf.lastIndexOf(Buffer.from('buffer')));
// Prints: 15
// (97 is the decimal ASCII value for 'a')
console.log(buf.lastIndexOf(97));
// Prints: -1
console.log(buf.lastIndexOf(Buffer.from('yolo')));
// Prints: 5
console.log(buf.lastIndexOf('buffer', 5));
// Prints: -1
console.log(buf.lastIndexOf('buffer', 4));
const utf16Buffer = Buffer.from('\u039a\u0391\u03a3\u03a3\u0395', 'ucs2');
// Prints: 6
console.log(utf16Buffer.lastIndexOf('\u03a3', undefined, 'ucs2'));
// Prints: 4
console.log(utf16Buffer.lastIndexOf('\u03a3', -5, 'ucs2'));
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#lastIndexOf().
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 amount of memory allocated for buf in bytes. Note that this
does not necessarily reflect the amount of "usable" data within buf.
Example: Create a Buffer and write a shorter ASCII string to it
const buf = Buffer.alloc(1234);
// Prints: 1234
console.log(buf.length);
buf.write('some string', 0, 'ascii');
// Prints: 1234
console.log(buf.length);
While the length property is not immutable, changing the value of length
can result in undefined and inconsistent behavior. Applications that wish to
modify the length of a Buffer should therefore treat length as read-only and
use buf.slice() to create a new Buffer.
Examples:
let buf = Buffer.allocUnsafe(10);
buf.write('abcdefghj', 0, 'ascii');
// Prints: 10
console.log(buf.length);
buf = buf.slice(0, 5);
// Prints: 5
console.log(buf.length);
buf.parent#
buf.buffer instead.The buf.parent property is a deprecated alias for buf.buffer.
buf.readDoubleBE(offset[, noAssert])#
buf.readDoubleLE(offset[, noAssert])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy:0 <= offset <= buf.length - 8.noAssert<boolean> Skipoffsetvalidation? Default:false- Returns: <number>
Reads a 64-bit double from buf at the specified offset with specified
endian format (readDoubleBE() returns big endian, readDoubleLE() returns
little endian).
Setting noAssert to true allows offset to be beyond the end of buf, but
the resulting behavior is undefined.
Examples:
const buf = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]);
// Prints: 8.20788039913184e-304
console.log(buf.readDoubleBE());
// Prints: 5.447603722011605e-270
console.log(buf.readDoubleLE());
// Throws an exception: RangeError: Index out of range
console.log(buf.readDoubleLE(1));
// Warning: reads passed end of buffer!
// This will result in a segmentation fault! Don't do this!
console.log(buf.readDoubleLE(1, true));
buf.readFloatBE(offset[, noAssert])#
buf.readFloatLE(offset[, noAssert])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy:0 <= offset <= buf.length - 4.noAssert<boolean> Skipoffsetvalidation? Default:false- Returns: <number>
Reads a 32-bit float from buf at the specified offset with specified
endian format (readFloatBE() returns big endian, readFloatLE() returns
little endian).
Setting noAssert to true allows offset to be beyond the end of buf, but
the resulting behavior is undefined.
Examples:
const buf = Buffer.from([1, 2, 3, 4]);
// Prints: 2.387939260590663e-38
console.log(buf.readFloatBE());
// Prints: 1.539989614439558e-36
console.log(buf.readFloatLE());
// Throws an exception: RangeError: Index out of range
console.log(buf.readFloatLE(1));
// Warning: reads passed end of buffer!
// This will result in a segmentation fault! Don't do this!
console.log(buf.readFloatLE(1, true));
buf.readInt8(offset[, noAssert])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy:0 <= offset <= buf.length - 1.noAssert<boolean> Skipoffsetvalidation? Default:false- Returns: <integer>
Reads a signed 8-bit integer from buf at the specified offset.
Setting noAssert to true allows offset to be beyond the end of buf, but
the resulting behavior is undefined.
Integers read from a Buffer are interpreted as two's complement signed values.
Examples:
const buf = Buffer.from([-1, 5]);
// Prints: -1
console.log(buf.readInt8(0));
// Prints: 5
console.log(buf.readInt8(1));
// Throws an exception: RangeError: Index out of range
console.log(buf.readInt8(2));
buf.readInt16BE(offset[, noAssert])#
buf.readInt16LE(offset[, noAssert])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy:0 <= offset <= buf.length - 2.noAssert<boolean> Skipoffsetvalidation? Default:false- Returns: <integer>
Reads a signed 16-bit integer from buf at the specified offset with
the specified endian format (readInt16BE() returns big endian,
readInt16LE() returns little endian).
Setting noAssert to true allows offset to be beyond the end of buf, but
the resulting behavior is undefined.
Integers read from a Buffer are interpreted as two's complement signed values.
Examples:
const buf = Buffer.from([0, 5]);
// Prints: 5
console.log(buf.readInt16BE());
// Prints: 1280
console.log(buf.readInt16LE());
// Throws an exception: RangeError: Index out of range
console.log(buf.readInt16LE(1));
buf.readInt32BE(offset[, noAssert])#
buf.readInt32LE(offset[, noAssert])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy:0 <= offset <= buf.length - 4.noAssert<boolean> Skipoffsetvalidation? Default:false- Returns: <integer>
Reads a signed 32-bit integer from buf at the specified offset with
the specified endian format (readInt32BE() returns big endian,
readInt32LE() returns little endian).
Setting noAssert to true allows offset to be beyond the end of buf, but
the resulting behavior is undefined.
Integers read from a Buffer are interpreted as two's complement signed values.
Examples:
const buf = Buffer.from([0, 0, 0, 5]);
// Prints: 5
console.log(buf.readInt32BE());
// Prints: 83886080
console.log(buf.readInt32LE());
// Throws an exception: RangeError: Index out of range
console.log(buf.readInt32LE(1));
buf.readIntBE(offset, byteLength[, noAssert])#
buf.readIntLE(offset, byteLength[, noAssert])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy:0 <= offset <= buf.length - byteLength.byteLength<integer> Number of bytes to read. Must satisfy:0 < byteLength <= 6.noAssert<boolean> SkipoffsetandbyteLengthvalidation? Default:false.- Returns: <integer>
Reads byteLength number of bytes from buf at the specified offset
and interprets the result as a two's complement signed value. Supports up to 48
bits of accuracy.
Setting noAssert to true allows offset to be beyond the end of buf, but
the resulting behavior is undefined.
Examples:
const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]);
// Prints: -546f87a9cbee
console.log(buf.readIntLE(0, 6).toString(16));
// Prints: 1234567890ab
console.log(buf.readIntBE(0, 6).toString(16));
// Throws an exception: RangeError: Index out of range
console.log(buf.readIntBE(1, 6).toString(16));
buf.readUInt8(offset[, noAssert])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy:0 <= offset <= buf.length - 1.noAssert<boolean> Skipoffsetvalidation? Default:false- Returns: <integer>
Reads an unsigned 8-bit integer from buf at the specified offset.
Setting noAssert to true allows offset to be beyond the end of buf, but
the resulting behavior is undefined.
Examples:
const buf = Buffer.from([1, -2]);
// Prints: 1
console.log(buf.readUInt8(0));
// Prints: 254
console.log(buf.readUInt8(1));
// Throws an exception: RangeError: Index out of range
console.log(buf.readUInt8(2));
buf.readUInt16BE(offset[, noAssert])#
buf.readUInt16LE(offset[, noAssert])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy:0 <= offset <= buf.length - 2.noAssert<boolean> Skipoffsetvalidation? Default:false- Returns: <integer>
Reads an unsigned 16-bit integer from buf at the specified offset with
specified endian format (readUInt16BE() returns big endian, readUInt16LE()
returns little endian).
Setting noAssert to true allows offset to be beyond the end of buf, but
the resulting behavior is undefined.
Examples:
const buf = Buffer.from([0x12, 0x34, 0x56]);
// Prints: 1234
console.log(buf.readUInt16BE(0).toString(16));
// Prints: 3412
console.log(buf.readUInt16LE(0).toString(16));
// Prints: 3456
console.log(buf.readUInt16BE(1).toString(16));
// Prints: 5634
console.log(buf.readUInt16LE(1).toString(16));
// Throws an exception: RangeError: Index out of range
console.log(buf.readUInt16LE(2).toString(16));
buf.readUInt32BE(offset[, noAssert])#
buf.readUInt32LE(offset[, noAssert])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy:0 <= offset <= buf.length - 4.noAssert<boolean> Skipoffsetvalidation? Default:false- Returns: <integer>
Reads an unsigned 32-bit integer from buf at the specified offset with
specified endian format (readUInt32BE() returns big endian,
readUInt32LE() returns little endian).
Setting noAssert to true allows offset to be beyond the end of buf, but
the resulting behavior is undefined.
Examples:
const buf = Buffer.from([0x12, 0x34, 0x56, 0x78]);
// Prints: 12345678
console.log(buf.readUInt32BE(0).toString(16));
// Prints: 78563412
console.log(buf.readUInt32LE(0).toString(16));
// Throws an exception: RangeError: Index out of range
console.log(buf.readUInt32LE(1).toString(16));
buf.readUIntBE(offset, byteLength[, noAssert])#
buf.readUIntLE(offset, byteLength[, noAssert])#
offset<integer> Number of bytes to skip before starting to read. Must satisfy:0 <= offset <= buf.length - byteLength.byteLength<integer> Number of bytes to read. Must satisfy:0 < byteLength <= 6.noAssert<boolean> SkipoffsetandbyteLengthvalidation? Default:false- Returns: <integer>
Reads byteLength number of bytes from buf at the specified offset
and interprets the result as an unsigned integer. Supports up to 48
bits of accuracy.
Setting noAssert to true allows offset to be beyond the end of buf, but
the resulting behavior is undefined.
Examples:
const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]);
// Prints: 1234567890ab
console.log(buf.readUIntBE(0, 6).toString(16));
// Prints: ab9078563412
console.log(buf.readUIntLE(0, 6).toString(16));
// Throws an exception: RangeError: Index out of range
console.log(buf.readUIntBE(1, 6).toString(16));
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>
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.
Note: Modifying the new Buffer slice will modify the memory in the
original Buffer because the allocated memory of the two objects overlap.
Example: Create a Buffer with the ASCII alphabet, take a slice, and then 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.slice(0, 3);
// Prints: abc
console.log(buf2.toString('ascii', 0, buf2.length));
buf1[0] = 33;
// Prints: !bc
console.log(buf2.toString('ascii', 0, buf2.length));
Specifying negative indexes causes the slice to be generated relative to the
end of buf rather than the beginning.
Examples:
const buf = Buffer.from('buffer');
// Prints: buffe
// (Equivalent to buf.slice(0, 5))
console.log(buf.slice(-6, -1).toString());
// Prints: buff
// (Equivalent to buf.slice(0, 4))
console.log(buf.slice(-6, -2).toString());
// Prints: uff
// (Equivalent to buf.slice(1, 4))
console.log(buf.slice(-5, -2).toString());
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 a RangeError if buf.length is not a multiple of 2.
Examples:
const buf1 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]);
// Prints: <Buffer 01 02 03 04 05 06 07 08>
console.log(buf1);
buf1.swap16();
// Prints: <Buffer 02 01 04 03 06 05 08 07>
console.log(buf1);
const buf2 = Buffer.from([0x1, 0x2, 0x3]);
// Throws an exception: RangeError: Buffer size must be a multiple of 16-bits
buf2.swap16();
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 a RangeError if buf.length is not a multiple of 4.
Examples:
const buf1 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]);
// Prints: <Buffer 01 02 03 04 05 06 07 08>
console.log(buf1);
buf1.swap32();
// Prints: <Buffer 04 03 02 01 08 07 06 05>
console.log(buf1);
const buf2 = Buffer.from([0x1, 0x2, 0x3]);
// Throws an exception: RangeError: Buffer size must be a multiple of 32-bits
buf2.swap32();
buf.swap64()#
- Returns: <Buffer> A reference to
buf.
Interprets buf as an array of 64-bit numbers and swaps the byte order in-place.
Throws a RangeError if buf.length is not a multiple of 8.
Examples:
const buf1 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]);
// Prints: <Buffer 01 02 03 04 05 06 07 08>
console.log(buf1);
buf1.swap64();
// Prints: <Buffer 08 07 06 05 04 03 02 01>
console.log(buf1);
const buf2 = Buffer.from([0x1, 0x2, 0x3]);
// Throws an exception: RangeError: Buffer size must be a multiple of 64-bits
buf2.swap64();
Note that JavaScript cannot encode 64-bit integers. This method is intended for working with 64-bit floats.
buf.toJSON()#
- Returns: <Object>
Returns a JSON representation of buf. JSON.stringify() implicitly calls
this function when stringifying a Buffer instance.
Example:
const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5]);
const json = JSON.stringify(buf);
// Prints: {"type":"Buffer","data":[1,2,3,4,5]}
console.log(json);
const copy = JSON.parse(json, (key, value) => {
return value && value.type === 'Buffer' ?
Buffer.from(value.data) :
value;
});
// Prints: <Buffer 01 02 03 04 05>
console.log(copy);
buf.toString([encoding[, start[, end]]])#
encoding<string> The character encoding to decode to. 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.
The maximum length of a string instance (in UTF-16 code units) is available
as buffer.constants.MAX_STRING_LENGTH.
Examples:
const buf1 = Buffer.allocUnsafe(26);
for (let i = 0; i < 26; i++) {
// 97 is the decimal ASCII value for 'a'
buf1[i] = i + 97;
}
// Prints: abcdefghijklmnopqrstuvwxyz
console.log(buf1.toString('ascii'));
// Prints: abcde
console.log(buf1.toString('ascii', 0, 5));
const buf2 = Buffer.from('tést');
// Prints: 74c3a97374
console.log(buf2.toString('hex'));
// Prints: té
console.log(buf2.toString('utf8', 0, 3));
// Prints: té
console.log(buf2.toString(undefined, 0, 3));
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.
Examples:
const buf = Buffer.from('buffer');
// Prints:
// 98
// 117
// 102
// 102
// 101
// 114
for (const value of buf.values()) {
console.log(value);
}
// Prints:
// 98
// 117
// 102
// 102
// 101
// 114
for (const value of buf) {
console.log(value);
}
buf.write(string[, offset[, length]][, encoding])#
string<string> String to be written tobuf.offset<integer> Number of bytes to skip before starting to writestring. Default:0.length<integer> Number of bytes to write. 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 a partial amount of string will
be written. However, partially encoded characters will not be written.
Example:
const buf = Buffer.allocUnsafe(256);
const len = buf.write('\u00bd + \u00bc = \u00be', 0);
// Prints: 12 bytes: ½ + ¼ = ¾
console.log(`${len} bytes: ${buf.toString('utf8', 0, len)}`);
buf.writeDoubleBE(value, offset[, noAssert])#
buf.writeDoubleLE(value, offset[, noAssert])#
value<number> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy:0 <= offset <= buf.length - 8.noAssert<boolean> Skipvalueandoffsetvalidation? Default:false- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset with specified endian
format (writeDoubleBE() writes big endian, writeDoubleLE() writes little
endian). value should be a valid 64-bit double. Behavior is undefined when
value is anything other than a 64-bit double.
Setting noAssert to true allows the encoded form of value to extend beyond
the end of buf, but the resulting behavior is undefined.
Examples:
const buf = Buffer.allocUnsafe(8);
buf.writeDoubleBE(0xdeadbeefcafebabe, 0);
// Prints: <Buffer 43 eb d5 b7 dd f9 5f d7>
console.log(buf);
buf.writeDoubleLE(0xdeadbeefcafebabe, 0);
// Prints: <Buffer d7 5f f9 dd b7 d5 eb 43>
console.log(buf);
buf.writeFloatBE(value, offset[, noAssert])#
buf.writeFloatLE(value, offset[, noAssert])#
value<number> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy:0 <= offset <= buf.length - 4.noAssert<boolean> Skipvalueandoffsetvalidation? Default:false- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset with specified endian
format (writeFloatBE() writes big endian, writeFloatLE() writes little
endian). value should be a valid 32-bit float. Behavior is undefined when
value is anything other than a 32-bit float.
Setting noAssert to true allows the encoded form of value to extend beyond
the end of buf, but the resulting behavior is undefined.
Examples:
const buf = Buffer.allocUnsafe(4);
buf.writeFloatBE(0xcafebabe, 0);
// Prints: <Buffer 4f 4a fe bb>
console.log(buf);
buf.writeFloatLE(0xcafebabe, 0);
// Prints: <Buffer bb fe 4a 4f>
console.log(buf);
buf.writeInt8(value, offset[, noAssert])#
value<integer> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy:0 <= offset <= buf.length - 1.noAssert<boolean> Skipvalueandoffsetvalidation? Default:false- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset. value should be a valid
signed 8-bit integer. Behavior is undefined when value is anything other than
a signed 8-bit integer.
Setting noAssert to true allows the encoded form of value to extend beyond
the end of buf, but the resulting behavior is undefined.
value is interpreted and written as a two's complement signed integer.
Examples:
const buf = Buffer.allocUnsafe(2);
buf.writeInt8(2, 0);
buf.writeInt8(-2, 1);
// Prints: <Buffer 02 fe>
console.log(buf);
buf.writeInt16BE(value, offset[, noAssert])#
buf.writeInt16LE(value, offset[, noAssert])#
value<integer> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy:0 <= offset <= buf.length - 2.noAssert<boolean> Skipvalueandoffsetvalidation? Default:false- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset with specified endian
format (writeInt16BE() writes big endian, writeInt16LE() writes little
endian). value should be a valid signed 16-bit integer. Behavior is undefined
when value is anything other than a signed 16-bit integer.
Setting noAssert to true allows the encoded form of value to extend beyond
the end of buf, but the resulting behavior is undefined.
value is interpreted and written as a two's complement signed integer.
Examples:
const buf = Buffer.allocUnsafe(4);
buf.writeInt16BE(0x0102, 0);
buf.writeInt16LE(0x0304, 2);
// Prints: <Buffer 01 02 04 03>
console.log(buf);
buf.writeInt32BE(value, offset[, noAssert])#
buf.writeInt32LE(value, offset[, noAssert])#
value<integer> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy:0 <= offset <= buf.length - 4.noAssert<boolean> Skipvalueandoffsetvalidation? Default:false- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset with specified endian
format (writeInt32BE() writes big endian, writeInt32LE() writes little
endian). value should be a valid signed 32-bit integer. Behavior is undefined
when value is anything other than a signed 32-bit integer.
Setting noAssert to true allows the encoded form of value to extend beyond
the end of buf, but the resulting behavior is undefined.
value is interpreted and written as a two's complement signed integer.
Examples:
const buf = Buffer.allocUnsafe(8);
buf.writeInt32BE(0x01020304, 0);
buf.writeInt32LE(0x05060708, 4);
// Prints: <Buffer 01 02 03 04 08 07 06 05>
console.log(buf);
buf.writeIntBE(value, offset, byteLength[, noAssert])#
buf.writeIntLE(value, offset, byteLength[, noAssert])#
value<integer> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy:0 <= offset <= buf.length - byteLength.byteLength<integer> Number of bytes to write. Must satisfy:0 < byteLength <= 6.noAssert<boolean> Skipvalue,offset, andbyteLengthvalidation? Default:false- Returns: <integer>
offsetplus the number of bytes written.
Writes byteLength bytes of value to buf at the specified offset.
Supports up to 48 bits of accuracy. Behavior is undefined when value is
anything other than a signed integer.
Setting noAssert to true allows the encoded form of value to extend beyond
the end of buf, but the resulting behavior is undefined.
Examples:
const buf = Buffer.allocUnsafe(6);
buf.writeIntBE(0x1234567890ab, 0, 6);
// Prints: <Buffer 12 34 56 78 90 ab>
console.log(buf);
buf.writeIntLE(0x1234567890ab, 0, 6);
// Prints: <Buffer ab 90 78 56 34 12>
console.log(buf);
buf.writeUInt8(value, offset[, noAssert])#
value<integer> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy:0 <= offset <= buf.length - 1.noAssert<boolean> Skipvalueandoffsetvalidation? Default:false- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset. value should be a
valid unsigned 8-bit integer. Behavior is undefined when value is anything
other than an unsigned 8-bit integer.
Setting noAssert to true allows the encoded form of value to extend beyond
the end of buf, but the resulting behavior is undefined.
Examples:
const buf = Buffer.allocUnsafe(4);
buf.writeUInt8(0x3, 0);
buf.writeUInt8(0x4, 1);
buf.writeUInt8(0x23, 2);
buf.writeUInt8(0x42, 3);
// Prints: <Buffer 03 04 23 42>
console.log(buf);
buf.writeUInt16BE(value, offset[, noAssert])#
buf.writeUInt16LE(value, offset[, noAssert])#
value<integer> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy:0 <= offset <= buf.length - 2.noAssert<boolean> Skipvalueandoffsetvalidation? Default:false- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset with specified endian
format (writeUInt16BE() writes big endian, writeUInt16LE() writes little
endian). value should be a valid unsigned 16-bit integer. Behavior is
undefined when value is anything other than an unsigned 16-bit integer.
Setting noAssert to true allows the encoded form of value to extend beyond
the end of buf, but the resulting behavior is undefined.
Examples:
const buf = Buffer.allocUnsafe(4);
buf.writeUInt16BE(0xdead, 0);
buf.writeUInt16BE(0xbeef, 2);
// Prints: <Buffer de ad be ef>
console.log(buf);
buf.writeUInt16LE(0xdead, 0);
buf.writeUInt16LE(0xbeef, 2);
// Prints: <Buffer ad de ef be>
console.log(buf);
buf.writeUInt32BE(value, offset[, noAssert])#
buf.writeUInt32LE(value, offset[, noAssert])#
value<integer> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy:0 <= offset <= buf.length - 4.noAssert<boolean> Skipvalueandoffsetvalidation? Default:false- Returns: <integer>
offsetplus the number of bytes written.
Writes value to buf at the specified offset with specified endian
format (writeUInt32BE() writes big endian, writeUInt32LE() writes little
endian). value should be a valid unsigned 32-bit integer. Behavior is
undefined when value is anything other than an unsigned 32-bit integer.
Setting noAssert to true allows the encoded form of value to extend beyond
the end of buf, but the resulting behavior is undefined.
Examples:
const buf = Buffer.allocUnsafe(4);
buf.writeUInt32BE(0xfeedface, 0);
// Prints: <Buffer fe ed fa ce>
console.log(buf);
buf.writeUInt32LE(0xfeedface, 0);
// Prints: <Buffer ce fa ed fe>
console.log(buf);
buf.writeUIntBE(value, offset, byteLength[, noAssert])#
buf.writeUIntLE(value, offset, byteLength[, noAssert])#
value<integer> Number to be written tobuf.offset<integer> Number of bytes to skip before starting to write. Must satisfy:0 <= offset <= buf.length - byteLength.byteLength<integer> Number of bytes to write. Must satisfy:0 < byteLength <= 6.noAssert<boolean> Skipvalue,offset, andbyteLengthvalidation? Default:false.- Returns: <integer>
offsetplus the number of bytes written.
Writes byteLength bytes of value to buf at the specified offset.
Supports up to 48 bits of accuracy. Behavior is undefined when value is
anything other than an unsigned integer.
Setting noAssert to true allows the encoded form of value to extend beyond
the end of buf, but the resulting behavior is undefined.
Examples:
const buf = Buffer.allocUnsafe(6);
buf.writeUIntBE(0x1234567890ab, 0, 6);
// Prints: <Buffer 12 34 56 78 90 ab>
console.log(buf);
buf.writeUIntLE(0x1234567890ab, 0, 6);
// Prints: <Buffer ab 90 78 56 34 12>
console.log(buf);
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.
Note that this is a property on the buffer module returned by
require('buffer'), not on the Buffer global or a Buffer instance.
buffer.kMaxLength#
- <integer> The largest size allowed for a single
Bufferinstance.
An alias for buffer.constants.MAX_LENGTH
Note that this is a property on the buffer module returned by
require('buffer'), not on the Buffer global or a Buffer instance.
buffer.transcode(source, fromEnc, toEnc)#
source<Buffer> | <Uint8Array> ABufferorUint8Arrayinstance.fromEnc<string> The current encoding.toEnc<string> To target encoding.
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.
The transcoding process will use substitution characters if a given byte sequence cannot be adequately represented in the target encoding. For instance:
const buffer = require('buffer');
const newBuf = buffer.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.
Note that this is a property on the buffer module returned by
require('buffer'), not on the Buffer global or a Buffer instance.
Class: SlowBuffer#
Buffer.allocUnsafeSlow() instead.Returns an un-pooled Buffer.
In order to avoid the garbage collection overhead of creating many individually
allocated Buffer instances, by default allocations under 4KB are sliced from a
single larger allocated object.
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 SlowBuffer then copy out the relevant bits.
Example:
// Need to keep around a few small chunks of memory
const store = [];
socket.on('readable', () => {
const data = socket.read();
// Allocate for retained data
const sb = SlowBuffer(10);
// Copy the data into the new allocation
data.copy(sb, 0, 0, 10);
store.push(sb);
});
Use of SlowBuffer should be used only as a last resort after a developer
has observed undue memory retention in their applications.
new SlowBuffer(size)#
Buffer.allocUnsafeSlow() instead.size<integer> The desired length of the newSlowBuffer.
Allocates a new Buffer of size bytes. If the size is larger than
buffer.constants.MAX_LENGTH or smaller than 0, a RangeError will be
thrown. A zero-length Buffer will be created if size is 0.
The underlying memory for SlowBuffer instances is not initialized. The
contents of a newly created SlowBuffer are unknown and may contain
sensitive data. Use buf.fill(0) to initialize a SlowBuffer to zeroes.
Example:
const { SlowBuffer } = require('buffer');
const buf = new SlowBuffer(5);
// Prints: (contents may vary): <Buffer 78 e0 82 02 01>
console.log(buf);
buf.fill(0);
// Prints: <Buffer 00 00 00 00 00>
console.log(buf);
Buffer Constants#
Note that buffer.constants is a property on the buffer module returned by
require('buffer'), not on the Buffer global or a Buffer instance.
buffer.constants.MAX_LENGTH#
- <integer> The largest size allowed for a single
Bufferinstance.
On 32-bit architectures, this value is (2^30)-1 (~1GB).
On 64-bit architectures, this value is (2^31)-1 (~2GB).
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.
C++ Addons#
Node.js Addons are dynamically-linked shared objects, written in C++, that
can be loaded into Node.js using the require() function, and used
just as if they were an ordinary Node.js module. They are used primarily to
provide an interface between JavaScript running in Node.js and C/C++ libraries.
At the moment, the method for implementing Addons is rather complicated, involving knowledge of several components and APIs :
V8: the C++ library Node.js currently 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 pthreads-like threading abstraction that may be used to power more sophisticated asynchronous Addons that need to move beyond the standard event loop. Addon authors are encouraged to think about how to avoid blocking the event loop with I/O or other time-intensive tasks by off-loading work via libuv to non-blocking system operations, worker threads or a custom use of libuv's threads.
Internal Node.js libraries. Node.js itself exports a number of C++ APIs that Addons can use — the most important of which is the
node::ObjectWrapclass.Node.js includes a number of 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 Node.js' own dependencies 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"));
}
void init(Local<Object> exports) {
NODE_SET_METHOD(exports, "hello", Method);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, init)
} // namespace demo
Note that 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 init and the
Addon module name is 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" ]
}
]
}
Note: 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'
Please see the examples below for further information or https://github.com/arturadib/node-qt for an example in production.
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.
Note that 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 Node.js' own dependencies#
Node.js uses a number of 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 make direct use of the Node.js and V8 APIs for implementing Addons. It is important to understand that 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 currently 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.
N-API#
N-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 version 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 N-API are used.
To use N-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 N-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, "hello", 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 the section titled C/C++ Addons - N-API.
Addon examples#
Following are some example Addons intended to help developers get started. The examples make use of 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. For example:
"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")));
return;
}
// Check the argument types
if (!args[0]->IsNumber() || !args[1]->IsNumber()) {
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8(isolate, "Wrong arguments")));
return;
}
// Perform the operation
double value = args[0]->NumberValue() + args[1]->NumberValue();
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::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<Function> cb = Local<Function>::Cast(args[0]);
const unsigned argc = 1;
Local<Value> argv[argc] = { String::NewFromUtf8(isolate, "hello world") };
cb->Call(Null(isolate), argc, argv);
}
void Init(Local<Object> exports, Local<Object> module) {
NODE_SET_METHOD(module, "exports", RunCallback);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, Init)
} // namespace demo
Note that 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'
});
Note that, 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::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<Object> obj = Object::New(isolate);
obj->Set(String::NewFromUtf8(isolate, "msg"), args[0]->ToString());
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::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"));
}
void CreateFunction(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, MyFunction);
Local<Function> fn = tpl->GetFunction();
// omit this to make it anonymous
fn->SetName(String::NewFromUtf8(isolate, "theFunction"));
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);
static v8::Persistent<v8::Function> constructor;
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::Persistent;
using v8::String;
using v8::Value;
Persistent<Function> MyObject::constructor;
MyObject::MyObject(double value) : value_(value) {
}
MyObject::~MyObject() {
}
void MyObject::Init(Local<Object> exports) {
Isolate* isolate = exports->GetIsolate();
// Prepare constructor template
Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);
tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject"));
tpl->InstanceTemplate()->SetInternalFieldCount(1);
// Prototype
NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne);
constructor.Reset(isolate, tpl->GetFunction());
exports->Set(String::NewFromUtf8(isolate, "MyObject"),
tpl->GetFunction());
}
void MyObject::New(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
if (args.IsConstructCall()) {
// Invoked as constructor: `new MyObject(...)`
double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
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<Context> context = isolate->GetCurrentContext();
Local<Function> cons = Local<Function>::New(isolate, constructor);
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
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::Persistent<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 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::Persistent;
using v8::String;
using v8::Value;
Persistent<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"));
tpl->InstanceTemplate()->SetInternalFieldCount(1);
// Prototype
NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne);
constructor.Reset(isolate, tpl->GetFunction());
}
void MyObject::New(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
if (args.IsConstructCall()) {
// Invoked as constructor: `new MyObject(...)`
double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
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<Context> context = isolate->GetCurrentContext();
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: