Fast, tiny, standards-compliant XML DOM implementation for node and the browser.
This is a (partial) implementation of the following specifications:
- DOM living standard, as last updated 19 December 2021
- DOM Parsing and Serialization W3C Editor's Draft, as last updated 20 April 2020
- Extensible Markup Language (XML) 1.0 (Fifth Edition)
- Namespaces in XML 1.0 (Third Edition)
See the 'Features and Limitations' section below for details on what's included and what's not.
The slimdom library can be installed using npm or yarn:
npm install --save slimdom
yarn add slimdom
The package includes both a commonJS-compatible UMD bundle (
dist/slimdom.umd.js) and an ES6 module (
Create documents using the slimdom.Document constructor, and manipulate them using the standard DOM API.
import * as slimdom from 'slimdom'; // alternatively, in node and other commonJS environments: // const slimdom = require('slimdom'); // Start with an empty document: const document = new slimdom.Document(); document.appendChild(document.createElementNS('http://www.example.com', 'root')); const xml = slimdom.serializeToWellFormedString(document); // -> '<root xmlns="http://www.example.com"/>' // Or parse from a string: const document2 = slimdom.parseXmlDocument('<root attr="value">Hello!</root>'); document2.documentElement.setAttribute('attr', 'new value'); const xml2 = slimdom.serializeToWellFormedString(document2); // -> '<root attr="new value">Hello!</root>'
Some DOM API's, such as the
DocumentFragment constructor, require the presence of a global document, for instance to set their initial
ownerDocument property. In these cases, slimdom will use the instance exposed through
slimdom.document. Although you could mutate this document, it is recommended to always create your own documents (using the
Document constructor) to avoid conflicts with other code using slimdom in your application.
When using a
Range, make sure to call
detach when you don't need it anymore. Unless you are only targeting environments that implement the WeakRef proposal, we do not have a way to detect when we can stop updating the range for mutations to the surrounding nodes. In environments that support WeakRef, calling detach is optional.
Features and limitations
This library implements:
- All node types:
Range, which correctly updates under mutations.
XMLSerializer, and read-only versions of
DOMParser, for XML parsing only.
NamedNodeMap, HTML documents are treated no different from other documents and a number of features from in the DOM spec are missing. In most cases, this is because alternatives are available that can be used together with slimdom with minimal effort.
This library implements the changes from whatwg/dom#819, as the specification as currently described has known bugs around adoption.
As serializing XML using the
XMLSerializer does not enforce well-formedness, you may instead want to use the
serializeToWellFormedString function which does perform such checks.
DOMParser interface is implemented, but this can only be used to parse XML. As the spec for it requires generating and returning an error document when parsing fails, you may want to use the
parseXmlDocument function instead, which throws in such cases.
The XML parser is non-validating, but does check for well-formedness. It does not support an external DTD or external parsed entities, but does check any internal DTD for syntactic errors. During parsing, any referenced entities are included, default attribute values are materialized and the DTD internal subset is discarded. References to external entities are replaced with nothing. References to parameter entities are ignored.
This library does not implement HTML parsing, which means no
outerHTML properties are read-only. If you need to parse HTML, see this example which shows how to connect the parse5 HTML parser with the help of the dom-treeadapter library.
CSS Selectors and XPath
This library does not implement CSS selectors, which means no
ParentNode and no
Element. This library also does not implement XPath, which means no
XPathEvaluator interfaces and no
To query a slimdom document using XPath or XQuery, use FontoXPath.
HTML & browser-specific features and behavior
Emulating a full browser environment is not the goal of this library. Consider using jsdom instead if you need that.
This implementation offers no special treatment of HTML documents, which means there are no implementations of
HTMLElement and its subclasses. This also affects HTML-specific casing behavior for attributes and tagNames. The
classList properties on
Document have not been implemented. HTML-specific query methods (
getElementById for interface
Element) are also missing.
This library does not currently implement events, including the
EventTarget interfaces. It also currently does not contain an implementation of
AbortSignal. As these may have wider applications than browser-specific use cases, please file an issue if you have a use for these in your application and would like support for them to be added.
There is currently no support for shadow DOM, so no
ShadowRoot interfaces and no
Element. Slimdom also does not support the APIs for custom elements using the
is option on
This library has no notion of URLs (
Document), nor of encodings (
This library omits properties and methods that exist mainly for web compatibility reasons (
XSLTProcessor interface). This also includes all interfaces and interface members listed as historical / removed in the DOM living standard.
The following features are missing simply because I have not yet had, or heard of, a need for them. If you do need one of these, feel free to create a feature request issue or even submit a pull request.
- Iteration helpers (
NodeFilter, and the
attributeFilterfor mutation observers.
Pull requests for missing features or tests, bug reports, questions and other feedback are always welcome! Just open an issue on the github repo, and provide as much detail as you can.
To work on the slimdom library itself, clone the repository and run
npm install to install its dependencies.
This repository includes a full suite of tests based on jest. Run
npm test to run the tests, or
npm run test:debug to debug the tests and code by disabling coverage and enabling the node inspector (see chrome://inspect in Chrome).
A runner for the W3C XML Conformance Test Suites is included in the
test/dom-parsing/xmlConformance.tests.ts file. These tests are used to check that the parser conforms to the specificiations. To run these tests, first execute
npm run download-xmlconf to download the necessary files to the
temp/xmlconf directory. The tests will then be included automatically when running
npm test. Tests for documents that are supposed to be rejected use Jest's snapshots feature to guard against unintentional changes to the errors produced. You may need to update these snapshots when the format of errors changes by running
npm test -- -u.
An experimental runner for the W3C web platform tests is
included in the temporarily unavailable due to the migration to jest. To use it (when re-enabled), clone the web platform tests repository somewhere and set the
WEB_PLATFORM_TESTS_PATH environment variable to the corresponding path. Then run
npm test as normal. The
webPlatform.tests.ts file contains a blacklist of tests that don't currently run due to missing features.