A super fast Node.js addon for HTML parsing and manipulation, written in Rust. It aims to provide a standard-compliant DOM API for Node.js.
- Standard Compliant: Implements standard DOM APIs including
DOMParser,querySelector,classList, and more, making it easy to migrate from browser-based code. - High-performance DOM parsing and manipulation
- Exposes a simple JavaScript API via NAPI-RS
- Designed for both server-side and CLI HTML processing
- Written in Rust for speed and safety
yarn add @utooland/domparser-rs
# or
npm install @utooland/domparser-rsconst { parse } = require('@utooland/domparser-rs');
const root = parse('<div id="foo" class="bar">hello <span>world</span></div>');
const div = root.select('div');
console.log(div.getAttribute('id')); // "foo"
console.log(div.text()); // "hello world"
div.setAttribute('title', 'my-title');
console.log(div.outerHtml()); // <div id="foo" class="bar" title="my-title">hello <span>world</span></div>Parses an HTML string and returns a NodeRepr instance representing the root node.
Parses a string using the specified MIME type (e.g., "text/html").
Represents a DOM node and provides various manipulation methods.
nodeType: numbernodeName: stringtagName: string | nullnamespaceURI: string | nullprefix: string | nulllocalName: string | nullid: stringclassName: stringparentNode: NodeRepr | nullparentElement: NodeRepr | nullfirstChild: NodeRepr | nulllastChild: NodeRepr | nullpreviousSibling: NodeRepr | nullnextSibling: NodeRepr | nullfirstElementChild: NodeRepr | nulllastElementChild: NodeRepr | nullpreviousElementSibling: NodeRepr | nullnextElementSibling: NodeRepr | nullchildren: NodeRepr[]childElementCount: numbernodeValue: string | nulldata: string | nulltextContent: stringinnerHTML: stringouterHTML: stringownerDocument: NodeRepr | nullchildNodes: NodeRepr[]isConnected: booleandoctype: NodeRepr | nullhead: NodeRepr | nullbody: NodeRepr | nulltitle: stringdocumentElement: NodeRepr | null
append(newChild: NodeRepr): voidappendChild(newChild: NodeRepr): NodeReprprepend(newChild: NodeRepr): voidafter(newSibling: NodeRepr): voidbefore(newSibling: NodeRepr): voidinsertBefore(newNode: NodeRepr, refNode?: NodeRepr | null): NodeReprreplaceChild(newChild: NodeRepr, oldChild: NodeRepr): NodeReprreplaceWith(newNode: NodeRepr): voidremove(): voidclone(): NodeRepr(Shallow clone)cloneRecursive(): NodeRepr(Deep clone)cloneNode(deep?: boolean): NodeReprimportNode(externalNode: NodeRepr, deep?: boolean): NodeRepradoptNode(externalNode: NodeRepr): NodeReprnormalize(): void
getAttribute(name: string): string | nullsetAttribute(name: string, value: string): voidremoveAttribute(name: string): voidtoggleAttribute(name: string, force?: boolean): booleanhasAttribute(name: string): booleangetAttributeNames(): string[]getAttributes(): Record<string, string>getAttributeNS(namespace: string | null, localName: string): string | nullsetAttributeNS(namespace: string | null, name: string, value: string): voidremoveAttributeNS(namespace: string | null, localName: string): voidhasAttributeNS(namespace: string | null, localName: string): boolean
select(selectors: string): NodeRepr | nullselectAll(selectors: string): NodeRepr[]querySelector(selectors: string): NodeRepr | nullquerySelectorAll(selectors: string): NodeRepr[]getElementById(id: string): NodeRepr | nullgetElementsByClassName(classNames: string): NodeRepr[]getElementsByTagName(tagName: string): NodeRepr[]matches(selectors: string): booleanclosest(selectors: string): NodeRepr | nullcontains(otherNode: NodeRepr): boolean
classListAdd(className: string): voidclassListRemove(className: string): voidclassListToggle(className: string, force?: boolean): booleanclassListContains(className: string): booleandatasetGet(): Record<string, string>datasetSet(key: string, value: string): voiddatasetRemove(key: string): void
text(): stringinnerHtml(): stringouterHtml(): stringcreateElement(tagName: string): NodeReprcreateTextNode(data: string): NodeReprcreateComment(data: string): NodeReprcreateDocumentFragment(): NodeReprcreateProcessingInstruction(target: string, data: string): NodeReprisSameNode(otherNode: NodeRepr): booleanisEqualNode(otherNode: NodeRepr): booleancompareDocumentPosition(other: NodeRepr): numberlookupPrefix(namespace?: string): string | nulllookupNamespaceURI(prefix?: string): string | nullisDefaultNamespace(namespace?: string): booleangetRootNode(): NodeReprhasChildNodes(): booleanhasAttributes(): boolean
splitText(offset: number): NodeReprsubstringData(offset: number, count: number): stringappendData(data: string): voidinsertData(offset: number, data: string): voiddeleteData(offset: number, count: number): voidreplaceData(offset: number, count: number, data: string): void
insertAdjacentElement(position: string, element: NodeRepr): NodeRepr | nullinsertAdjacentText(position: string, data: string): voidinsertAdjacentHTML(position: string, html: string): void
npm install
npm run build
npm testnpm run benchmarkFor more usage examples and advanced API, see the source code and benchmarks in the repository.