This page documents Deno's implementation of the Web Streams API standard, which provides interfaces for creating, composing, and consuming streams of data. Streams enable efficient handling of large data sets by processing data incrementally rather than loading everything into memory.
For information about HTTP-specific streaming (fetch requests/responses), see HTTP, Fetch, and WebSocket. For file-based streaming operations, see File System Operations.
The Streams API implementation in Deno provides three primary stream types aligned with the WHATWG Streams Standard:
Deno extends the standard with resource-backed streams that bridge JavaScript streams to Rust resources (file handles, network sockets, etc.) for efficient I/O operations.
Sources: ext/web/06_streams.js1-6564
Diagram: Streams API Component Architecture
The architecture separates concerns into distinct layers:
ReadableStream, WritableStream, TransformStream).Sources: ext/web/06_streams.js3747-6564 ext/web/06_streams.js896-1212
The ReadableStream class provides methods for reading data incrementally. Key internal symbols:
[_controller] - References the underlying controller ext/web/06_streams.js347[_reader] - References the currently locked reader (if any) ext/web/06_streams.js358[_state] - Stream state: "readable", "closed", or "errored" ext/web/06_streams.js361[_disturbed] - Tracks whether the stream has been consumed ext/web/06_streams.js348[_storedError] - Stores error if stream errored ext/web/06_streams.js362ext/web/06_streams.js3747-4110
Diagram: ReadableStream Reader Access Patterns
Sources: ext/web/06_streams.js4112-4590
Manages streams with arbitrary chunk values:
Key methods:
enqueue(chunk) - Add chunk to internal queue ext/web/06_streams.js4645close() - Signal no more data ext/web/06_streams.js4630error(e) - Error the stream ext/web/06_streams.js4660ext/web/06_streams.js4593-4896
Optimized for byte streams with BYOB reader support:
This controller enables efficient zero-copy reading by allowing the underlying source to write directly into buffers provided by readers.
ext/web/06_streams.js4899-5382
Sources: ext/web/06_streams.js4593-5382
The WritableStream class represents a destination for writing data:
[_state] - One of: "writable", "closed", "erroring", "errored" ext/web/06_streams.js361[_writer] - Currently locked writer (if any) ext/web/06_streams.js364[_controller] - WritableStreamDefaultController instance ext/web/06_streams.js347[_backpressure] - Boolean indicating if writes should slow down ext/web/06_streams.js344[_writeRequests] - Queue of pending write promises ext/web/06_streams.js365ext/web/06_streams.js5385-5635
Diagram: WritableStream Backpressure Mechanism
The ready promise on WritableStreamDefaultWriter provides backpressure signaling. It remains pending when the stream's queue exceeds the high water mark and resolves when space is available ext/web/06_streams.js5710
Sources: ext/web/06_streams.js5638-5856 ext/web/06_streams.js5859-6172
Diagram: TransformStream Data Pipeline
A TransformStream consists of:
ext/web/06_streams.js6175-6564
When creating a TransformStream, you provide a transformer object:
The TransformStreamDefaultController provides methods:
enqueue(chunk) - Send transformed chunk to readable side ext/web/06_streams.js6400terminate() - Close both sides ext/web/06_streams.js6418error(reason) - Error both sides ext/web/06_streams.js6410ext/web/06_streams.js6361-6564
Sources: ext/web/06_streams.js6175-6564
Deno extends the standard Streams API with resource-backed implementations for efficient I/O with native resources.
Diagram: Resource-Backed Stream Integration
Sources: ext/web/06_streams.js896-1212 ext/web/06_streams.js19-29
Creates a ReadableStream backed by a Deno resource:
rid - Resource ID from Deno's resource table.autoClose - Whether to close the resource when stream closes.readAll() operations ext/web/06_streams.js965The underlying source uses core.read() to pull data from the resource into provided buffers.
Creates a WritableStream backed by a Deno resource:
The underlying sink uses core.writeAll() to write chunks to the resource ext/web/06_streams.js1186
ext/web/06_streams.js1173-1212
Converts a ReadableStream into a Deno resource:
This enables passing JavaScript streams to Rust ops that expect resource IDs. The implementation:
op_readable_stream_resource_allocate ext/web/06_streams.js904Sources: ext/web/06_streams.js896-926 ext/web/06_streams.js946-1006 ext/web/06_streams.js1173-1212
Resource-backed streams include optimizations for common patterns:
When collecting a stream's entire contents into memory:
op_read_all() for single operation ext/web/06_streams.js1109ext/web/06_streams.js1095-1160
Sources: ext/web/06_streams.js1095-1160
Streams are central to the Fetch API implementation for handling request and response bodies.
The InnerBody class in the fetch implementation manages the body's stream state:
This abstraction allows bodies to be static (Uint8Array/string) or streaming (ReadableStream).
Sources: ext/fetch/22_body.js89-255
Streams maintain internal queues to buffer chunks:
Operations:
enqueueValueWithSize(container, value, size) - Add item to queue ext/web/06_streams.js505-541dequeueValue(container) - Remove and return item from queue ext/web/06_streams.js543-560Two built-in strategies control buffering:
ByteLengthQueuingStrategy - Buffers based on byte length ext/web/06_streams.js3603-3639CountQueuingStrategy - Buffers based on chunk count ext/web/06_streams.js3642-3676ext/web/06_streams.js3603-3676
Sources: ext/web/06_streams.js505-560 ext/web/06_streams.js3603-3676
The readableStreamTee() function creates two independent branches from a single stream ext/web/06_streams.js2715 Chunks are cloned for the second branch if requested ext/web/06_streams.js2718
ext/web/06_streams.js2715-2946
The pipeTo() method connects a readable stream to a writable stream ext/web/06_streams.js3901 It handles chunk transfer with backpressure and cleanup.
ext/web/06_streams.js3901-4110
Sources: ext/web/06_streams.js2715-2946 ext/web/06_streams.js3901-4110
The implementation uses symbols for private state mapping to specification internal slots:
Resource-backed streams use SafeFinalizationRegistry to clean up resources if streams are garbage collected:
Sources: ext/web/06_streams.js343-394 ext/web/06_streams.js931-933
Refresh this wiki