v151 · DOM · Streaming HTML

Streaming HTML Writer

Pipe an HTML byte stream directly into the DOM via element.streamAppendHTML(), which returns a WritableStream. The browser's incremental parser renders each chunk as it arrives — no buffering, no innerHTML swaps.

Chrome 151 required. The streamAppendHTML() API ships in Chrome 151 (Dev channel). The demo below uses a polyfill fallback — indicated in the status bar — so you can explore the streaming concept in any browser.

live demo

Ready.

API comparison

The new API collapses two patterns into one clean call:

Before (manual buffering)

// Accumulate chunks until safe boundary let buf = ''; reader.read().then(function pump({done, value}) { if (done) { el.innerHTML += buf; return; } buf += decoder.decode(value); return reader.read().then(pump); });

After (Chrome 151+)

// Pipe directly into the DOM const writer = el.streamAppendHTML(); response.body.pipeTo(writer);

code

// Requires Chrome 151+
async function streamHTMLFeed(containerEl, htmlChunks) {
  if (typeof containerEl.streamAppendHTML === 'function') {
    // Native path: get a WritableStream from the element
    const writableStream = containerEl.streamAppendHTML();
    const writer = writableStream.getWriter();
    const enc = new TextEncoder();

    for (const chunk of htmlChunks) {
      await writer.write(enc.encode(chunk));
      await delay(400); // simulate network delay
    }
    await writer.close();
  } else {
    // Polyfill: append innerHTML chunk by chunk
    for (const chunk of htmlChunks) {
      containerEl.insertAdjacentHTML('beforeend', chunk);
      await delay(400);
    }
  }
}

const chunks = items.map(item => `
  <div class="stream-item">
    <h4>${item.title}</h4>
    <p>${item.body}</p>
  </div>
`);

streamHTMLFeed(document.getElementById('feed'), chunks);

see also

implementation reference

Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