v153 · html · dom · streaming
Renewed HTML insertion & streaming methods
Chrome 153 adds a coherent set of HTML-string insertion methods to Element — positional variants of before, after, append, prepend, and replaceWith that accept raw HTML strings — plus a streamAppendHTML() method for incremental streaming insertion without blocking the main thread (its input/return contract is unsettled — see the syntax section).
at a glance
| Shipped in | Chrome 153 (status tracking; see ship status note below) |
|---|---|
| Status | In developer trial / proposed (milestone 157 in ChromeStatus) |
| Explainer | WICG/declarative-partial-updates — dynamic markup explainer |
| Repository | WICG/declarative-partial-updates |
| Standards position (Firefox) | Positive (mozilla/standards-positions #1370) |
| Standards position (Safari) | Active discussion (WebKit/standards-positions #629) |
| Discussion issues | WHATWG HTML #2142 · WHATWG HTML #10122 · Trusted Types #594 |
| Implementation bug | Chromium Issue 491743369 |
| ChromeStatus | 5054329641893888 — Renewed HTML insertion & streaming methods |
why it exists
The existing insertAdjacentHTML() method works but is verbose, positional-string-based, and has no streaming counterpart. The innerHTML setter destroys and recreates the full subtree, breaking references and event listeners. Server-side rendering and MPA frameworks that stream HTML fragments (out-of-order streaming, HTMX-style patterns) need a way to append HTML from a fetch() ReadableStream chunk-by-chunk, exactly as the network delivers it, without accumulating the whole string first.
The new methods provide: clean positional shortcuts that replace insertAdjacentHTML, and streamAppendHTML() which feeds stream chunks to the HTML parser incrementally, yielding control back to the event loop between chunks.
Syntax and methods
// WebIDL surface from the WICG dynamic-markup-revamped explainer:
partial interface Element {
void beforeHTML(DOMString html, optional SetHTMLOptions options);
void afterHTML(DOMString html, optional SetHTMLOptions options);
void prependHTML(DOMString html, optional SetHTMLOptions options);
void appendHTML(DOMString html, optional SetHTMLOptions options);
void replaceWithHTML(DOMString html, optional SetHTMLOptions options);
// Streaming input/return contract unsettled: the explainer WebIDL returns a
// WritableStream you write chunks into; the earlier WHATWG discussion (issue
// #2142) centered on piping a ReadableStream input instead.
WritableStream streamAppendHTML(SetHTMLOptions options); // explainer shape
};
The renewed HTML insertion suite adds ergonomic string-based positional methods alongside incremental streaming insertion on DOM elements:
| Method | Target location | Legacy equivalent |
|---|---|---|
element.beforeHTML(html) | Immediately before element | insertAdjacentHTML("beforebegin", html) |
element.afterHTML(html) | Immediately after element | insertAdjacentHTML("afterend", html) |
element.prependHTML(html) | As the first child of element | insertAdjacentHTML("afterbegin", html) |
element.appendHTML(html) | As the last child of element | insertAdjacentHTML("beforeend", html) |
element.replaceWithHTML(html) | Replaces element with parsed nodes | outerHTML = html |
Streaming insertion method:
| Method | Parameter | Return contract (unsettled) |
|---|---|---|
element.streamAppendHTML(...) |
Stream or options bag | Unsettled: The WICG explainer WebIDL specifies returning a WritableStream to pipe data into, whereas the earlier WHATWG discussion (issue #2142) centered on piping a ReadableStream of decoded chunks into the insertion point. Applications must treat this return contract as unsettled until the specification reaches consensus. |
Inputs and outputs
Inputs: The positional methods (beforeHTML, afterHTML, prependHTML, appendHTML, replaceWithHTML) take a mandatory html string (or TrustedHTML under Trusted Types enforcement) and an optional SetHTMLOptions dictionary containing sanitizer configurations. For streamAppendHTML, input parameter conventions remain unsettled between a stream source and an options bag.
Outputs: Positional methods return undefined (WebIDL void) synchronously. For streamAppendHTML, the input/return contract remains explicitly unsettled: the explainer WebIDL defines returning a WritableStream you write chunks into, while the earlier WHATWG discussion (issue #2142) centered on a ReadableStream input. Authors must avoid asserting either return shape.
Errors and lifecycle
Errors: The explainer does not define novel exception classes for the positional methods (beforeHTML, afterHTML, prependHTML, appendHTML, replaceWithHTML, and streamAppendHTML). As with insertAdjacentHTML and innerHTML, passing malformed HTML does not throw a parsing error; the HTML parser invokes resilient error-recovery steps to construct a DOM tree. The explainer does not yet define which exceptions, if any, apply to the new methods (its WICG template question on error raising is open): whether parent-requiring methods reject detached elements, and how stream aborts surface, are open questions — verify against your build rather than assuming insertAdjacentHTML semantics carry over.
Lifecycle: Markup injected synchronously undergoes immediate DOM insertion and tree mutation events. For streaming insertion, parsed nodes are appended incrementally as chunks arrive from the stream, yielding execution to the browser between chunks to preserve user responsiveness.
Source: WICG explainer; Chromium Issue 491743369.Examples
The following examples exercise the positional insertion methods; the streaming insertion appears only as a non-runnable contract note while its input/return contract is unsettled:
// 1. Positional HTML insertions (replaces insertAdjacentHTML)
const list = document.querySelector('#results');
list.appendHTML('<li>Appended item</li>');
list.prependHTML('<li class="pinned">Pinned top item</li>');
const target = document.querySelector('#current-card');
target.beforeHTML('<div class="notice">Before notice</div>');
target.afterHTML('<div class="notice">After notice</div>');
target.replaceWithHTML('<div id="current-card" class="updated">New card content</div>');
// 2. Streaming insertion (streamAppendHTML) is deliberately not shown as runnable code:
// the explainer WebIDL returns a WritableStream you write HTML chunks into, while the
// earlier WHATWG discussion (issue #2142) centered on piping a ReadableStream of decoded
// chunks into the insertion point. The input/return contract is unsettled (see the syntax
// table); do not code against either shape until the specification settles.
Source: WICG explainer — Resulting API.
browser compatibility
The page previously listed this feature as shipped enabled by default in Chrome 153. However, when queried on 2026-10-07, the authoritative ChromeStatus API record (feature 5054329641893888) reports is_released: false with status "Proposed" and desktop target milestone 157. Developers should verify availability behind experimental flags (chrome://flags/#enable-experimental-web-platform-features) in target builds.
| Engine / Browser | Status | Evidence & Notes |
|---|---|---|
| Chrome (Chromium) | Proposed / Target 157 | ChromeStatus 5054329641893888; Issue 491743369 |
| Firefox (Gecko) | Positive signal | Mozilla standards-positions #1370 |
| Safari (WebKit) | No formal signal | WebKit standards-positions #629 |
security and privacy
- Script execution: Classic positional HTML insertion methods follow the same security model as
innerHTML: inline<script>elements inserted via these methods do not execute. The unsafe/trusted options dictionary may permit opt-in script execution viarunScripts: truewhen explicitly supported. - Sanitization & Trusted Types: The proposal is designed to integrate natively with the Sanitizer API and allows Trusted Types policies to transform parser options rather than requiring synchronous string transforms.
- Streaming parser safety: Streaming HTML parsing prevents large payload buffering, mitigating memory exhaustion denial-of-service risks on constrained devices.