Skip to main content

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:

ExampleDescription
fs.createWriteStream()Writing to a file
http.ServerResponseThe body of the server's HTTP response
process.stdoutStandard output
net.SocketA TCP socket

The main Writable Stream methods

MethodDescription
.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

javascript
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 stream

Writable Stream events

EventDescription
drainThe stream is ready for more data after the buffer filled up
finishThe stream finished writing
errorAn error occurred while writing
closeThe 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:

javascript
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:

javascript
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 ready
Premium

A concise answer to help you respond confidently on this topic during an interview.