Open a .xml file in your browser and you usually get one of three things: a wall of unindented text, a viewer that freezes the tab on anything big, or — when the XML is actually broken — a blank page that won't tell you why.
So I went looking for a good XML viewer extension. The most-installed ones on the stores are stuck around 2 stars and haven't been updated since 2023. The reviews rhyme: "doesn't work", "freezes", "just shows plain text". I built Xwift to do the three things those don't.
What it does
- Tree view — collapsible, syntax-highlighted elements, attributes, text, CDATA, comments and processing instructions. Expand/collapse all.
- Source view — pretty-print (2 / 4 / tab) or minify, with line numbers and one-click copy.
-
Tells you where it's broken — a tolerant parser that keeps going on malformed input and lists every well-formedness problem with its
line:column: mismatched and unclosed tags, duplicate attributes, unbound namespace prefixes, an unescaped&, a stray]]>… click an error to jump to it. - Doesn't choke on big files — parsing runs in a Web Worker, so the tab stays responsive where "load it all into the DOM" viewers stall.
The interesting part (for fellow devs)
The whole thing is hand-written with zero dependencies — no DOMParser, no library. That was the point. The parser is a tolerant single-pass scanner that builds a best-effort tree and collects precise errors, and the formatter re-emits significant whitespace verbatim, so mixed content and xml:space="preserve" survive a round-trip.
Before shipping I ran an adversarial audit over the core, and it surfaced 15 real bugs I would never have caught by eye. A few favorites:
- Namespace scopes were plain objects, so an unbound prefix literally named
toStringor__proto__resolved up the prototype chain and got treated as bound. Fixed withMap-based scopes. - The serializer was recursive, so a deeply-nested-but-valid document overflowed the call stack even though the iterative parser handled it fine. Rewrote it as an explicit-stack walk.
- A
[hidden]attribute was silently overridden by adisplay:flexCSS rule — the empty drop-zone covered the whole viewer. My first E2E missed it because it asserted element content, not visibility.
Then it's verified in real Chrome and real Firefox — the parser produces byte-identical output under V8 and SpiderMonkey.
Respectful by default
- Zero data collection. Everything runs locally — no network requests with your content, no account, no telemetry. Files you open never leave your browser.
-
Minimal permissions. No host permissions, no
<all_urls>, no tab snooping. It reads a page only the moment you ask it to.
Get it
- Source (MIT, audit the parser): https://github.com/jjdoor/xwift
- Chrome / Edge / Firefox: rolling out as each store finishes review.
What's the worst XML-viewing moment you've had — the freeze, the blank page, or the "valid" XML that very much wasn't?
Top comments (0)