Bidirectional socket-style communication
Network connections
Node.js · Class
stream.Duplex is a bidirectional stream that implements both the Readable and Writable interfaces. Extend it or construct it with callbacks to define how data is read and written.
A Duplex is a stream with independent readable and writable sides. Create one with new Duplex(options), provide the readable implementation through read or _read(), and provide writable behavior through write or _write(); the two directions can be consumed and supplied separately.
new stream.Duplex(options)| Name | Type | Description |
|---|---|---|
options | Object | Configuration object passed to the readable and writable stream constructors; it can include options such as allowHalfOpen and the read/write callbacks. |
A new stream.Duplex instance.
_read(), _write(), _writev(), and _final().import { Duplex } from 'node:stream';
const stream = new Duplex({
read() {},
write(chunk, encoding, callback) {
process.stdout.write(`received: ${chunk.toString()}`);
callback();
}
});
stream.on('data', chunk => console.log(`read: ${chunk}`));
stream.push('from readable side');
stream.push(null);
stream.end('from writable side');This runnable example creates a Duplex with separate readable and writable behavior, pushes one readable chunk, then writes one writable chunk.
Network connections
Compression and encryption
Custom adapters
A Duplex implements both the Readable and Writable interfaces, so it can receive data and produce data independently. A TCP socket is a typical example.
Follow-up: How do you implement one? Extend Duplex and implement _read() and _write(), or pass read and write callbacks to its constructor.
Use new Duplex(options). The options configure both stream sides, while read and write callbacks provide the operations that the stream invokes for reading and writing.
Follow-up: What should a subclass do before using inherited buffering? Call the Duplex constructor so its buffering configuration is initialized.
allowHalfOpen control?The readable and writable halves are independent by default because allowHalfOpen defaults to true. With allowHalfOpen: false, ending one side automatically ends the other side.
Follow-up: When would the default be useful? Protocols that intentionally keep one direction open can use half-open behavior; use false for coupled lifetimes.
stream.Readablestream.Writablestream.Transformstream.PassThroughstream.pipeline()