v151 · fetch · streams
textStream() for response/request/blob
textStream() reads a byte-stream body — a Response, a Request, or a Blob — as a ReadableStream of decoded strings, always UTF-8. It is exactly equivalent to piping the body through a TextDecoderStream yourself, minus the footgun of forgetting to.
at a glance
| Milestone listing | Chrome 151 — Enabled by default |
|---|---|
| Feature detail | Desktop 151, Android 151; status text “Proposed” (updated 2026-06-22); ship stage (intent 5) desktop_first 151 |
| Surface | Method on the Body mixin (Request, Response) and on Blob |
| Runtime feature | TextStreamMethod — status stable at trunk (crbug.com/514448226) |
| Standards body | WHATWG Fetch (Body mixin) and W3C FileAPI (Blob) |
| ChromeStatus | 5146752165478400 — textStream() for response/request/blob |
Member reference
The feature adds exactly one method on three interfaces (the Body mixin covers Request and Response; Blob is defined separately in FileAPI). Each member has a stable detailed reference page covering syntax, inputs, outputs, errors, context, lifecycle, examples, compatibility, and security/privacy:
Response.textStream()— read a response body as a stream of UTF-8 strings (single-use for non-null bodies;TypeErrorwhen unusable)Request.textStream()— read an upload payload as a stream of UTF-8 strings (consumes a non-null request body)Blob.textStream()— read a blob or file as a stream of UTF-8 strings (repeatable; each call creates a fresh stream)
Syntax
Defined on the Body interface mixin in the Fetch Standard, and separately on Blob in FileAPI:
// WHATWG Fetch — Body mixin (normative IDL)
ReadableStream textStream();
// W3C FileAPI — Blob (normative IDL)
ReadableStream textStream();
Chromium's bindings gate both behind the same runtime feature, marked stable:
// third_party/blink/renderer/core/fetch/body.idl
[RuntimeEnabled=TextStreamMethod, CallWith=ScriptState, RaisesException]
ReadableStream textStream();
// third_party/blink/renderer/core/fileapi/blob.idl
[RuntimeEnabled=TextStreamMethod, CallWith=ScriptState, NewObject, RaisesException]
ReadableStream textStream();
Source: Fetch Standard — Body mixin; FileAPI — Blob.textStream(); Chromium body.idl; Chromium blob.idl
| Parameters | None. |
|---|---|
| Return value | A ReadableStream whose chunks are strings — the body's bytes decoded as UTF-8. |
| Exceptions | TypeError if the object is unusable (its body is non-null and already disturbed or locked) — Fetch Standard method steps, mirrored by the RaisesException binding. |
| Null body | If the body is null, returns a new, already-closed empty ReadableStream (no exception). |
| Encoding | Always UTF-8 — the decoder is set up “regardless of the presence or the value of a Content-Type header and regardless of the presence or the value of a charset parameter” (Fetch). FileAPI notes this differs from readAsText(), which accepts an encoding label — textStream() has no encoding option. |
| Side effect | For a non-null body, reading begins immediately: bodyUsed becomes true as soon as textStream() is called, and the object becomes single-use. For a null body, bodyUsed stays false and repeated calls each return a new, independently closed empty stream (WPT null-body tests). Blob has no bodyUsed at all — every call returns a fresh stream. |
Local runtime check (headless Chrome 154.0.8037.97, 2026-10-08): Response, Request, and Blob each returned string chunks for "hello 世界". For non-null response/request bodies, bodyUsed was true immediately after textStream(); a second call threw TypeError, as did calling it while the original body stream was locked. Null response/request bodies each returned distinct closed streams (done: true) on repeat calls without setting bodyUsed. Two empty Blob calls likewise returned distinct closed streams. These observations match the cited specification and WPT contracts, not every possible error or deployment environment.
Examples
// Read a fetch() response as a stream of decoded text chunks.
const response = await fetch("/large-log.txt");
const reader = response.textStream().getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
console.log("chunk:", value); // value is a string, decoded as UTF-8
}
// Same contract on a Blob (e.g. a File from an <input type="file">):
const stream = file.textStream();
// ...and on a Request body before it is sent.
Source: whatwg/fetch PR #1862; WPT textstream.any.js (reader-loop shape)
Browser compatibility
Per browser-compat-data (checked 2026-07-26): the entry exists for all three interfaces — api/Response.json, api/Request.json, and api/Blob.json.
| Engine / runtime | Support | Notes |
|---|---|---|
| Chrome | 151 | All three interfaces (Response, Request, Blob) per BCD; matches the Chrome 151 milestone listing (Enabled by default); Chrome for Android and WebView (Android + iOS) are BCD mirrors |
| Edge | mirror | BCD mirrors Chrome's data |
| Firefox | Not supported | BCD version_added: false (Firefox for Android mirrors); vendor signal recorded on the ChromeStatus entry: No signal |
| Safari | Not supported | BCD version_added: false (Safari on iOS mirrors); the ChromeStatus entry records a Positive signal — a recorded signal, not an official WebKit standards position (a feature this small has none) |
| Node.js | 26.5.0 | BCD records version_added: 26.5.0 for all three interfaces |
| Deno | Unknown | No BCD entry as of 2026-07-26 |
Support rows are from BCD only. Separately, vendor signals come from the ChromeStatus API feature record (checked 2026-07-26): Firefox “No signal”, Safari “Positive”, web developers “No signals”. No Baseline entry: the webstatus.dev query returns no feature (checked 2026-07-26).
Source: BCD api/Response.json; BCD api/Request.json; BCD api/Blob.json; chromestatus.com/feature/5146752165478400Specifications
| Specification | Status |
|---|---|
| WHATWG Fetch — Body mixin: textStream() | Living Standard (normative); landed via whatwg/fetch PR #1862 (merged) |
| W3C FileAPI — Blob.textStream() | Working Draft (normative) |
See also
- whatwg/fetch PR #1862 — “Add a textStream() method to the Body mixin” (merged 2026-06-05; the feature's explainer, proposal, and spec change in one)
- WPT — fetch/api/body/textstream.any.js and WPT — FileAPI/blob/Blob-textStream.any.js
- crbug.com/514448226 — implementation tracking; Chromium runtime_enabled_features.json5 (
TextStreamMethod, stable) - Chromium body.idl; Chromium blob.idl
- MDN now has substantive Response.textStream(), Request.textStream(), and Blob.textStream() member pages (Specifications and Browser compatibility sections present, checked 2026-10-08). See also TextDecoderStream, the adjacent API this method is shorthand for.
- Chrome Platform Showcase — textStream() for response/request/blob (also: response pipeline, feature detect)