fast-xml-parser vs xml2js vs xml-js vs xml-parser
Parsing and Converting XML in JavaScript Applications
fast-xml-parserxml2jsxml-jsxml-parser
Parsing and Converting XML in JavaScript Applications

fast-xml-parser, xml-js, xml-parser, and xml2js are npm packages designed to parse XML strings into JavaScript objects or convert JavaScript objects back into XML. These libraries help frontend and full-stack developers handle XML data—commonly used in legacy APIs, configuration files, or enterprise integrations—within modern JavaScript environments. Each package offers different trade-offs in parsing strictness, performance, feature set, and ease of use.

Npm Package Weekly Downloads Trend
3 Years
Github Stars Ranking
Stat Detail
Package
Downloads
Stars
Size
Issues
Publish
License
fast-xml-parser50,707,5212,990588 kB69a month agoMIT
xml2js26,443,0314,9713.44 MB2472 years agoMIT
xml-js4,249,8161,337-1267 years agoMIT
xml-parser128,024103-911 years agoMIT

Parsing XML in JavaScript: fast-xml-parser vs xml-js vs xml2js (and Why to Avoid xml-parser)

When you’re stuck dealing with XML—whether from a SOAP API, an old config file, or a third-party feed—you’ll likely reach for an npm package to turn that markup into something JavaScript can actually work with. Among the popular choices are fast-xml-parser, xml-js, xml2js, and the outdated xml-parser. Let’s cut through the noise and compare them based on real engineering concerns: correctness, performance, API design, and maintainability.

⚠️ First: Deprecation Check

Before diving deep, note this critical fact:

  • xml-parser is deprecated. Its npm page explicitly states: "This module is deprecated. Please use xml2js instead." It hasn’t been updated since 2015, lacks namespace support, fails on many valid XML inputs, and should not be used in any new project.

We’ll focus the rest of this comparison on the three actively maintained alternatives.

📥 Basic Parsing: Turning XML into JS Objects

All three usable packages convert XML strings into plain JavaScript objects—but they do it differently.

fast-xml-parser

Uses a recursive descent parser. By default, it preserves attribute names under a @_ prefix and text content under #text. You can disable attributes or change parsing behavior via options.

// fast-xml-parser
import { parse } from 'fast-xml-parser';

const xml = `<book id="101"><title>JS Guide</title></book>`;
const result = parse(xml);
// { book: { '@_id': '101', title: 'JS Guide' } }

xml-js

Offers two modes: element (tree-like with type metadata) and javascript (simpler object). The latter is more common for app logic.

// xml-js
import { xml2js } from 'xml-js';

const xml = `<book id="101"><title>JS Guide</title></book>`;
const result = xml2js(xml, { compact: true });
// { book: { _attributes: { id: '101' }, title: 'JS Guide' } }

xml2js

Uses the sax parser under the hood and relies on callbacks (though promisified versions exist). Attributes go into a $ property by default.

// xml2js
import { parseStringPromise } from 'xml2js';

const xml = `<book id="101"><title>JS Guide</title></book>`;
const result = await parseStringPromise(xml);
// { book: { $: { id: '101' }, title: [ 'JS Guide' ] } }

💡 Notice how xml2js always wraps child text in arrays—even for single elements. This avoids ambiguity but adds noise.

🔁 Round-Trip Conversion: JS Object → XML

Sometimes you need to generate XML from data (e.g., for API requests). Only two of these support reliable round-trip conversion.

fast-xml-parser

Includes a parse and unparse pair. The output closely matches input if you preserve structure.

// fast-xml-parser: round-trip
import { parse, unparse } from 'fast-xml-parser';

const xml = '<note><to>Alice</to></note>';
const obj = parse(xml);
const backToXml = unparse(obj);
// "<note><to>Alice</to></note>"

xml-js

Also supports bidirectional conversion cleanly.

// xml-js: round-trip
import { js2xml, xml2js } from 'xml-js';

const xml = '<note><to>Alice</to></note>';
const obj = xml2js(xml, { compact: true });
const backToXml = js2xml(obj, { compact: true });
// "<note><to>Alice</to></note>"

xml2js

Does not include a built-in serializer. You’d need a separate package like js2xmlparser—breaking round-trip symmetry and adding maintenance risk.

🧪 Handling Edge Cases: Namespaces, CDATA, and Whitespace

Real XML isn’t always clean. How do these libraries cope?

  • Namespaces:

    • fast-xml-parser supports them out of the box (ignoreNameSpace: false by default).
    • xml-js ignores namespaces unless you use non-compact mode (then they appear as prefix:localName).
    • xml2js supports them via the xmlns option but requires extra config.
  • CDATA:

    • All three preserve CDATA content as text, though xml2js may require explicitChildren: true to avoid merging.
  • Whitespace:

    • fast-xml-parser trims by default (trimValues: true), but you can disable it.
    • xml-js preserves whitespace in compact mode.
    • xml2js keeps all whitespace unless you set normalize: true.

⚙️ Performance and Bundle Impact

While we won’t quote numbers (per instructions), consider these qualitative differences:

  • fast-xml-parser is written in pure JavaScript with zero dependencies. It’s optimized for speed and works in browsers without polyfills.
  • xml-js is also dependency-free and lightweight, but not tuned for large documents.
  • xml2js depends on the sax parser, which is robust but heavier. It’s primarily designed for Node.js and may bloat browser bundles.

🛠️ Error Handling and Validation

  • fast-xml-parser throws clear errors on malformed XML (e.g., unclosed tags) and offers optional validation.
  • xml-js uses try/catch internally but gives vague error messages like “Invalid character” without context.
  • xml2js emits errors via callbacks or rejects promises, but stack traces can be hard to debug due to sax’s event-driven nature.

