← Chrome 151 reference

v151 · shipped · dom · svg · security

XML Parsing in Rust for non-XSLT scenarios

Chrome 151 enables by default the memory-safe Rust-based XML parser that replaces the C-based libxml2 parser for all non-XSLT XML parsing in Blink — including DOMParser, XMLHttpRequest.responseXML, SVG documents, and XHTML.

Behaviour change The Rust parser aims for full spec compliance, which may differ in edge cases from libxml2's behaviour. Code that relied on libxml2-specific quirks in malformed XML handling may see different output. Well-formed XML is unaffected.

at a glance

Shipped inChrome 151 (Enabled by default, all platforms — after a stepped rollout that began at 1% in Chrome 147)
StatusEnabled by default (stepped rollout)
Finch featureXMLRustForNonXslt
Affected APIsDOMParser, XMLHttpRequest.responseXML, SVG documents, XHTML
Not affectedXSLT processing (separate deprecation track, removal planned Chrome 158)
Blink componentBlink>DOM, Blink>SVG
ChromeStatus5309598397497344 — XML Parsing in Rust for non-XSLT scenarios (API record)
Source: blink-dev Intent to Ship — XML Parsing in Rust for non-XSLT scenarios, February 2026

why it exists

Blink has historically relied on libxml2, a C library, for XML parsing. libxml2 has accumulated a long history of memory-safety vulnerabilities — use-after-free bugs, buffer overflows, heap corruption — that are fundamentally difficult to prevent in C. In addition, libxml2 experienced periods of slow security-disclosure response.

Replacing the parser with a Rust implementation eliminates this entire class of memory-safety vulnerability by construction. XSLT scenarios are excluded from the initial rollout because libxml2 and libxslt are tightly entangled; the Rust parser cannot yet be applied there without also replacing the XSLT engine (which is on a separate deprecation track).

The rollout began at 1% of Chrome 147 stable users and reached enabled-by-default in Chrome 151 (chromestatus milestone listing). During the rollout, Chromium engineers monitored a real-world parsing performance histogram (Blink.XMLParsing.NonXsltXmlParsingTime.Combined) before expanding. A ~50% throughput regression was observed on a 3 MB heavy-XML microbenchmark, so the team gathered production data to validate real-world impact was acceptable.

Milestone divergence note: While this page documents the Chrome 151 rollout wave where the XMLRustForNonXslt Finch feature reached general availability across platforms (attributed to the chromestatus milestone listing cited above), the ChromeStatus API record (5309598397497344) lists Chrome 153 for its desktop, Android, and WebView milestones (with Intent to Ship thread in February 2026). Both entries refer to the identical Rust XML parser transition tracked under Chromium issue 466303347.

Source: blink-dev Intent to Ship; Chromium issue 466303347

Syntax

The parser replacement operates entirely under the hood. Existing web developer APIs that parse XML conform to the W3C XML specification and use unchanged JavaScript signatures:

// DOMParser parsing XML document:
const parser = new DOMParser();
const doc = parser.parseFromString(xmlString, "text/xml");

// XMLHttpRequest responseXML property:
const xhr = new XMLHttpRequest();
xhr.open("GET", "/data.xml");
xhr.onload = () => {
  const xml = xhr.responseXML;
};
xhr.send();
Source: MDN DOMParser.parseFromString; MDN XMLHttpRequest.responseXML

what changes

This is a transparent implementation swap — the web-facing APIs are unchanged. All of the following continue to work identically for well-formed XML:

API / scenarioUses Rust parser in Chrome 151+
DOMParser.parseFromString(str, 'text/xml')Yes
DOMParser.parseFromString(str, 'application/xhtml+xml')Yes
XMLHttpRequest.responseXMLYes
Top-level SVG navigation (.svg file in address bar)Yes
SVG external image (<img src="...svg">)Yes
XHTML documentsYes
XSLT processingNo — still uses libxml2/libxslt
Source: blink-dev Intent to Ship

Inputs and parameters

The parser consumes character streams or byte sequences of XML markup passed via DOMParser.parseFromString(), HTTP responses received via XMLHttpRequest, or SVG and XHTML document resources fetched during network navigation. Input encoding detection follows standard XML declaration rules.

Source: W3C XML §well-formed

Outputs and return values

Successful parsing returns an active DOM Document or XMLDocument instance containing the parsed element hierarchy. When parsing malformed input via DOMParser, the returned document contains a <parsererror> element detailing the syntax error rather than raising an uncaught exception.

Source: MDN DOMParser reference

Errors and exceptions

In accordance with XML standards, fatal parsing errors in documents produce error pages or <parsererror> elements in DOMParser. The Rust parser enforces stricter conformity with the XML standard, eliminating non-standard error recovery quirks previously present in libxml2.

Source: W3C XML specification

Execution context and exposure

The Rust XML parser replaces Blink's non-XSLT XML parsing paths and is enabled across all desktop and mobile platforms. Note the exposure of the affected APIs differs: DOMParser is a Window-only API (not exposed in dedicated, shared, or service workers), while XMLHttpRequest.responseXML is available wherever XMLHttpRequest is; worker contexts that need XML parsing use those respective surfaces, not DOMParser.

Source: ChromeStatus feature 5309598397497344

Lifecycle and state transitions

The XML parser engine processes input synchronously for DOMParser.parseFromString() and incrementally as chunks arrive over the network for top-level navigation, SVG rendering, and XMLHttpRequest. Document readiness states transition from loading to interactive and complete upon parse completion.

Source: MDN DOMParser

Examples

// API shape is identical — only the underlying parser changes
const parser = new DOMParser();
const doc = parser.parseFromString(
  '<root><item id="1">Hello</item></root>',
  'text/xml'
);
console.log(doc.querySelector('item').textContent); // "Hello"

// Malformed XML still produces a parsererror document
const bad = parser.parseFromString('<unclosed', 'text/xml');
console.log(bad.querySelector('parsererror')); // HTMLElement
Source: blink-dev Intent to Ship

Browser compatibility

BrowserXML parser
Chrome 151+ (all platforms)Rust parser for non-XSLT (enabled by default; stepped rollout began at 1% in M147)
FirefoxOwn XML parser (Expat-based)
SafariOwn XML parser (libxml2-based historically)
Source: chromestatus.com feature page; blink-dev thread, February 2026

Security and privacy considerations

Replacing libxml2 with a memory-safe Rust parser directly mitigates the primary historical attack surface in XML handling, including buffer overflows, memory out-of-bounds reads/writes, and use-after-free bugs. It enforces strict memory safety guarantees at compile time while maintaining existing web origin boundary protections.

Source: Chromium issue 466303347

see also