cherry-html
v1.0.2
Published
High-performance HTML parser and DOM manipulation library in Rust
Downloads
378
Maintainers
Readme
<🍒/> cherry-html
cherry-html is a high-performance HTML parser and DOM manipulation library built in Rust using napi-rs for Node.js. It provides a blistering fast native API for manipulating HTML structures, a compatible cheerio-like wrapper for ease of use, and a streaming parser to evaluate CSS selectors on the fly as data arrives!
Features
- Blazing Fast: Uses
html5everandscraperunder the hood. - Native Parser: Parse once and query multiple times with maximum performance.
- Cheerio-like API: An easy, drop-in API designed to mimic the familiar
cheeriointerface while being powered by our Rust backend. - Streaming Parser: Apply CSS selectors directly on an incoming stream of HTML chunks.
Installation
npm install cherry-html1. The Cheerio-like API (Highly Recommended)
If you are coming from cheerio, you can use our API which matches Cheerio's syntax very closely while being backed entirely by the native Rust parser. This gives you the extreme speed of Rust while keeping the syntax you are already familiar with.
const { load } = require('cherry-html/cheerio');
const html = `
<ul id="fruits">
<li class="apple">Apple</li>
<li class="orange">Orange</li>
<li class="pear">Pear</li>
</ul>
`;
const $ = load(html);
// Query elements
console.log($('.apple').text()); // "Apple"
// Manipulate DOM
$('#fruits').append('<li class="plum">Plum</li>');
$('.orange').removeClass('orange').addClass('tangerine');
// Iterate
$('li').each((i, el) => {
console.log($(el).text());
});Available Cheerio Methods
Currently supported:
- Selectors:
$(selector),.find(selector),.parent(),.children(),.eq(index),.first(),.last() - Attributes/Classes:
.attr(name),.attr(name, value),.removeAttr(name),.addClass(name),.removeClass(name) - Manipulation:
.text(),.text(str),.html(),.html(str),.append(str),.prepend(str),.remove() - Iteration:
.each(fn),.map(fn),.toArray()
2. Native API
[!WARNING]
We strongly recommend against using the Native API directly. Thecheerio-like API (Section 1) utilizes advanced Rust thread-locking and batching optimizations that make it significantly faster than the raw Native API.
If you absolutely must skip the convenience API and interact with the raw Rust bindings directly, you can use the native API.
const { parse } = require('cherry-html');
const document = parse('<div class="container"><p>Hello World</p></div>');
// querySelectorAll returns an array of native `Element` objects
const elements = document.querySelectorAll('.container p');
for (const el of elements) {
console.log(el.text()); // "Hello World"
el.setHtml('<b>Updated!</b>');
}Available Native Methods
Document:.querySelectorAll(selector)Element:.text(),.setText(text).html(),.setHtml(html).attr(name),.setAttr(name, value),.removeAttr(name).addClass(name),.removeClass(name).append(html),.prepend(html),.remove().parent(),.children(),.querySelectorAll(selector)
3. Streaming API
Parse and capture elements matching specific selectors as HTML chunks arrive over the network, without keeping the entire document tree in JavaScript memory. The library provides a native Node.js Writable stream wrapper that automatically converts matched elements into cheerio-like objects!
const { createStream } = require('cherry-html/stream');
const fs = require('fs');
// Register the selectors you want to track
const stream = createStream({
selectors: ['.important-data', 'a.external-link']
});
// The 'selectors' event fires when the stream is finished parsing
stream.on('selectors', (results) => {
// `results` is an object mapping selectors to Cheerio-like instances
const importantData = results['.important-data'];
const links = results['a.external-link'];
console.log(importantData.text());
links.each((i, el) => {
console.log(el.attr('href'));
});
});
// Since it's a standard Writable stream, you can pipe any data source into it!
// E.g., from a file:
fs.createReadStream('large-file.html').pipe(stream);
// Or from an HTTP request:
// https.get('https://example.com', (res) => res.pipe(stream));🚧 Coming Soon (Missing Functions)
I am actively developing cherry-html. The following functions and features are currently missing but will be added soon:
- Advanced structural manipulation (
.before(),.after(),.replaceWith(),.empty()) - Sibling traversal (
.next(),.prev(),.siblings()) - Form data serialization (
.serialize(),.val()) - Data attributes handling (
.data()) - More robust and complex CSS pseudo-selectors support in the native engine.
Acknowledgements & Credits
cherry-html stands on the shoulders of giants. A huge thank you to the following open-source projects that make this library possible:
- napi-rs: The incredible framework for building pre-compiled Node.js addons in Rust.
- scraper: The robust HTML parsing and querying library for Rust.
- html5ever: The blazing-fast HTML5 parser developed by the Servo project.
- cheerio: For designing the elegant, jQuery-like API that developers know and love.
License
MIT
