What is a Writable stream?
A Writable Stream is a Node.js stream meant for writing data in chunks to some destination resource, for example, a file, a network connection, an HTTP response, stdout, and so on.
If a Readable Stream is a data source, a Writable Stream is a data destination.
The core idea
A Writable Stream lets you pass data gradually, without holding all of the content in memory. This matters especially for:
- writing large files,
- sending streaming HTTP responses,
- transferring data over a network.
Examples of Writable Streams in Node.js
Several built-in Node.js objects already implement the Writable Stream interface:
| Example | Description |
|---|---|
fs.createWriteStream() | Writing to a file |
http.ServerResponse | The body of the server's HTTP response |
process.stdout | Standard output |
net.Socket | A TCP socket |
The main Writable Stream methods
| Method | Description |
|---|---|
.write(chunk) | Writes a chunk of data (a string or a Buffer) |
.end([chunk]) | Ends the stream, an optional final chunk can be passed |
.cork() / .uncork() | Buffers writes to improve performance |
.destroy([error]) | Aborts the stream with an error |
.pipe(destination) | Used on a Readable Stream to direct data into a Writable Stream |
An example: writing to a file
const fs = require('fs');
const stream = fs.createWriteStream('output.txt');
stream.write('First line\n');
stream.write('Second line\n');
stream.end('Final line\n'); // Closes the streamWritable Stream events
| Event | Description |
|---|---|
drain | The stream is ready for more data after the buffer filled up |
finish | The stream finished writing |
error | An error occurred while writing |
close | The stream is fully closed |
The backpressure mechanism
When Writable can't keep up processing incoming data, it pauses reading from Readable.
The .write() method itself signals this, it returns:
true, if the buffer isn't full;false, if the stream is overloaded.
An example with backpressure handling:
const fs = require('fs');
const readable = fs.createReadStream('input.txt');
const writable = fs.createWriteStream('output.txt');
readable.on('data', (chunk) => {
if (!writable.write(chunk)) {
readable.pause(); // pause reading
}
});
writable.on('drain', () => {
readable.resume(); // resume once the buffer frees up
});
readable.on('end', () => writable.end());Working via pipe()
Most often, a Writable Stream is used together with a Readable Stream:
const fs = require('fs');
const readable = fs.createReadStream('input.txt');
const writable = fs.createWriteStream('output.txt');
readable.pipe(writable);pipe() automatically manages backpressure and data flow, it's the recommended way to connect them.
Advantages of Writable Streams
- Asynchronous, step-by-step writing
- Minimal memory use
- Can be combined with Readable via
pipe() - Flow control (backpressure)
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.