npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@sylphx/molt-xml

v1.0.2

Published

XML transformer - dirty cleaning, type preservation, and streaming

Readme

@sylphx/molt-xml

npm version CI License: MIT TypeScript

Fast and robust XML transformer - Dirty cleaning · Type preservation · Object conversion · Zero dependencies


Why molt-xml?

🔥 Handles dirty XML - Fixes malformed XML automatically 🎯 Type-safe - Full TypeScript support with strict types 🔄 Bidirectional - Parse to DOM or objects, stringify back to XML 🛡️ Production-ready - Comprehensive test coverage ⚡ Fast parsing - Efficient state machine parser 🌊 Streaming support - Process large XML files efficiently

import { molt } from '@sylphx/molt-xml'

// Parse dirty XML to JavaScript object
const data = molt('<user name=alice age=30/>')
// => { '@name': 'alice', '@age': '30' }

// Clean dirty XML
import { MoltXML } from '@sylphx/molt-xml'
const clean = MoltXML.clean('<user name=alice>')
// => '<user name="alice"></user>'

Features

🔥 Dirty XML Cleaning

Handle real-world malformed XML:

import { MoltXML } from '@sylphx/molt-xml'

// Missing quotes
const clean1 = MoltXML.clean('<user name=alice age=30/>')
// => '<user name="alice" age="30"/>'

// Unclosed tags
const clean2 = MoltXML.clean('<div><p>Hello</div>')
// => '<div><p>Hello</p></div>'

// Mixed issues
const dirty = '<config port=8080 enabled=true><server host=localhost></config>'
const clean3 = MoltXML.clean(dirty)

📦 Parse to Objects

Convert XML to JavaScript objects:

import { molt } from '@sylphx/molt-xml'

const xml = `
  <user>
    <name>Alice</name>
    <age>30</age>
    <tags>
      <tag>developer</tag>
      <tag>typescript</tag>
    </tags>
  </user>
`

const data = molt(xml)
/*
{
  user: {
    name: 'Alice',
    age: '30',
    tags: {
      tag: ['developer', 'typescript']
    }
  }
}
*/

🏗️ Parse to DOM

Get structured XMLDocument:

import { MoltXML } from '@sylphx/molt-xml'

const doc = MoltXML.parse('<root><item id="1">Hello</item></root>')

// Navigate DOM
doc.root.children[0]  // XMLElement
doc.root.children[0].attributes.id  // "1"
doc.root.children[0].children[0]  // Text node

✍️ Stringify

Convert XMLDocument back to XML:

import { MoltXML } from '@sylphx/molt-xml'

const doc = MoltXML.parse('<root><item>Hello</item></root>')
const xml = MoltXML.stringify(doc, {
  pretty: true,
  indent: 2,
})

Installation

bun add @sylphx/molt-xml
# or
npm install @sylphx/molt-xml
# or
pnpm add @sylphx/molt-xml

API

⚡ Unified API (Recommended)

molt(input, options?)

Parse XML string to JavaScript object.

import { molt } from '@sylphx/molt-xml'

const data = molt('<user name="alice" age="30"/>')
// => { '@name': 'alice', '@age': '30' }

Options:

interface ParseXMLOptions {
  cleanDirty?: boolean     // Clean dirty XML before parsing (default: true)
  preserveWhitespace?: boolean  // Preserve whitespace in text (default: false)
  parseTypes?: boolean     // Auto-convert types (numbers, booleans) (default: false)
  maxSize?: number         // Maximum input size in bytes
}

🏗️ DOM API

MoltXML.parse(input, options?)

Parse XML to XMLDocument:

import { MoltXML } from '@sylphx/molt-xml'

const doc = MoltXML.parse(`
  <root>
    <item id="1">Hello</item>
  </root>
`)

// Access DOM
doc.root.name  // 'root'
doc.root.children[0].attributes  // { id: '1' }

MoltXML.toObject(input, options?)

Parse XML directly to object (same as molt()):

import { MoltXML } from '@sylphx/molt-xml'

const obj = MoltXML.toObject('<user><name>Alice</name></user>')

MoltXML.stringify(doc, options?)

Stringify XMLDocument to XML string:

import { MoltXML } from '@sylphx/molt-xml'

const doc = MoltXML.parse('<root/>')
const xml = MoltXML.stringify(doc, {
  pretty: true,
  indent: 2,
  xmlDeclaration: true,
})

Options:

interface StringifyXMLOptions {
  pretty?: boolean         // Pretty print (default: false)
  indent?: number          // Indentation spaces (default: 2)
  xmlDeclaration?: boolean // Include <?xml?> declaration (default: false)
}

🧹 Clean API

MoltXML.clean(input, maxSize?)

Clean dirty XML to valid XML:

import { MoltXML } from '@sylphx/molt-xml'

const clean = MoltXML.clean('<user name=alice age=30/>')
// => '<user name="alice" age="30"/>'

🚨 Error Handling

import { MoltXML, XMLError, ParseError, ValidationError } from '@sylphx/molt-xml'

try {
  const data = molt(invalidXml)
} catch (err) {
  if (err instanceof ParseError) {
    console.error(`Parse error: ${err.message}`)
  } else if (err instanceof ValidationError) {
    console.error(`Validation error: ${err.message}`)
  } else if (err instanceof XMLError) {
    console.error(`XML error: ${err.message}`)
  }
}

Use Cases

1. Parse Configuration Files

import { molt } from '@sylphx/molt-xml'
import fs from 'fs'

// Read pom.xml (Maven)
const pom = molt(fs.readFileSync('pom.xml', 'utf8'))
console.log(pom.project.groupId, pom.project.artifactId)

// Read web.config
const config = molt(fs.readFileSync('web.config', 'utf8'))

2. API Response Handling

import { molt } from '@sylphx/molt-xml'

// Handle XML from APIs
const response = await fetch('https://api.example.com/data.xml')
const xml = await response.text()
const data = molt(xml, {
  cleanDirty: true,
  parseTypes: true,
})

3. Data Transformation

import { molt, MoltXML } from '@sylphx/molt-xml'

// XML to Object
const obj = molt('<users><user id="1"><name>Alice</name></user></users>')

// Process data
const processed = {
  ...obj.users,
  timestamp: new Date().toISOString(),
}

// Back to XML (via JSON)
import { stringifyTOML } from '@sylphx/molt-toml'
const toml = stringifyTOML(processed)

4. Clean Dirty XML

import { MoltXML } from '@sylphx/molt-xml'
import fs from 'fs'

// Read dirty XML from external source
const dirty = fs.readFileSync('dirty.xml', 'utf8')

// Clean and save
const clean = MoltXML.clean(dirty)
fs.writeFileSync('clean.xml', clean)

Supported XML Features

| Feature | Parsing | Stringifying | |---------|---------|--------------| | Elements | ✅ | ✅ | | Attributes | ✅ | ✅ | | Text content | ✅ | ✅ | | CDATA sections | ✅ | ✅ | | Comments | ✅ | ✅ | | Processing instructions | ✅ | ✅ | | XML declaration | ✅ | ✅ | | Namespaces | ✅ | ✅ | | Self-closing tags | ✅ | ✅ | | Mixed content | ✅ | ✅ | | Dirty XML (unquoted attrs) | ✅ | ❌ | | Type conversion | ✅ | ❌ |


Object Conversion

XML is converted to JavaScript objects with these conventions:

// Attributes use @ prefix
'<user id="1"/>' => { '@id': '1' }

// Text content uses # key
'<name>Alice</name>' => { name: 'Alice' }

// Mixed content preserves structure
'<p>Hello <b>world</b>!</p>' => {
  p: [
    'Hello ',
    { b: 'world' },
    '!'
  ]
}

// Multiple children with same name become array
`<tags>
  <tag>a</tag>
  <tag>b</tag>
</tags>` => { tags: { tag: ['a', 'b'] } }

Contributing

We welcome contributions! Please see CONTRIBUTING.md for details.

Development

# Install dependencies (from monorepo root)
cd ../..
bun install

# Run tests
bun test

# Build
bun run build

# Lint and format
bun lint
bun format

Part of molt Family

@sylphx/molt-xml is part of the molt data transformation stack:

  • @sylphx/molt-json - JSON transformer
  • @sylphx/molt-xml - XML transformer (this package)
  • @sylphx/molt-yaml - YAML transformer
  • @sylphx/molt-toml - TOML transformer
  • @sylphx/molt-csv - CSV transformer
  • @sylphx/molt - Meta package with all formats

See the monorepo root for more information.


License

MIT © Sylphx