← Chrome 153 reference

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 inChrome 153 (status tracking; see ship status note below)
StatusIn developer trial / proposed (milestone 157 in ChromeStatus)
ExplainerWICG/declarative-partial-updates — dynamic markup explainer
RepositoryWICG/declarative-partial-updates
Standards position (Firefox)Positive (mozilla/standards-positions #1370)
Standards position (Safari)Active discussion (WebKit/standards-positions #629)
Discussion issuesWHATWG HTML #2142 · WHATWG HTML #10122 · Trusted Types #594
Implementation bugChromium Issue 491743369
ChromeStatus5054329641893888 — Renewed HTML insertion & streaming methods
Source: chromestatus.com/feature/5054329641893888; ChromeStatus API record 5054329641893888.

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.

Source: WICG explainer; Sanitizer API.

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:

MethodTarget locationLegacy equivalent
element.beforeHTML(html)Immediately before elementinsertAdjacentHTML("beforebegin", html)
element.afterHTML(html)Immediately after elementinsertAdjacentHTML("afterend", html)
element.prependHTML(html)As the first child of elementinsertAdjacentHTML("afterbegin", html)
element.appendHTML(html)As the last child of elementinsertAdjacentHTML("beforeend", html)
element.replaceWithHTML(html)Replaces element with parsed nodesouterHTML = html

Streaming insertion method:

MethodParameterReturn 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.
Source: WICG explainer — Resulting API; WHATWG HTML issue #2142.

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.

Source: WICG explainer — Resulting API; WHATWG HTML issue #10122.

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 / BrowserStatusEvidence & Notes
Chrome (Chromium)Proposed / Target 157ChromeStatus 5054329641893888; Issue 491743369
Firefox (Gecko)Positive signalMozilla standards-positions #1370
Safari (WebKit)No formal signalWebKit standards-positions #629
Source: ChromeStatus API record 5054329641893888; Mozilla standards-positions #1370; WebKit standards-positions #629.

security and privacy

Source: WICG explainer; Sanitizer API; Trusted Types issue #594.

see also