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.
at a glance
| Shipped in | Chrome 151 (Enabled by default, all platforms — after a stepped rollout that began at 1% in Chrome 147) |
|---|---|
| Status | Enabled by default (stepped rollout) |
| Finch feature | XMLRustForNonXslt |
| Affected APIs | DOMParser, XMLHttpRequest.responseXML, SVG documents, XHTML |
| Not affected | XSLT processing (separate deprecation track, removal planned Chrome 158) |
| Blink component | Blink>DOM, Blink>SVG |
| ChromeStatus | 5309598397497344 — XML Parsing in Rust for non-XSLT scenarios (API record) |
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.
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 / scenario | Uses Rust parser in Chrome 151+ |
|---|---|
DOMParser.parseFromString(str, 'text/xml') | Yes |
DOMParser.parseFromString(str, 'application/xhtml+xml') | Yes |
XMLHttpRequest.responseXML | Yes |
Top-level SVG navigation (.svg file in address bar) | Yes |
SVG external image (<img src="...svg">) | Yes |
| XHTML documents | Yes |
| XSLT processing | No — still uses libxml2/libxslt |
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.
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.
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.
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.
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.
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
| Browser | XML parser |
|---|---|
| Chrome 151+ (all platforms) | Rust parser for non-XSLT (enabled by default; stepped rollout began at 1% in M147) |
| Firefox | Own XML parser (Expat-based) |
| Safari | Own XML parser (libxml2-based historically) |
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 466303347see also
- MDN: DOMParser
- MDN: DOMParser.parseFromString
- MDN: XMLHttpRequest.responseXML
- chromestatus — XML Parsing in Rust for non-XSLT scenarios (5309598397497344)
- ChromeStatus API record (5309598397497344)
- blink-dev Intent to Ship — XML Parsing in Rust for non-XSLT scenarios
- Chromium Issue 466303347 — XML parsing in Rust for non-XSLT scenarios
- W3C Extensible Markup Language (XML) 1.0 specification
- W3C XML §4.3.2 Well-Formed Parsed Entities
- Removing XSLT for a more secure browser (Chrome Developers)
- GNOME libxml2 repository