Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš€ Yestee

The fast, lightweight, and modern HTML/XML parser and manipulator.

Zero dependencies. jQuery-like API. Built from scratch.

npm version License: MIT TypeScript


Why Yestee?

Feature Yestee Cheerio JSDOM
Zero Dependencies βœ… ❌ (parse5 + css-select + ...) ❌
Own Parser βœ… Built-in ❌ Wraps parse5/htmlparser2 ❌
Own Selector Engine βœ… Built-in ❌ Wraps css-select ❌
TypeScript Native βœ… βœ… ⚠️
jQuery-like API βœ… βœ… ❌
ESM + CJS βœ… βœ… βœ…
Bundle Size πŸͺΆ Tiny Medium Heavy

Installation

npm install yestee

Quick Start

import { load } from 'yestee';

const $ = load(`
  <html>
    <body>
      <h1 class="title">Hello World</h1>
      <ul id="fruits">
        <li class="fruit">Apple</li>
        <li class="fruit">Orange</li>
        <li class="fruit">Pear</li>
      </ul>
    </body>
  </html>
`);

// Select & extract
$('h1.title').text();              // => 'Hello World'
$('.fruit').first().text();        // => 'Apple'
$('#fruits li').length;            // => 3

// Manipulate
$('h1').text('Hello Yestee!');
$('h1').addClass('welcome');
$('#fruits').append('<li class="fruit">Grape</li>');
$('.fruit').first().remove();

// Render
console.log($.html());

API Reference

Loading

import { load } from 'yestee';

// Load HTML
const $ = load('<div>Hello</div>');

// Load with options
const $ = load('<root><item/></root>', { xml: true });

Selectors

Yestee supports a comprehensive set of CSS selectors:

// Tag, Class, ID
$('div')
$('.class-name')
$('#element-id')

// Attributes
$('[href]')
$('[type="text"]')
$('[href^="https"]')     // starts with
$('[href$=".com"]')      // ends with
$('[href*="example"]')   // contains

// Combinators
$('div p')               // descendant
$('ul > li')             // child
$('h1 + p')              // adjacent sibling
$('h1 ~ p')              // general sibling

// Pseudo-classes
$('li:first-child')
$('li:last-child')
$('li:nth-child(2)')
$('li:nth-child(odd)')
$('li:not(.active)')
$('div:empty')
$(':root')

// Comma groups
$('h1, h2, h3')

// Compound
$('li.active[data-id="1"]:first-child')

Content

// Text
$('p').text();                     // Get text
$('p').text('New text');           // Set text

// HTML
$('div').html();                   // Get inner HTML
$('div').html('<p>New</p>');       // Set inner HTML

// Attributes
$('a').attr('href');               // Get attribute
$('a').attr('href', '/new');       // Set attribute
$('a').attr({ href: '/', target: '_blank' }); // Set multiple
$('a').removeAttr('target');       // Remove attribute

// Data attributes
$('div').data('name');             // Get data-name
$('div').data('name', 'value');    // Set data-name

// Properties
$('p').prop('outerHTML');          // Get outer HTML
$('p').prop('tagName');            // => 'P'

// Value (form elements)
$('input').val();                  // Get value
$('input').val('new value');       // Set value

Classes

$('div').addClass('active');
$('div').addClass('a b c');        // Multiple
$('div').removeClass('active');
$('div').removeClass();            // Remove all
$('div').toggleClass('active');
$('div').hasClass('active');       // => true/false

Traversal

$('div').find('span');             // Find descendants
$('span').parent();                // Direct parent
$('span').parents();               // All ancestors
$('span').parents('div');          // Filtered ancestors
$('span').closest('div');          // Closest ancestor (or self)
$('ul').children();                // Direct children
$('ul').children('.active');       // Filtered children
$('li').siblings();                // Sibling elements
$('li').next();                    // Next element sibling
$('li').next('.special');          // Next matching sibling
$('li').nextAll();                 // All following siblings
$('li').prev();                    // Previous element sibling
$('li').prevAll();                 // All preceding siblings
$('li').first();                   // First in set
$('li').last();                    // Last in set
$('li').eq(2);                     // Element at index
$('li').eq(-1);                    // Last element

Manipulation

$('ul').append('<li>New</li>');    // Append child
$('ul').prepend('<li>First</li>'); // Prepend child
$('p').after('<hr>');              // Insert after
$('p').before('<h2>Title</h2>');   // Insert before
$('span').remove();                // Remove from DOM
$('div').empty();                  // Remove all children
$('old').replaceWith('<new/>');    // Replace element
$('div').wrap('<section></section>'); // Wrap element
$('div').clone();                  // Deep clone

Filtering

$('li').filter('.active');         // Filter by selector
$('li').filter((i, el) => i > 0); // Filter by function
$('li').not('.active');            // Exclude matching
$('li').has('.child');             // Has matching descendant
$('li').is('.active');             // Check if matches
$('li').slice(0, 2);              // Slice collection

Iteration

// Each
$('li').each((index, element) => {
  console.log(index, element.tagName);
});

// Map
const texts = $('li').map((i, el) => $(el).text());

// For...of
for (const el of $('li')) {
  console.log(el.tagName);
}

// To array
const elements = $('li').toArray();

// Length
$('li').length;  // => 3

Rendering

// Full document HTML
$.html();

// Full document XML
$.xml();

// All text content
$.text();

// Root elements
$.root();

Low-Level APIs

Yestee also exposes its internals for advanced use:

import {
  // Parser
  parse,
  parseFragment,
  tokenize,

  // Selector engine
  querySelectorAll,
  querySelector,
  matches,

  // Serializer
  serialize,
  innerHTML,
  outerHTML,
  textContent,

  // DOM utilities
  createElement,
  createTextNode,
  appendChild,
  removeChild,
  cloneNode,
  NodeType,
} from 'yestee';

// Use the tokenizer directly
const tokens = tokenize('<div class="test">Hello</div>');

// Use the parser directly
const doc = parse('<div>Hello</div>');

// Query the DOM directly
const elements = querySelectorAll(doc, '.test');

// Serialize back to HTML
const html = serialize(doc, { pretty: true, indent: '  ' });

Use Cases

  • πŸ•·οΈ Web Scraping β€” Extract data from static HTML
  • πŸ“§ Email Templates β€” Parse and modify HTML emails
  • πŸ” SEO Auditing β€” Extract meta tags, headings, links
  • 🧹 HTML Sanitization β€” Clean user-submitted HTML
  • πŸ—οΈ Static Site Generation β€” Transform HTML during build
  • πŸ“‘ RSS/XML Parsing β€” Process feeds and XML data
  • βœ… Testing β€” Assert HTML structure in unit tests
  • πŸ”„ SSR Post-processing β€” Modify server-rendered output

TypeScript Support

Yestee is written in TypeScript and ships with full type definitions:

import { load, type ElementNode, type Yestee } from 'yestee';

const $ = load('<div>Hello</div>');
const el: ElementNode = $('div').get(0) as ElementNode;

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for details.

# Clone the repo
git clone https://github.com/Sathish27/Yestee.git
cd yestee

# Install dependencies
npm install

# Run tests
npm test

# Build
npm run build

License

MIT Β© Sathish

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages