These libraries handle the two main tasks of working with XML: reading (parsing) and writing (building). fast-xml-parser, libxmljs, and xml2js focus on converting XML text into JavaScript objects or DOM trees. xmlbuilder and xmlbuilder2 focus on creating XML text from JavaScript data. The choice often depends on whether you need raw speed, native validation, or browser compatibility, as some rely on Node.js native modules while others are pure JavaScript.
Working with XML in JavaScript usually means solving one of two problems: turning XML text into data you can use (parsing), or turning your data into XML text (building). The packages fast-xml-parser, libxmljs, and xml2js handle parsing, while xmlbuilder and xmlbuilder2 handle building. Let's look at how they handle real-world tasks like performance, environment support, and API design.
How a library reads XML matters when you deal with large files. Some build a full tree in memory, while others stream or optimize for speed.
fast-xml-parser is built for speed using pure JavaScript. It avoids heavy memory allocation and parses directly to a JSON object.
// fast-xml-parser: High performance parsing
const { XMLParser } = require("fast-xml-parser");
const parser = new XMLParser();
const result = parser.parse(xmlString);
console.log(result.root.element);
libxmljs uses native C++ bindings (libxml2). It is extremely fast and supports strict DOM standards, but it requires compilation.
// libxmljs: Native DOM parsing
const libxmljs = require("libxmljs");
const xmlDoc = libxmljs.parseXmlString(xmlString);
const root = xmlDoc.root();
console.log(root.text());
xml2js is the classic choice. It is reliable but generally slower because it focuses on flexibility and handling edge cases in XML structure.
// xml2js: Flexible parsing
const xml2js = require("xml2js");
const parser = new xml2js.Parser();
parser.parseString(xmlString, (err, result) => {
console.log(result.root.element);
});
xmlbuilder and xmlbuilder2 do not parse XML. They are write-only libraries. Attempting to read XML with them will not work.
// xmlbuilder / xmlbuilder2: No parsing capability
// These libraries are designed solely for creating XML, not reading it.
// You must use a parser like fast-xml-parser alongside them.
Frontend architects must know where the code will run. Native bindings break in browsers, while pure JS works everywhere.
fast-xml-parser runs anywhere JavaScript runs. It has no native dependencies, so it works in Webpack, Vite, and Node.js without extra config.
// fast-xml-parser: Works in Browser and Node
import { XMLParser } from "fast-xml-parser";
// No build steps needed for native modules
const parser = new XMLParser();
libxmljs requires Node.js and a C++ build environment. It will fail in a browser bundle unless you use a heavy shim or run it on a server.
// libxmljs: Node.js Only
// Will throw errors if bundled for client-side browser use
const libxmljs = require("libxmljs");
// Requires node-gyp to install
xml2js is pure JavaScript. It works in both Node.js and browser bundles, though it is heavier than fast-xml-parser.
// xml2js: Works in Browser and Node
const xml2js = require("xml2js");
// Safe to import in frontend bundles
xmlbuilder is pure JavaScript and works in both environments, but it is older and less optimized.
// xmlbuilder: Works in Browser and Node
const builder = require("xmlbuilder");
// Legacy support available
xmlbuilder2 is modern pure JavaScript. It is designed to work seamlessly in modern frontend build tools and Node.js.
// xmlbuilder2: Works in Browser and Node
const { create } = require("xmlbuilder2");
// Optimized for modern ES6+ environments
When you need to create XML, the API style affects how readable your code is. Chainable APIs tend to be cleaner than object configurations.
fast-xml-parser does not build XML. It is a parser only. You would need a separate library for generation.
// fast-xml-parser: No building capability
// Use xmlbuilder2 alongside this for generation tasks
libxmljs allows building via DOM manipulation. You create nodes and append them, similar to how you would in a browser.
// libxmljs: DOM-style building
const doc = libxmljs.Document().node("root");
doc.node("child", "content");
console.log(doc.toString());
xml2js does not build XML. It is a parser only. You must pair it with a builder library.
// xml2js: No building capability
// Pair with xmlbuilder2 for full round-trip support
xmlbuilder uses a chainable API but feels dated. It relies on callback-style function chaining.
// xmlbuilder: Legacy chainable API
const builder = require("xmlbuilder");
const xml = builder.create("root")
.ele("child").txt("content").up()
.end();
xmlbuilder2 uses a modern, clean chainable API with better support for namespaces and attributes.
// xmlbuilder2: Modern chainable API
const { create } = require("xmlbuilder2");
const doc = create().ele("root").ele("child", "content");
console.log(doc.end({ prettyPrint: true }));
XML is strict. How libraries handle bad input determines if your app crashes or recovers gracefully.
fast-xml-parser includes built-in validation options. You can configure it to throw errors on invalid tags or attributes.
// fast-xml-parser: Built-in validation
const parser = new XMLParser({ ignoreAttributes: false });
try {
parser.parse(invalidXml);
} catch (e) {
console.error("Parse failed", e);
}
libxmljs has robust error reporting because it wraps a mature C library. It provides detailed line numbers and error codes.
// libxmljs: Detailed native errors
try {
libxmljs.parseXmlString(invalidXml);
} catch (e) {
console.error(e.message, e.line); // Detailed debug info
}
xml2js passes errors to the callback or Promise rejection. It is lenient by default, which can hide issues.
// xml2js: Callback error handling
parser.parseString(invalidXml, (err, result) => {
if (err) console.error("Parse error", err);
});
xmlbuilder and xmlbuilder2 validate structure during creation. If you try to create invalid XML trees, they will throw.
// xmlbuilder2: Structure validation
try {
create().ele("root").ele("invalid"); // Example constraint
} catch (e) {
console.error("Build error", e);
}
Despite their differences, these libraries share common goals and patterns.
// Common goal: JS Object <-> XML String
// Parser: XML -> JS
// Builder: JS -> XML
fast-xml-parser and xmlbuilder2 favor synchronous operations for simplicity unless streaming is needed.// xml2js: Promise support
await parser.parseStringPromise(xml);
// fast-xml-parser: Sync by default
const result = parser.parse(xml);
@ or in a separate object).// fast-xml-parser
const parser = new XMLParser({ ignoreAttributes: false });
// xml2js
const parser = new xml2js.Parser({ attrkey: "@" });
| Feature | fast-xml-parser | libxmljs | xml2js | xmlbuilder | xmlbuilder2 |
|---|---|---|---|---|---|
| Primary Task | Parsing | Parsing & Building | Parsing | Building | Building |
| Language | Pure JS | Native C++ Bindings | Pure JS | Pure JS | Pure JS |
| Browser Safe | ✅ Yes | ❌ No (Node Only) | ✅ Yes | ✅ Yes | ✅ Yes |
| Performance | 🚀 Very High | 🚀 High | 🐢 Moderate | 🐢 Moderate | 🐇 Good |
| API Style | Config Object | DOM Methods | Callback/Promise | Chainable | Modern Chainable |
| Maintenance | 🟢 Active | 🟡 Stable | 🟢 Stable | 🟠 Legacy | 🟢 Active |
fast-xml-parser is the modern standard for reading XML. It is fast, safe for browsers, and easy to use. Pick this for most frontend and Node.js parsing tasks.
libxmljs is a specialist tool. Use it only on the server if you need strict DOM compliance or XPath queries that pure JS libraries cannot handle. Avoid it for frontend code.
xml2js is the reliable veteran. It is perfect for legacy systems or when you need specific parsing behaviors that other libraries do not support.
xmlbuilder is outdated. Do not start new projects with this. It is kept alive for compatibility but lacks modern features.
xmlbuilder2 is the best choice for writing XML. It is clean, modern, and works everywhere. Pair it with fast-xml-parser for a complete XML solution.
Final Thought: For a modern stack, combine fast-xml-parser for reading and xmlbuilder2 for writing. This gives you pure JavaScript compatibility, high performance, and a clean API without the headaches of native dependencies.
Choose fast-xml-parser for modern applications that need high performance without native dependencies. It is pure JavaScript, so it works seamlessly in both Node.js and browser environments. It is ideal when you need to parse large XML files quickly or require validation features like XSD support without the overhead of native bindings.
Choose libxmljs only for server-side Node.js applications where maximum parsing speed and strict XML standard compliance are critical. It relies on native C++ bindings (libxml2), which makes it unsuitable for browser-based frontend code or serverless environments that do not support native modules. Use this when you need advanced XPath queries or DOM manipulation that pure JS parsers struggle with.
Choose xml2js if you are maintaining legacy codebases or need a stable, battle-tested parser with a massive ecosystem. It is slower than modern alternatives but offers a very flexible configuration for handling XML attributes and text nodes. It is a safe default for general-purpose Node.js scripts where ultimate performance is not the primary concern.
Choose xmlbuilder only if you are working on an older project that already depends on it. It is in maintenance mode and lacks the modern API improvements found in its successor. For new projects, avoid this in favor of xmlbuilder2 to ensure better long-term support and a cleaner coding experience.
Choose xmlbuilder2 for any new project that requires generating XML documents. It offers a modern, chainable API that is easier to read and maintain than the original xmlbuilder. It supports both Node.js and browser environments, making it the most versatile choice for XML generation tasks today.
Validate XML, Parse XML to JS Object, or Build XML from JS Object without C/C++ based libraries and no callback.
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

Sponsor this project

This is a donation. No goods or services are expected in return. Any requests for refunds for those purposes will be rejected.
The list of users are mostly published by Github or communicated directly. Feel free to contact if you find any information wrong.
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 Name | Size |
|---|---|
| fxbuilder.min.js | 6.5K |
| fxparser.min.js | 20K |
| fxp.min.js | 26K |
| fxvalidator.min.js | 5.7K |
| v3 | v4 and v5 | v6 |
| documents |
note:
negative means error
* Y-axis: requests per second
Usage Trend of fast-xml-parser
This project exists thanks to all the people who contribute. [Contribute].
Thank you to all our backers! 🙏 [Become a backer]
