🚀 Big News:Socket Has Acquired Secure Annex.Learn More
Socket
Book a DemoSign in
Socket

@stacksjs/ts-xml

Package Overview
Dependencies
Maintainers
2
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@stacksjs/ts-xml

A fast, dependency-free XML parser, builder, and validator for TypeScript & Bun.

latest
Source
npmnpm
Version
0.1.0
Version published
Weekly downloads
55K
-8.64%
Maintainers
2
Weekly downloads
 
Created
Source

Social Card of this repo

npm version GitHub Actions Commitizen friendly

ts-xml

A fast, dependency-free XML parser, builder, and validator for TypeScript and Bun. Character-by-character parsing with charCodeAt comparisons for maximum performance.

Features

  • Zero Dependencies - only Bun as a runtime
  • XMLParser - parse XML strings to JavaScript objects
  • XMLBuilder - build XML strings from JavaScript objects
  • XMLValidator - validate XML structure with detailed error reporting
  • Entity Handling - XML, HTML, numeric, and hex entity decoding/encoding
  • Namespace Support - optional namespace prefix removal
  • Preserve Order - array-based output to maintain element ordering
  • Stop Nodes - skip parsing of specific tag contents
  • Unpaired Tags - support for HTML-style void elements (e.g., <br>, <hr>)
  • CDATA & Comments - optionally capture CDATA sections and comments as properties
  • Processing Instructions - capture <?xml?> declarations and custom PIs
  • Value Parsing - automatic number, boolean, hex, and scientific notation parsing
  • Custom Processors - tag value, attribute value, and tag name transformation callbacks
  • Fully Typed - complete TypeScript type definitions

Get Started

Installation

bun install ts-xml

Parsing XML

import { XMLParser } from 'ts-xml'

const parser = new XMLParser()
const result = parser.parse('<root><item>Hello</item></root>')
// { root: { item: 'Hello' } }

Parsing with Attributes

import { XMLParser } from 'ts-xml'

const parser = new XMLParser({ ignoreAttributes: false })
const result = parser.parse('<book isbn="978-0-123"><title>XML Guide</title></book>')
// { book: { '@_isbn': '978-0-123', title: 'XML Guide' } }

Building XML

import { XMLBuilder } from 'ts-xml'

const builder = new XMLBuilder({ format: true, indentBy: '  ' })
const xml = builder.build({
  root: {
    item: ['one', 'two', 'three'],
  },
})

Validating XML

import { XMLValidator } from 'ts-xml'

const result = XMLValidator('<root><child/></root>')
if (result === true) {
  console.log('Valid XML')
}
else {
  console.log(`Error: ${result.err.msg} at line ${result.err.line}`)
}

Preserve Element Order

import { XMLParser, XMLBuilder } from 'ts-xml'

const parser = new XMLParser({ preserveOrder: true })
const ordered = parser.parse('<root><a>1</a><b>2</b><a>3</a></root>')
// Maintains original element order as arrays

const builder = new XMLBuilder({ preserveOrder: true })
const xml = builder.build(ordered) // Round-trips correctly

Configuration

Parser Options

OptionTypeDefaultDescription
attributeNamePrefixstring"@_"Prefix for attribute names
attributesGroupNamestring | falsefalseGroup attributes under this key
textNodeNamestring"#text"Property name for text content
ignoreAttributesbooleantrueSkip attribute parsing
removeNSPrefixbooleanfalseStrip namespace prefixes
allowBooleanAttributesbooleanfalseAllow attributes without values
alwaysCreateTextNodebooleanfalseAlways create text node property
trimValuesbooleantrueTrim whitespace from values
parseTagValuebooleantrueParse numbers/booleans from text
parseAttributeValuebooleanfalseParse numbers/booleans from attributes
processEntitiesbooleantrueDecode XML entities
htmlEntitiesbooleanfalseDecode HTML entities
commentPropNamestring | falsefalseProperty name for comments
cdataPropNamestring | falsefalseProperty name for CDATA sections
piPropNamestring | falsefalseProperty name for processing instructions
preserveOrderbooleanfalseMaintain element ordering
stopNodesstring[][]Tags whose content is not parsed
unpairedTagsstring[][]Tags that don't need closing
numberParseOptionsNumberParseOptions{ hex: true, leadingZeros: true, scientific: true }Number parsing behavior

Builder Options

OptionTypeDefaultDescription
attributeNamePrefixstring"@_"Prefix for attribute names
textNodeNamestring"#text"Property name for text content
ignoreAttributesbooleanfalseSkip attributes when building
formatbooleanfalsePretty-print output
indentBystring" "Indentation string
suppressEmptyNodebooleanfalseRender empty nodes as self-closing
suppressBooleanAttributesbooleantrueRender boolean attributes without ="true"
processEntitiesbooleantrueEncode entities in output
preserveOrderbooleanfalseBuild from ordered format

Benchmarks

Benchmarked on Apple M3 Pro using mitata, comparing against fast-xml-parser, xml2js, and sax.

Parsing

Benchmarkts-xmlfast-xml-parserxml2jssax
Simple XML344 ns1.64 µs (4.8x slower)2.03 µs885 ns
Medium (3 products + attrs)6.67 µs27.4 µs (4.1x slower)18.0 µs12.3 µs
Large (100 products)321 µs1.16 ms (3.6x slower)2.04 ms1.88 ms
Very Large (1000 products)3.02 ms13.0 ms (4.3x slower)9.83 ms4.90 ms
CDATA831 ns2.89 µs (3.5x slower)5.62 µs5.36 µs
Deep nesting (50 levels)9.33 µs59.1 µs (6.3x slower)43.0 µs27.5 µs
RSS Feed8.33 µs40.4 µs (4.9x slower)53.9 µs28.7 µs
Entities2.28 µs6.05 µs (2.7x slower)9.42 µs6.42 µs
Namespaces3.42 µs14.4 µs (4.2x slower)11.6 µs7.91 µs

Building

Benchmarkts-xmlfast-xml-parserxml2js
Small object1.61 µs3.83 µs (2.4x slower)8.60 µs
Large (100 products)42.6 µs118 µs (2.8x slower)197 µs
Formatted output1.67 µs4.07 µs (2.4x slower)8.05 µs

Validation

Benchmarkts-xmlfast-xml-parser
Valid XML3.30 µs7.79 µs (2.4x slower)
Large valid (1000 products)1.39 ms3.37 ms (2.4x slower)
Invalid XML (early exit)260 ns591 ns (2.3x slower)

Round-trip

Benchmarkts-xmlfast-xml-parser
Parse + Build (medium)9.15 µs34.7 µs (3.8x slower)

Run benchmarks yourself: bun run bench

Testing

bun test

724 tests across 6 test files covering parser, builder, validator, entities, and edge cases.

Changelog

Please see our releases page for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Community

For help, discussion about best practices, or any other conversation that would benefit from being searchable:

Discussions on GitHub

For casual chit-chat with others using this package:

Join the Stacks Discord Server

Postcardware

"Software that is free, but hopes for a postcard." We love receiving postcards from around the world showing where Stacks is being used! We showcase them on our website too.

Our address: Stacks.js, 12665 Village Ln #2306, Playa Vista, CA 90094, United States 🌎

Sponsors

We would like to extend our thanks to the following sponsors for funding Stacks development. If you are interested in becoming a sponsor, please reach out to us.

License

The MIT License (MIT). Please see LICENSE for more information.

Made with 💙

Keywords

xml

FAQs

Package last updated on 12 Mar 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts