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 🙏

© 2026 – Pkg Stats / Ryan Hefner

xml-language-service

v1.1.0

Published

Editor-agnostic XML language service with fault-tolerant parsing, XSD validation (Xerces-C++ WASM), completions, hover, symbols, folding, formatting, rename, definition and references.

Downloads

41

Readme

This tool helps you work with XML in JavaScript and TypeScript projects. It can understand XML even if it has errors, and it gives features like auto complete, hover info, formatting, renaming tags, finding definitions, and validating with XSD. You can use it in editors, language servers, CLI tools, web apps, or tests.. without needing Java or installing native software.

Architecture Overview

Links

| Resource | URL | | --- | --- | | npm package | https://www.npmjs.com/package/xml-language-service | | Documentation | https://harshanacz.github.io/xml-language-service/ | | Repository | https://github.com/harshanacz/xml-language-service | | Issues | https://github.com/harshanacz/xml-language-service/issues | | Project using this | https://github.com/harshanacz/xml-review-bot-demo |

Install

npm install xml-language-service

Requirements:

  • Node.js 18 or newer
  • ESM-compatible project setup

The npm package includes the Xerces WASM assets, so consumers do not need to install Java, Xerces, Emscripten, or a native compiler.

Quick Start

import { getLanguageService } from "xml-language-service";

const service = getLanguageService();

const xml = `<catalog>
  <book id="bk101">
    <title>XML Developer Guide</title>
  </book>
</catalog>`;

const document = service.parseXMLDocument("file:///catalog.xml", xml);

const completions = service.doComplete(document, { line: 1, character: 4 });
const hover = service.doHover(document, { line: 2, character: 6 });
const symbols = service.findDocumentSymbols(document);
const foldingRanges = service.getFoldingRanges(document);

console.log(completions.items);
console.log(hover);
console.log(symbols);
console.log(foldingRanges);

service.dispose();

What You Get

| Feature | Description | | --- | --- | | Fault-tolerant parser | Builds a usable partial tree even when the XML is incomplete or malformed. | | Completion | Suggests element names, attributes, and closing tags. Can become XSD-aware when a schema is registered. | | Hover | Returns contextual information for XML elements, comments, and schema-backed nodes. | | Document symbols | Produces a hierarchical outline for editor sidebars and navigation views. | | Folding | Finds multi-line XML regions that can be collapsed. | | Formatting | Returns text edits for consistent XML indentation and spacing. | | Rename | Renames matching opening and closing tags together. | | Definition | Jumps between matching opening and closing tags. | | References | Finds elements with the same tag name in the document. | | XSD validation | Reports syntax and schema diagnostics through Xerces-C++ WASM. | | AST/CST printer | Prints parser output as a tree or JSON for debugging and snapshot tests. |

Public API

The main entry point is getLanguageService().

import { getLanguageService } from "xml-language-service";

const service = getLanguageService();

Common service methods:

| Method | Purpose | | --- | --- | | parseXMLDocument(uri, text) | Parse XML text into an XMLDocument. | | doComplete(document, position, fileName?, documentPath?) | Get completion items. | | doHover(document, position, fileName?, documentPath?) | Get hover content. | | findDocumentSymbols(document) | Get a nested document symbol tree. | | getFoldingRanges(document) | Get folding ranges. | | format(document, options?) | Get formatting text edits. | | doRename(document, position, newName) | Rename an element tag pair. | | doDefinition(document, position) | Find the matching tag definition. | | findReferences(document, position) | Find same-name element references. | | registerSchema(schema) | Register an XSD schema or schema bundle. | | validate(schemaUri, document) | Validate a parsed document against a registered schema. | | addUserAssociation(association) | Associate schemas with file names, paths, or namespaces. | | printTreeAST(document) | Print the AST as a visual text tree (├──, └──). | | printAST(document, options?) | Print the parsed AST for debugging. | | printCST(document, options?) | Print the raw CST for debugging. | | dispose() | Release schema provider resources. |

The package also exports core types such as XMLDocument, XMLNode, XMLAttribute, Position, Range, Diagnostic, SchemaBundle, CompletionItem, HoverResult, DocumentSymbol, FoldingRange, and TextEdit.

XSD Validation

XSD validation is handled by Apache Xerces-C++ compiled to WebAssembly. Xerces uses a SAX streaming parser, so parsing and schema validation happen in the same pass.

raw XML text
    |
    v
Xerces SAX stream
    |
    +-- syntax diagnostics
    +-- XSD diagnostics

This matters because diagnostics can still be reported for the part of the document Xerces was able to read before a fatal syntax error.

Register A Single XSD

const service = getLanguageService();

await service.registerSchema({
  uri: "file:///schema.xsd",
  xsdText: xsdContent,
});

const document = service.parseXMLDocument("file:///catalog.xml", xmlText);
const diagnostics = await service.validate("file:///schema.xsd", document);

Register A Schema Bundle

Use a SchemaBundle when the root schema references other files with xs:include or xs:import. The imports keys should match the schemaLocation values used inside the XSD.

await service.registerSchema({
  uri: "file:///root.xsd",
  xsdText: rootXsdContent,
  imports: {
    "types.xsd": typesXsdContent,
    "common.xsd": commonXsdContent,
  },
});

Built-In Schemas

The service ships with built-in schemas for common XML files and can associate them automatically by filename or namespace.

| File | Schema | | --- | --- | | pom.xml | Maven 4.0.0 | | web.xml | Java Servlet 3.1 |

You can register additional associations with addUserAssociation().

Debugging AST And CST Output

Three functions let you inspect parser output, create snapshot tests, or understand the tree structure of any XML document.

import { getLanguageService } from "xml-language-service";

const service = getLanguageService();
const document = service.parseXMLDocument(
  "file:///catalog.xml",
  `<catalog><book id="bk101"/></catalog>`,
);

// Visual text tree — quick structural overview
console.log(service.printTreeAST(document));
// Document
// └── catalog
//     └── book

// Full AST — includes attributes, text and comment nodes
console.log(service.printAST(document));
console.log(service.printAST(document, { includePositions: true }));
console.log(service.printAST(document, { format: "json" }));

// Raw CST — every grammar rule and token produced by the parser
console.log(service.printCST(document));

printAST and printCST accept these options:

| Option | Type | Default | | --- | --- | --- | | format | "tree" \| "json" | "tree" | | indent | number | 2 | | includePositions | boolean | false | | includeTokens | boolean | true |

Manual Debug Script

A ready-made script at tests/utils/manual.mjs exercises all three printers against a sample XML document. Run it directly with Node — no test runner needed:

npm run build
node tests/utils/manual.mjs

Architecture

TextDocument
    |
    v
@xml-tools/parser
    |
    v
XMLDocument
    |
    +-- completion
    +-- hover
    +-- symbols
    +-- folding
    +-- formatting
    +-- rename
    +-- definition
    +-- references
    |
    v
SchemaProvider
    |
    v
Xerces-C++ WASM

Development

npm install
npm run build
npm run build:watch
npm run test:run
npm test

Useful scripts:

| Script | Description | | --- | --- | | npm run build | Compile TypeScript and copy schema/WASM assets into dist. | | npm run build:watch | Compile TypeScript in watch mode. | | npm run test:run | Run the Vitest suite once. | | npm test | Run Vitest in watch mode. |

License

MIT