FormatterHQ

XML to TypeScript Interface Generator

Generate TypeScript interfaces from an XML sample, such as an Atom or RSS feed. Attributes and child elements become typed properties.

Input XML
Output TYPESCRIPT
Ready.

How to use the XML to TypeScript

  1. Paste your XML document into the Input editor, or use Sample, Upload file or Load URL, or press Sample to see an example.
  2. Leave Top-level class name empty to name the root type after the root element, or type your own name.
  3. Tick Types only (no helpers) for interfaces only, or leave it off to add a Convert class that validates the JSON form at runtime.
  4. Press Generate (it also updates as you edit), then use Copy or Download.

XML to TypeScript interfaces

JavaScript has no single standard way to turn XML into objects, so the shape you get depends on the parser. This XML to TypeScript generator converts your sample with fast-xml-parser, using these settings: attributes are kept without a prefix, element text next to attributes goes into a value property, namespace prefixes are removed, and numbers and booleans are parsed. It then writes TypeScript interfaces for that object shape. If you parse XML the same way in your app, the interfaces match the data exactly.

Example: an Atom feed

<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Release notes</title>
  <entry>
    <id>urn:uuid:1</id>
    <title>Version 2.0</title>
    <link href="https://example.com/v2" rel="alternate"/>
    <updated>2026-06-01T10:00:00Z</updated>
  </entry>
  <entry>
    <id>urn:uuid:2</id>
    <title>Version 1.9</title>
    <link href="https://example.com/v1-9" rel="alternate"/>
    <updated>2026-04-12T09:30:00Z</updated>
  </entry>
</feed>
export interface Feed {
    title: string;
    entry: Entry[];
}

export interface Entry {
    id:      string;
    title:   string;
    link:    Link;
    updated: Date;
}

export interface Link {
    href: string;
    rel:  string;
}

The xmlns declaration is dropped, the two <entry> elements become an array, and <link>, which carries only attributes, becomes an object with href and rel.

Parsing XML to match the interfaces

import { XMLParser } from "fast-xml-parser";

const parser = new XMLParser({
    ignoreAttributes: false,
    attributeNamePrefix: "",
    textNodeName: "value",
    removeNSPrefix: true,
    isArray: (name) => name === "entry",   // always an array, even with one entry
});
const feed = parser.parse(xmlText).feed as Feed;

The isArray callback matters: without it, a feed with a single entry parses as an object instead of an array, and your code breaks on the first quiet week. The same reason is why your sample should contain at least two of every repeating element. In the browser, DOMParser is an alternative, but then you read values with querySelector and getAttribute and build objects yourself.

Things to adjust

  • updated is typed Date, but a parser returns a string; change it to string unless you convert it.
  • Numeric-looking IDs lose leading zeros when parsed as numbers; disable number parsing for those tags or type them as strings.
  • An element that appears once in some documents and several times in others is typed as a union like string[] | string; normalize it with isArray and simplify the type.

To see the JSON produced from your XML, use XML to JSON. For RSS feeds, RSS to JSON is a quick preview. Format the output with the TypeScript Formatter. Generation runs in your browser.

Frequently asked questions

Which XML parser matches the generated interfaces?
fast-xml-parser configured with ignoreAttributes: false, attributeNamePrefix: "", textNodeName: "value" and removeNSPrefix: true produces the same object shape the generator uses.
Why is an element sometimes an object and sometimes an array?
XML has no array syntax, so a parser only knows an element repeats when it sees it twice. Use the parser’s isArray option for elements that can repeat.
Why was the xmlns attribute removed?
Namespace declarations and prefixes are stripped so property names stay simple. Your parser should use the same setting (removeNSPrefix) to match.
Are XML attributes and elements distinguished in the types?
No. Both become properties of the same interface, which matches how fast-xml-parser represents them without an attribute prefix.

Last updated September 26, 2026

Related tools

GraphQL to TypeScript Generate TypeScript interfaces, enums and union types from a GraphQL schema (SDL), with nullability and argument types. JSON Schema to TypeScript Turn JSON Schema into TypeScript interfaces and types with optional properties, enums, $ref definitions and JSDoc comments. JSON to TypeScript Generate TypeScript interfaces from a JSON sample instantly, with nested types detected automatically. JSON to C++ Generate C++ classes with nlohmann::json helpers from a JSON sample instantly, with nested types detected automatically. JSON to Crystal Generate Crystal classes with JSON mapping from a JSON sample instantly, with nested types detected automatically. JSON to C# Generate C# classes with JsonProperty attributes from a JSON sample instantly, with nested types detected automatically. JSON to Dart Generate Dart classes with fromJson and toJson from a JSON sample instantly, with nested types detected automatically. JSON to Elm Generate Elm type aliases with decoders from a JSON sample instantly, with nested types detected automatically. JSON to Flow Generate Flow Flow type definitions from a JSON sample instantly, with nested types detected automatically. JSON to Go Generate Go structs with json tags from a JSON sample instantly, with nested types detected automatically. JSON to Haskell Generate Haskell records with Aeson instances from a JSON sample instantly, with nested types detected automatically. JSON to Java Generate Java POJO classes with getters and setters from a JSON sample instantly, with nested types detected automatically.