๐ฑ Lightweight offline DOM
npm install zeed-dom> A modern, lightweight, TypeScript virtual DOM for Node.js, browser, and static content generation.
---
- โก๏ธ Fast: Efficient HTML parsing and serialization
- ๐งฉ JSX Compatible: Works seamlessly with JSX/TSX
- ๐ CSS Selectors: Query with a subset of CSS selectors
- ๐ Easy Manipulation: Chainable API, .handle() helper, and more
- ๐ HTML, XML, Markdown, Plaintext: Serialize to multiple formats
- ๐งน Pretty Print: Tidy up HTML with tidyDOM
- ๐ฆพ TypeScript: Full typings, modern codebase
- ๐ Safe HTML: Output sanitized HTML for user content
Note: This project does not aim for full browser DOM completeness, but covers most practical use cases for static content, SSR, and offline DOM manipulation.
---
``sh`
npm i zeed-dom
- zeed โ Foundation library
- zerva โ Event-driven server
> Used by TipTap in its html-package.
---
- Virtual DOM tree with VNode, VElement, VDocument, etc.serializeSafeHTML
- HTML parsing and serialization
- XML output support
- CSS selector engine (subset)
- JSX/TSX support (see below)
- Safe HTML serialization ().handle()
- Markdown and plaintext serialization
- Manipulation helpers: , .replaceWith(), .remove(), etc.tidyDOM
- Works in Node.js, browser, and serverless
- Pretty print HTML ()
- TypeScript-first API
---
Drop in HTML, query, and change it. Returns HTML again. Great for post-processing:
`ts
import { handleHTML } from 'zeed-dom'
const newHTML = handleHTML(html, (document) => {
const img = document.querySelector('.img-wrapper img')
if (img)
img.setAttribute('title', img.getAttribute('src'))
})
`
Take any HTML node or document and serialize it to another format:
- serializePlaintext(node): Readable and searchable plain textserializeMarkdown(node)
- : Simple MarkdownserializeSafeHTML(node)
- or safeHTML(htmlString): Allow only basic tags and attributes
`js
import { h, xml } from 'zeed-dom'
const dom = h(
'ol',
{ class: 'projects' },
[
h('li', null, 'zeed ', h('img', { src: 'logo.png' })),
h('li', null, 'zeed-dom'),
]
)
console.log(dom.render())
//

console.log(dom.render(xml))
//

$3
`jsx
import { h } from 'zeed-dom'let dom = (
- zeed
- zeed-dom
)dom.handle('li', (e) => {
if (!e.textContent.endsWith('-dom')) {
e.remove()
} else {
e.innerHTML = 'zeed-dom - great DOM helper for static content'
}
})
console.log(dom.render())
//
- zeed-dom - great DOM helper for static content
`$3
`js
import { tidyDOM, vdom } from 'zeed-dom'const dom = vdom('
Hello World')
tidyDOM(dom)
console.log(dom.render())
// Output is pretty printed like:
//
// Hello World
//
`---
โ๏ธ JSX Setup
JSX is supported out of the box. For TypeScript, add to your
tsconfig.json:`json
{
"compilerOptions": {
"jsx": "react",
"jsxFactory": "h"
}
}
`Add this to your
shims.d.ts:`ts
// https://www.typescriptlang.org/docs/handbook/jsx.html#intrinsic-elements
declare namespace JSX {
interface IntrinsicElements {
[elemName: string]: any
}
}
`For ESBuild:
`js
{
jsxFactory: 'h'
}
`Or as a CLI option:
--jsx-factory=hFor browser DOM:
`js
const { hFactory } = require('zeed-dom')
export const h = hFactory({ document })
`---
๐งช API Highlights
-
vdom(htmlString): Parse HTML to virtual DOM
- tidyDOM(node): Pretty print/format DOM
- serializeSafeHTML(node): Output safe HTML
- serializeMarkdown(node): Output Markdown
- serializePlaintext(node): Output plain text
- handleHTML(html, fn): Manipulate HTML with a callback
- VElement, VNode, VDocument, etc.: Core classes
- .handle(selector, fn): Manipulate elements by selector
- .querySelector, .querySelectorAll: CSS selector queries
- .replaceWith(), .remove(), .setAttribute(), etc.: DOM-like methods---
๐ฆ Performance
The parser is fast, as shown in htmlparser-benchmark
---
๐ Misc
- Use double underscore in JSX for namespaces:
โ
- Use CDATA helper for raw data:
- style attributes can be objects: โ `