🌐 Environment Support

  • Browser: fast-xml-parser and xml-js work out of the box. xml2js can be bundled but isn’t optimized for it.
  • Node.js: All three work, but xml2js is most entrenched in legacy Node ecosystems.

📊 Summary Table

Featurefast-xml-parserxml-jsxml2js
Actively maintained✅ Yes✅ Yes✅ Yes
Bidirectional✅ Parse + unparse✅ xml2js + js2xml❌ Parse only
Zero dependencies❌ (depends on sax)
Browser-friendly✅ Excellent✅ Good⚠️ Possible, but heavy
Array handlingSingle values stay scalarSingle values stay scalarAlways arrays
Error clarity✅ Clear messages⚠️ Generic errors⚠️ Hard to trace
Namespace support✅ Built-in⚠️ Limited✅ With config

💡 Final Recommendation

  • For new browser or full-stack apps: Start with fast-xml-parser. It’s fast, correct, dependency-free, and handles real-world XML gracefully.
  • For simple config/data files where readability matters: xml-js is fine if your data is small and you value compact object shapes.
  • For maintaining legacy Node.js integrations: xml2js is acceptable if you’re already using it, but don’t adopt it for new work.
  • Never use xml-parser—it’s obsolete and unsafe.

In practice, most teams today will find fast-xml-parser hits the sweet spot: it just works, doesn’t surprise you, and stays out of your way.

How to Choose: fast-xml-parser vs xml2js vs xml-js vs xml-parser
  • fast-xml-parser:

    Choose fast-xml-parser when you need high-performance XML parsing with minimal memory overhead and support for both browser and Node.js environments. It’s ideal for applications that process large XML documents or require validation against basic XML rules without external dependencies. Its streaming parser and customizable options (like ignoring attributes or preserving order) make it suitable for real-world production systems where speed and correctness matter.

  • xml2js:

    Choose xml2js when working in a Node.js environment and you need mature, battle-tested XML parsing with extensive configuration options (e.g., explicit array coercion, custom tag processors). It’s commonly used in enterprise or legacy integration scenarios but comes with heavier runtime behavior due to its reliance on the sax parser and callback-based design. Not recommended for browser-only apps unless bundled carefully.

  • xml-js:

    Choose xml-js if your primary need is bidirectional conversion between XML and JavaScript objects with a simple, consistent API. It’s well-suited for smaller payloads where readability of the resulting object structure is important, and you don’t require advanced XML features like namespaces or DTDs. Avoid it for performance-critical paths or large documents, as it’s not optimized for speed.

  • xml-parser:

    Do not choose xml-parser for new projects — it is deprecated on npm and no longer maintained. The package lacks modern features, has known limitations in handling edge cases, and hasn’t received updates in years. Use fast-xml-parser or xml2js instead depending on your needs.

README for fast-xml-parser

fast-xml-parser

NPM total downloads

Validate XML, Parse XML to JS Object, or Build XML from JS Object without C/C++ based libraries and no callback.

FXP logo
  • Validate XML data syntactically. Use detailed-xml-validator to verify business rules.
  • Parse XML to JS Objects and vice versa
  • Common JS, ESM, and browser compatible
  • Faster than any other pure JS implementation.

It can handle big files (tested up to 100mb). XML Entities, HTML entities, and DOCTYPE entites are supported. Unpaired tags (Eg <br> in HTML), stop nodes (Eg <script> in HTML) are supported. It can also preserve Order of tags in JS object


Your Support, Our Motivation

Try out our New Thoughts

  • WishIn - You need it if negative thoughts take over all the time
  • Flowgger: 90% less logs size and 90% less debugging time
    Flowgger Logging Framework
  • Text2Chart: interactive flow chart out of simple text.

Financial Support

Sponsor this project

donate button


fxp_sponsors

This is a donation. No goods or services are expected in return. Any requests for refunds for those purposes will be rejected.

Users

more

The list of users are mostly published by Github or communicated directly. Feel free to contact if you find any information wrong.


More about this library

How to use

To use as package dependency $ npm install fast-xml-parser or $ yarn add fast-xml-parser

To use as system command $ npm install fast-xml-parser -g

To use it on a webpage include it from a CDN

Example

As CLI command

$ fxparser some.xml

In a node js project

const { XMLParser, XMLBuilder, XMLValidator} = require("fast-xml-parser");

const parser = new XMLParser();
let jObj = parser.parse(XMLdata);

const builder = new XMLBuilder();
const xmlContent = builder.build(jObj);

In a HTML page

<script src="path/to/fxp.min.js"></script>
:
<script>
  const parser = new fxparser.XMLParser();
  parser.parse(xmlContent);
</script>

Bundle size

Bundle NameSize
fxbuilder.min.js6.5K
fxparser.min.js20K
fxp.min.js26K
fxvalidator.min.js5.7K

Documents

v3v4 and v5v6
documents
  1. Getting Started
  2. XML Parser
  3. XML Builder
  4. XML Validator
  5. Entities
  6. HTML Document Parsing
  7. PI Tag processing
  1. Getting Started
  2. Features
  3. Options
  4. Output Builders
  5. Value Parsers

note:

  • Version 6 is released with version 4 for experimental use. Based on it's demand, it'll be developed and the features can be different in final release.
  • Version 5 has the same functionalities as version 4.

Performance

negative means error

XML Parser

  • Y-axis: requests per second
  • X-axis: File size

XML Builder

* Y-axis: requests per second

Usage Trend

Usage Trend of fast-xml-parser

NPM Usage Trend of fast-xml-parser

Supporters

Contributors

This project exists thanks to all the people who contribute. [Contribute].

Backers from Open collective

Thank you to all our backers! 🙏 [Become a backer]

License

  • MIT License

Donate $5