Archive for March, 2026

LINQ to XML for TypeScript: Why I Built It, and How Claude Helped

XML transformation in JavaScript has meant wrestling with DOMDocument. There is a better way — and it now exists for TypeScript.

I am pleased to announce LtXmlTs — a TypeScript implementation of LINQ to XML, available now on GitHub at github.com/EricWhiteDev/LtXmlTs under the MIT license.

Here is why I built it, and why it took the form it did.

The case for JavaScript Word add-ins

For anyone targeting macOS or Word Online, JavaScript add-ins are the only option. And unlike VSTO add-ins — which require cumbersome deployment cycles — a JavaScript add-in can be updated on the fly. For certain use cases, there is no other path.

Very often, the only way to implement real functionality in such an add-in is through direct manipulation of Open XML markup. Some developers sidestep this by farming the work out to a .NET or Python service. I think there are cleaner approaches — but they require doing XML transformation in TypeScript. And that means confronting the available tools.

The problem with DOMDocument

DOMDocument works. But revisiting it months later involves matching variable names scattered across the page and deducing intent from imperative steps. LINQ to XML is better because the structure of your code directly mirrors the XML you are producing — the nesting is the documentation. Recursive pure functional transformations are also the only clean way to implement certain classes of Open XML functionality, short of XSLT (which I dislike) or sprawling DOMDocument code.

CriterionDOMDocumentLINQ to XML
Code readabilityVariable names must be traced up and down the pageNesting hierarchy mirrors the XML being produced
Functional constructionImperative; mutable nodes built step by stepFunctional construction is declarative and easy to reason about
Recursive transformsDifficult to express cleanly; code sprawlsPure functional transformations are a first-class pattern
Long-term maintenanceIntent is buried; requires active reconstructionOriginal intent is clear and on the surface

A look at the difference

Consider a paragraph with formatted text — something that appears constantly in Open XML documents:

const paragraph = new XElement(W.p,
  new XElement(W.pPr,
    new XElement(W.pStyle,
      new XAttribute(W.val, "Heading1")
    )
  ),
  new XElement(W.r,
    new XElement(W.rPr,
      new XElement(W.b)
    ),
    new XElement(W.t,
      new XAttribute(XML.space, "preserve"),
      "Hello, Open XML"
    )
  )
);

The indentation is the documentation. No variable names to trace, no appendChild calls to sequence. The code is the structure.

Why I was the right person to build this

Years ago, as a Microsoft employee, I worked on the LINQ to XML team. I was required to know every detail of the library’s semantics — every edge case, every design decision. I later built a JavaScript implementation that shipped as part of the Open-Xml-Sdk-JavaScript and used it for years. But JavaScript is not TypeScript, and other TypeScript implementations I evaluated left me uncertain about their semantic fidelity. So I built my own.

How Claude Code made this possible

I used Claude Code throughout, but the process was not casual “vibing.” It was over one hundred targeted prompts — one class, one area of functionality at a time — with unit tests written and reviewed at each step. Intense, focused engineering using Claude as a powerful tool, not a magic wand.

Vibing? Not so much. Intense, focused engineering using Claude as a powerful tool — that is more accurate.

My knowledge of the LINQ to XML semantics was essential for verification. What Claude provided was velocity: implementations fleshed out rapidly, comprehensive test suites generated, iteration without writing every character by hand. The result was faster than manual development — and the code quality was higher.

The next phase is generating the Open XML manipulation code that uses this library. The engineering approach will be the same: precise, AI-assisted, and thoroughly reviewed. It has been a lot of fun.

There is documentation in the docs directory of the repo.

Comments

Looking for Contract Work or Full-Time Employee Work

Hi Friends,

After more than six years at Docugami, it is time to move on to the next adventure. I’m looking for either contract work, or work as a full-time employee. While I have lots of experience in many technologies, I would love to continue working in my main area of expertise, specifically Microsoft Office and Open XML.

Please connect with me on LinkedIn/ericwhitedev.

From my profile on LinkedIn:

.NET developer, technical writer, blogger. Open XML, Open XML SDK, JavaScript/TypeScript, Office client development, SharePoint 2010 development. Experience with many technologies, including ASP.NET, HTML, CSS, JavaScript, XML, XSLT, XSD, and document transformations.

Specialties: Open XML, C#, .NET, JavaScript/TypeScript, Office development, SharePoint development, technical writing

Over the many years, I’ve written books, magazine articles, blog posts, and recorded more than 200 screen-casts.

This blog Table-of-Contents contains links to much of what I’ve written and recorded over the years: https://www.ericwhite.com/blog/toc-expanded
Videos: https://www.youtube.com/user/OpenXML/videos

http://blogs.msdn.com/ericwhite
http://ericwhite.com/blog

Looking forward to connecting.

Eric

Comments