![Mason Freed](https://web.dev/images/authors/masonfreed.jpg) Mason Freed [X](https://twitter.com/Mfreed777) [GitHub](https://github.com/mfreed7) ![Dominik Röttsches](https://web.dev/images/authors/drott.jpg) Dominik Röttsches [GitHub](https://github.com/drott) [Mastodon](https://typo.social/@drott)

<br />


Published: October 29, 2025

<br />

Chrome intends to deprecate and remove XSLT from the browser. This document
details how you can migrate your code before the removal in late-2026.

Chromium has officially deprecated XSLT, including the
[XSLTProcessor](https://developer.mozilla.org/docs/Web/API/XSLTProcessor)
JavaScript API and the [XSLT processing
instruction](https://en.wikipedia.org/wiki/Processing_Instruction#:%7E:text=%3C%3Fxml%2Dstylesheet%20type%3D%22text/xsl%22).
We intend to remove support from version 158 (November 17, 2026). The
[Firefox](https://github.com/mozilla/standards-positions/issues/1287#issuecomment-3227145793)
and
[WebKit](https://github.com/whatwg/html/issues/11523#issuecomment-3149280766)
projects have also indicated plans to remove XSLT from their browser engines.
This document provides some history and context, explains how we are removing
XSLT to make Chrome safer, and provides a path for migrating before these
features are removed from the browser. For the latest updates, also see the
[Chrome Platform Status entry](https://chromestatus.com/feature/4709671889534976).

> [!NOTE]
> **Note:** To further improve security, we also plan to migrate XML parsing within Chrome from libxml2 to an XML parser written in Rust.

## What is being removed?

There are two APIs in the browser that implement XSLT, and both are being
removed:

- The [XSLTProcessor](https://developer.mozilla.org/docs/Web/API/XSLTProcessor) class (for example, `new XSLTProcessor()`).
- The [XSLT Processing
  Instruction](https://developer.mozilla.org/docs/Web/XML/XSLT/Guides/Transforming_XML_with_XSLT) (for example, `<?xml-stylesheet type="text/xsl" ... ?>`).

## Timeline For Chrome

Chrome has the following plan:

- Chrome 142 (Oct 28, 2025): Early warning console messages added to Chrome.
- Chrome 143 (Dec 2, 2025): Official deprecation of the API - deprecation warning messages begin to show in the console and in lighthouse.
- Chrome 145 (Dec 2, 2025 *Canary*): Canary, Dev, and Beta releases begin disabling XSLT by default, as an early-warning.
- Chrome 146 (Mar 10, 2026): [Enterprise Policy (EP)](https://chromeenterprise.google/policies/#XSLTEnabled) goes live for testing. This allows enterprises to both test disabling XSLT early, and also will let them continue using features past the removal date.
- Chrome 152 (Aug 25, 2026): [Origin
  Trial (OT)](https://developer.chrome.com/origintrials#/view_trial/1902207892610613249) goes live for testing. This allows sites to continue using features past the removal date.
- Chrome 154 (Sep 22, 2026): *Webview* Canary, Dev, and Beta releases begin disabling XSLT by default, as an early-warning.
- Chrome 158 (Nov 17, 2026): XSLT stops functioning on Stable releases, for all users other than Origin Trial and Enterprise Policy participants.
- Chrome 176 (Aug 17, 2027): Origin Trial and Enterprise Policy stop functioning. XSLT is disabled for all users.

## What is XSLT?

XSLT, or Extensible Stylesheet Language Transformations, is a language used to
transform XML documents, commonly into other formats such as HTML. It uses an
XSLT stylesheet file to define the rules for this conversion, and an XML file
containing the data used as input.

In browsers, when an XML file is received that links to an XSLT stylesheet, the
browser uses the rules in that stylesheet to rearrange, format, and convert the
raw XML data into a structured page (often HTML) that can be rendered for the
user.

For example, an XSLT stylesheet could take the following XML input:

```xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="demo.xsl" ?>
<page>
 <message>
  Hello World.
 </message>
</page>
```

and this XSL stylesheet:

```xslt
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html"/>
  <xsl:template match="/page/message">
    <body>
      <p>Message: <xsl:value-of select="."/></p>
    </body>
  </xsl:template>
</xsl:stylesheet>
```

and process them into this HTML for the browser to display: HTML

```html
<body>
  <p>Message: Hello World.</p>
</body>
```

In addition to the XSL processing instruction shown in the previous example,
there's also the
[XSLTProcessor](https://developer.mozilla.org/docs/Web/API/XSLTProcessor/XSLTProcessor)
JavaScript API which can be used to process local XML documents with local XSLT
stylesheets.

## History of XSLT

XSLT was recommended by the World Wide Web Consortium (W3C) on [November 16,
1999](https://www.w3.org/TR/xslt-10/), as a language for transforming XML
documents into other formats, most commonly HTML for display in web browsers.
Before the official 1.0 recommendation, Microsoft took an early initiative by
shipping a proprietary implementation based on a W3C working draft in [Internet
Explorer 5.0](https://en.wikipedia.org/wiki/Internet_Explorer_5), released in
March 1999. Following the official standard, Mozilla implemented native XSLT 1.0
support in [Netscape 6](https://www-archive.mozilla.org/status/2000-09-06) in
late 2000. Other major browsers, including Safari, Opera, and later Chrome, also
incorporated native XSLT 1.0 processors, making client-side XML-to-HTML
transformations a viable web technology in the early 2000s.

The XSLT language itself continued to evolve, with the release of [XSLT 2.0 in
2007](https://www.w3.org/TR/xslt20/) and [XSLT 3.0 in
2017](https://www.w3.org/TR/xslt-30/), which introduced powerful features like
regular expressions, improved data types, and the ability to process JSON.
Browser support, however, stagnated. Today, all major web browser engines only
provide native support for the original XSLT 1.0 from 1999. This lack of
advancement, coupled with the rise of the use of JSON as a wire format, and
JavaScript libraries and frameworks (like jQuery, React, and Vue.js) that offer
more flexible and powerful DOM manipulation and templating, has led to a
significant decline in the use of client-side XSLT. Its role within the web
browser has been largely superseded by these JavaScript-based technologies.

## Why does XSLT need to be removed?

The continued inclusion of XSLT 1.0 in web browsers presents a significant and
unnecessary security risk. The underlying libraries that process these
transformations, such as [libxslt](https://github.com/GNOME/libxslt) (used by
Chromium browsers), are complex, aging C/C++ codebases. This type of code is
notoriously susceptible to memory safety vulnerabilities like buffer overflows,
which can lead to arbitrary code execution. For example, security audits and bug
trackers have repeatedly identified high-severity vulnerabilities in these
parsers (e.g., [CVE-2025-7425](https://nvd.nist.gov/vuln/detail/CVE-2025-7425)
and [CVE-2022-22834](https://nvd.nist.gov/vuln/detail/CVE-2022-22834), both in
libxslt). Because client-side XSLT is now a niche, rarely-used feature, these
libraries receive far less maintenance and security scrutiny than core
JavaScript engines, yet they represent a direct, potent attack surface for
processing untrusted web content. Indeed, XSLT is the source of several recent
[high-profile security
exploits](https://www.offensivecon.org/speakers/2025/ivan-fratric.html) that
continue to put browser users at risk. The security risks of maintaining this
brittle, legacy functionality far outweighs its limited modern utility.

Furthermore, the original purpose of client-side XSLT---transforming data into
renderable HTML---has been superseded by safer, more ergonomic, and
better-maintained JavaScript APIs. Modern web development relies on things like
the Fetch API to retrieve data (typically JSON) and the DOMParser API to safely
parse XML or HTML strings into a DOM structure within the browser's secure
JavaScript sandbox. Frameworks like React, Vue, and Svelte then manage the
rendering of this data efficiently and securely. This modern toolchain is
actively developed, benefits from the massive security investment in JavaScript
engines, and is what virtually all web developers use today. Indeed, only about
[0.02%](https://chromestatus.com/metrics/feature/timeline/popularity/79) of web
page loads today actually use XSLT at all, with less than
[0.001%](https://chromestatus.com/metrics/feature/timeline/popularity/78) using
XSLT processing instructions.

This is not a Chrome or Chromium-only action: the other two major browser
engines also support the removal of XSLT from the web platform:
[WebKit](https://github.com/whatwg/html/issues/11523#issuecomment-3149280766),
[Gecko](https://github.com/whatwg/html/issues/11523#issuecomment-3149788558).

For these reasons, deprecating and removing XSLT reduce the browser's attack
surface for all users, simplify the web platform, and allow engineering
resources to be focused on securing the technologies that actually power the
modern web, with no practical loss of capability for developers.

## Improving XML parsing security

Similar to the severe security issues in libxslt, severe
[security](https://gitlab.gnome.org/GNOME/libxml2/-/issues/950)
[issues](https://project-zero.issues.chromium.org/issues/432450829) were
recently reported against libxml2 which is used in Chromium for parsing,
serialization and testing the well-formedness of XML. To address future security
issues with XML parsing In Chromium we plan to phase out the usage of libxml2
and replace XML parsing with a memory-safe XML parsing library written in Rust.
Importantly, we won't be removing XML from the browser; only XSLT is being
considered for removal here. We intend to ensure that replacing libxml2 is
entirely transparent to web developers.

## XML + CSS is not being removed

It is important to distinguish the deprecation of XSLT
(`<?xml-stylesheet type="text/xsl" ... ?>`) from the
`<?xml-stylesheet ... ?>` processing instruction itself, which remains supported
when used with CSS. You can still use the processing instruction with
`type="text/css"` to apply standard layout and design rules to your raw data,
just as you can with HTML. For example:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="styles.css"?>
<root>
  <item>Content here</item>
</root>
```

## How to migrate

There are a few alternative paths for migration.

### JSON

For sites that are fully built on XML and XSL there is no one-size-fits all way
to make the transition. Migration options include moving the XSLT processing
pipeline to the server side and sending down the rendered HTML to the client, or
migrating server-side XML API endpoints to
[JSON](https://en.wikipedia.org/wiki/JSON), and performing client-side rendering
using JavaScript to transform JSON into HTML DOM and CSS.

### Client-side XSLT in JavaScript

There are a few client-side (JavaScript-based) XSLT libraries available, but the
largest by far is produced by
[Saxonica](https://www.saxonica.com/welcome/welcome.xml) (view the
[comprehensive documentation for
Saxonica](https://www.saxonica.com/saxonjs/documentation3/index.html#!starting)).
The implementation goes well beyond the XSLT 1.0 implementation in web browsers,
implementing full support for the latest [v3.0
standard](https://www.w3.org/TR/xslt-30/), and eventually the [in-progress v4.0
standard](https://qt4cg.org/specifications/xslt-40/Overview.html).

### Polyfill

There is a polyfill that attempts to allow existing code, which depends on web
browsers' implementations of XSLT 1.0, to continue functioning, while not using
native XSLT features from the browser. The polyfill is [located on
GitHub](https://github.com/search?q=XSLT+polyfill&type=repositories).

The polyfill contains a functional WASM-based polyfilled replacement for the
XSLTProcessor class, so existing JavaScript code can continue to work as-is:

```html
<script src="xslt-polyfill.min.js"></script>

<script>
const xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(xsltDoc);
const fragment = xsltProcessor.transformToFragment(xmlDoc, document);
</script>
```

The polyfill also provides an automatic utility function for an easy way to
replace XML documents that use XSLT processing instructions:

For an original `demo.xml` file like this:

```xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="demo.xsl"?>
<ROOT>
...content...
```

One line can be added to invoke the polyfill and transform the document with the
referenced XSLT stylesheet:

```xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="demo.xsl"?>
<ROOT>
<script src="xslt-polyfill.min.js"
   xmlns="http://www.w3.org/1999/xhtml"></script>
...content...
```

In this case, the new `<script>` element loads the polyfill, which detects the
XML document type and the XSLT processing instruction and transparently loads
it, replacing the document.

## Extension

There's also a [Chrome
extension](https://chromewebstore.google.com/search/xslt%20polyfill) that can be
added to supported browsers, which will apply the same XSLT polyfill to all raw
XML pages that contain XSLT processing instructions or calls to XSLTProcessor.
This can be used for applications where the source XML or XSLT cannot be
changed, to maintain functionality.

In particular, when XSLT is disabled, Chrome now shows a warning banner that
links directly to an extension search page, to help users locate an extension:

![The message shown in Chrome when xslt is detected.](https://developer.chrome.com/static/docs/web-platform/deprecating-xslt/image/deprecation-message.png)

## Specific use cases

In the [discussion in HTML
standards](https://github.com/whatwg/html/issues/11523), several concrete use
cases were identified. This section talks specifically about each of them, to
recommend paths forward for developers publishing XML resources that use XSLT
today.

### RSS and Atom Feeds

In many existing RSS or Atom feeds, XSLT is used to make raw XML feeds
human-readable when viewed directly in a browser. The primary use case is that
when a user accidentally clicks on a site's RSS feed link, rather than pasting
that link into their RSS reader, they get a formatted HTML response that they
can read, rather than the raw XML itself.

There are two paths forward for this use case. The "standard" HTML way to do
this is to add `<link rel="alternate" type="application/rss+xml">` to an
(HTML-based) site, rather than adding an explicit (user-visible) `<a
href="something.xml">` that users might accidentally click. This solution allows
RSS readers to find the feed if a user pastes in just the website URL, but it
also allows human users to see the regular HTML content without getting confused
by a link to an XML resource. This also follows the normal web paradigm that
HTML is for humans and XML is for machines. Of course this doesn't solve the
case where a user just "has" an RSS link from somewhere, and they paste it into
their web browser (rather than their RSS reader).

When that solution isn't wanted, the polyfill offers another path. As mentioned
previously, the RSS/Atom XML feed can be augmented with one line, `<script
src="xslt-polyfill.min.js" xmlns="http://www.w3.org/1999/xhtml"></script>`,
which will maintain the existing behavior of XSLT-based transformation to HTML.
That shouldn't affect RSS reader's ability to continue parsing the XML, since
the `<script>` is a direct child of the root element.

### API output for embedded devices

Some commercial embedded devices measure or otherwise generate XML data for
consumption by users on the local network. Some of these devices do this by
generating a single XML data feed that uses XSLT to transform it into a
human-readable HTML format. That allows the API to be directly viewed in a
browser without needing additional code on the device or in the browser.  

Since this is a very application specific use case, the shape of the solution
might vary. For applications where the source code of the embedded device can be
updated, any of the options described previously (JSON, Polyfill) could work. In
particular, however, many such devices are difficult or impossible to update,
for various reasons. In that case, the
[extension](https://chromewebstore.google.com/detail/xslt-polyfill/hlahhpnhgficldhfioiafojgdhcppklm)
is likely the best option, since it allows client browsers to continue to read
the data in exactly the same way, without modifying the device.

### Lazy templating for web sites

Web developers sometimes use XSLT on the client side to apply presentation
markup to semantic markup, functioning as a lazy templating language that is
separate from the JavaScript ecosystem.

There are two solutions to this more general problem. For an existing site built
in this way, the easiest solution is likely just to add the polyfill to maintain
existing functionality. Or perhaps perform the XSLT transformation on the server
side, and serve the resulting HTML to the client, rather than the raw XML. The
more long-term solution for such properties would be to migrate to a more modern
JavaScript or JSON-based framework.

If you encounter a specific problem in Chrome related to this XSLT deprecation,
[report a bug here](https://issues.chromium.org/issues/new?component=1456730&template=2210866).

## How to detect usage of XSLT

Generally, deprecated features such as XSLT can be detected in your codebase in
a few ways. This section outlines two of them.

### The Reporting API

The [Reporting API](https://developer.mozilla.org/docs/Web/API/Reporting_API)
is a generic reporting mechanism for web applications to use report on various
platform features and conditions, including feature deprecations. To set it up
to report on the XSLT deprecation, a code snippet like this can be used:

```javascript
new ReportingObserver((reports, observer) => {
  reports.forEach((report) => {
    if (report.body.id === "XSLT") {
      // XSLT usage was detected - report it back here.
    }
  });
}, {types: ["deprecation"],buffered: true}).observe();
```

[See this code in action on CodePen](https://codepen.io/web-dot-dev/pen/ZYWgqXO).

### The enterprise Legacy Technology Report

For admins of an enterprise, the Legacy Technology Report can be used to
automatically collect deprecated feature usage and report them back in a user
friendly manner. See [this Google Support
article](https://support.google.com/chrome/a/answer/14250860) for more
information about how to enable this feature.