Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

cherio

btele4kMIT1.0.0-rc.2

Elegant implementation of core jQuery designed for the server

htmlparser, jquery, selector, scraper, parser, html

readme

cheerio

Implementation of core jQuery designed specifically for the server.

const cheerio = require('cherio')
const $ = cheerio.load('<h2 class="title">Hello world</h2>')

$('h2.title').text('Hello there!')
$('h2').addClass('welcome')

$.html()
//=> <html><head></head><body><h2 class="title welcome">Hello there!</h2></body></html>

Installation

npm install cheerio

Features

❤ Familiar syntax: Cheerio implements a subset of core jQuery. Cheerio removes all the DOM inconsistencies and browser cruft from the jQuery library, revealing its truly gorgeous API.

ϟ Blazingly fast: Cheerio works with a very simple, consistent DOM model. As a result parsing, manipulating, and rendering are incredibly efficient. Preliminary end-to-end benchmarks suggest that cheerio is about 8x faster than JSDOM.

❁ Incredibly flexible: Cheerio wraps around parse5 parser and can optionally use @FB55's forgiving htmlparser2. Cheerio can parse nearly any HTML or XML document.

Cheerio is not a web browser

Cheerio parses markup and provides an API for traversing/manipulating the resulting data structure. It does not interpret the result as a web browser does. Specifically, it does not produce a visual rendering, apply CSS, load external resources, or execute JavaScript. If your use case requires any of this functionality, you should consider projects like PhantomJS or JSDom.

API

Markup example we'll be using:

<ul id="fruits">
  <li class="apple">Apple</li>
  <li class="orange">Orange</li>
  <li class="pear">Pear</li>
</ul>

This is the HTML markup we will be using in all of the API examples.

Loading

First you need to load in the HTML. This step in jQuery is implicit, since jQuery operates on the one, baked-in DOM. With Cheerio, we need to pass in the HTML document.

This is the preferred method:

const cheerio = require('cheerio');
const $ = cheerio.load('<ul id="fruits">...</ul>');

Optionally, you can also load in the HTML by passing the string as the context:

const $ = require('cheerio');
$('ul', '<ul id="fruits">...</ul>');

Or as the root:

const $ = require('cheerio');
$('li', 'ul', '<ul id="fruits">...</ul>');

If you need to modify parsing options for XML input, you may pass an extra object to .load():

const $ = cheerio.load('<ul id="fruits">...</ul>', {
    xml: {
      normalizeWhitespace: true,
    }
});

The options in the xml object are taken directly from htmlparser2, therefore any options that can be used in htmlparser2 are valid in cheerio as well. The default options are:

{
    withDomLvl1: true,
    normalizeWhitespace: false,
    xmlMode: true,
    decodeEntities: true
}

For a full list of options and their effects, see this and htmlparser2's options.

Some users may wish to parse markup with the htmlparser2 library, and traverse/manipulate the resulting structure with Cheerio. This may be the case for those upgrading from pre-1.0 releases of Cheerio (which relied on htmlparser2), for those dealing with invalid markup (because htmlparser2 is more forgiving), or for those operating in performance-critical situations (because htmlparser2 may be faster in some cases). Note that "more forgiving" means htmlparser2 has error-correcting mechanisms that aren't always a match for the standards observed by web browsers. This behavior may be useful when parsing non-HTML content.

To support these cases, load also accepts a htmlparser2-compatible data structure as its first argument. Users may install htmlparser2, use it to parse input, and pass the result to load:

// Usage as of htmlparser2 version 3:
const htmlparser2 = require('htmlparser2');
const dom = htmlparser2.parseDOM(document, options);

const $ = cheerio.load(dom);

Selectors

Cheerio's selector implementation is nearly identical to jQuery's, so the API is very similar.

$( selector, [context], [root] )

selector searches within the context scope which searches within the root scope. selector and context can be a string expression, DOM Element, array of DOM elements, or cheerio object. root is typically the HTML document string.

This selector method is the starting point for traversing and manipulating the document. Like jQuery, it's the primary method for selecting elements in the document, but unlike jQuery it's built on top of the CSSSelect library, which implements most of the Sizzle selectors.

$('.apple', '#fruits').text()
//=> Apple

$('ul .pear').attr('class')
//=> pear

$('li[class=orange]').html()
//=> Orange

Attributes

Methods for getting and modifying attributes.

.attr( name, value )

Method for getting and setting attributes. Gets the attribute value for only the first element in the matched set. If you set an attribute's value to null, you remove that attribute. You may also pass a map and function like jQuery.

$('ul').attr('id')
//=> fruits

$('.apple').attr('id', 'favorite').html()
//=> <li class="apple" id="favorite">Apple</li>

See http://api.jquery.com/attr/ for more information

.prop( name, value )

Method for getting and setting properties. Gets the property value for only the first element in the matched set.

$('input[type="checkbox"]').prop('checked')
//=> false

$('input[type="checkbox"]').prop('checked', true).val()
//=> ok

See http://api.jquery.com/prop/ for more information

.data( name, value )

Method for getting and setting data attributes. Gets or sets the data attribute value for only the first element in the matched set.

$('<div data-apple-color="red"></div>').data()
//=> { appleColor: 'red' }

$('<div data-apple-color="red"></div>').data('apple-color')
//=> 'red'

const apple = $('.apple').data('kind', 'mac')
apple.data('kind')
//=> 'mac'

See http://api.jquery.com/data/ for more information

.val( [value] )

Method for getting and setting the value of input, select, and textarea. Note: Support for map, and function has not been added yet.

$('input[type="text"]').val()
//=> input_text

$('input[type="text"]').val('test').html()
//=> <input type="text" value="test"/>

.removeAttr( name )

Method for removing attributes by name.

$('.pear').removeAttr('class').html()
//=> <li>Pear</li>

.hasClass( className )

Check to see if any of the matched elements have the given className.

$('.pear').hasClass('pear')
//=> true

$('apple').hasClass('fruit')
//=> false

$('li').hasClass('pear')
//=> true

.addClass( className )

Adds class(es) to all of the matched elements. Also accepts a function like jQuery.

$('.pear').addClass('fruit').html()
//=> <li class="pear fruit">Pear</li>

$('.apple').addClass('fruit red').html()
//=> <li class="apple fruit red">Apple</li>

See http://api.jquery.com/addClass/ for more information.

.removeClass( [className] )

Removes one or more space-separated classes from the selected elements. If no className is defined, all classes will be removed. Also accepts a function like jQuery.

$('.pear').removeClass('pear').html()
//=> <li class="">Pear</li>

$('.apple').addClass('red').removeClass().html()
//=> <li class="">Apple</li>

See http://api.jquery.com/removeClass/ for more information.

.toggleClass( className, [switch] )

Add or remove class(es) from the matched elements, depending on either the class's presence or the value of the switch argument. Also accepts a function like jQuery.

$('.apple.green').toggleClass('fruit green red').html()
//=> <li class="apple fruit red">Apple</li>

$('.apple.green').toggleClass('fruit green red', true).html()
//=> <li class="apple green fruit red">Apple</li>

See http://api.jquery.com/toggleClass/ for more information.

.is( selector )

.is( element )

.is( selection )

.is( function(index) )

Checks the current list of elements and returns true if any of the elements match the selector. If using an element or Cheerio selection, returns true if any of the elements match. If using a predicate function, the function is executed in the context of the selected element, so this refers to the current element.

Forms

.serializeArray()

Encode a set of form elements as an array of names and values.

$('<form><input name="foo" value="bar" /></form>').serializeArray()
//=> [ { name: 'foo', value: 'bar' } ]

Traversing

.find(selector)

.find(selection)

.find(node)

Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element.

$('#fruits').find('li').length
//=> 3
$('#fruits').find($('.apple')).length
//=> 1

.parent([selector])

Get the parent of each element in the current set of matched elements, optionally filtered by a selector.

$('.pear').parent().attr('id')
//=> fruits

.parents([selector])

Get a set of parents filtered by selector of each element in the current set of match elements.

$('.orange').parents().length
// => 2
$('.orange').parents('#fruits').length
// => 1

.parentsUntil([selector][,filter])

Get the ancestors of each element in the current set of matched elements, up to but not including the element matched by the selector, DOM node, or cheerio object.

$('.orange').parentsUntil('#food').length
// => 1

.closest(selector)

For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.

$('.orange').closest()
// => []
$('.orange').closest('.apple')
// => []
$('.orange').closest('li')
// => [<li class="orange">Orange</li>]
$('.orange').closest('#fruits')
// => [<ul id="fruits"> ... </ul>]

.next([selector])

Gets the next sibling of the first selected element, optionally filtered by a selector.

$('.apple').next().hasClass('orange')
//=> true

.nextAll([selector])

Gets all the following siblings of the first selected element, optionally filtered by a selector.

$('.apple').nextAll()
//=> [<li class="orange">Orange</li>, <li class="pear">Pear</li>]
$('.apple').nextAll('.orange')
//=> [<li class="orange">Orange</li>]

.nextUntil([selector], [filter])

Gets all the following siblings up to but not including the element matched by the selector, optionally filtered by another selector.

$('.apple').nextUntil('.pear')
//=> [<li class="orange">Orange</li>]

.prev([selector])

Gets the previous sibling of the first selected element optionally filtered by a selector.

$('.orange').prev().hasClass('apple')
//=> true

.prevAll([selector])

Gets all the preceding siblings of the first selected element, optionally filtered by a selector.

$('.pear').prevAll()
//=> [<li class="orange">Orange</li>, <li class="apple">Apple</li>]
$('.pear').prevAll('.orange')
//=> [<li class="orange">Orange</li>]

.prevUntil([selector], [filter])

Gets all the preceding siblings up to but not including the element matched by the selector, optionally filtered by another selector.

$('.pear').prevUntil('.apple')
//=> [<li class="orange">Orange</li>]

.slice( start, [end] )

Gets the elements matching the specified range

$('li').slice(1).eq(0).text()
//=> 'Orange'

$('li').slice(1, 2).length
//=> 1

.siblings([selector])

Gets the first selected element's siblings, excluding itself.

$('.pear').siblings().length
//=> 2

$('.pear').siblings('.orange').length
//=> 1

.children([selector])

Gets the children of the first selected element.

$('#fruits').children().length
//=> 3

$('#fruits').children('.pear').text()
//=> Pear

.contents()

Gets the children of each element in the set of matched elements, including text and comment nodes.

$('#fruits').contents().length
//=> 3

.each( function(index, element) )

Iterates over a cheerio object, executing a function for each matched element. When the callback is fired, the function is fired in the context of the DOM element, so this refers to the current element, which is equivalent to the function parameter element. To break out of the each loop early, return with false.

const fruits = [];

$('li').each(function(i, elem) {
  fruits[i] = $(this).text();
});

fruits.join(', ');
//=> Apple, Orange, Pear

.map( function(index, element) )

Pass each element in the current matched set through a function, producing a new Cheerio object containing the return values. The function can return an individual data item or an array of data items to be inserted into the resulting set. If an array is returned, the elements inside the array are inserted into the set. If the function returns null or undefined, no element will be inserted.

$('li').map(function(i, el) {
  // this === el
  return $(this).text();
}).get().join(' ');
//=> "apple orange pear"

.filter( selector )
.filter( selection )
.filter( element )
.filter( function(index, element) )

Iterates over a cheerio object, reducing the set of selector elements to those that match the selector or pass the function's test. When a Cheerio selection is specified, return only the elements contained in that selection. When an element is specified, return only that element (if it is contained in the original selection). If using the function method, the function is executed in the context of the selected element, so this refers to the current element.

Selector:

$('li').filter('.orange').attr('class');
//=> orange

Function:

$('li').filter(function(i, el) {
  // this === el
  return $(this).attr('class') === 'orange';
}).attr('class')
//=> orange

.not( selector )
.not( selection )
.not( element )
.not( function(index, elem) )

Remove elements from the set of matched elements. Given a jQuery object that represents a set of DOM elements, the .not() method constructs a new jQuery object from a subset of the matching elements. The supplied selector is tested against each element; the elements that don't match the selector will be included in the result. The .not() method can take a function as its argument in the same way that .filter() does. Elements for which the function returns true are excluded from the filtered set; all other elements are included.

Selector:

$('li').not('.apple').length;
//=> 2

Function:

$('li').not(function(i, el) {
  // this === el
  return $(this).attr('class') === 'orange';
}).length;
//=> 2

.has( selector )
.has( element )

Filters the set of matched elements to only those which have the given DOM element as a descendant or which have a descendant that matches the given selector. Equivalent to .filter(':has(selector)').

Selector:

$('ul').has('.pear').attr('id');
//=> fruits

Element:

$('ul').has($('.pear')[0]).attr('id');
//=> fruits

.first()

Will select the first element of a cheerio object

$('#fruits').children().first().text()
//=> Apple

.last()

Will select the last element of a cheerio object

$('#fruits').children().last().text()
//=> Pear

.eq( i )

Reduce the set of matched elements to the one at the specified index. Use .eq(-i) to count backwards from the last selected element.

$('li').eq(0).text()
//=> Apple

$('li').eq(-1).text()
//=> Pear

.get( [i] )

Retrieve the DOM elements matched by the Cheerio object. If an index is specified, retrieve one of the elements matched by the Cheerio object:

$('li').get(0).tagName
//=> li

If no index is specified, retrieve all elements matched by the Cheerio object:

$('li').get().length
//=> 3

.index()

.index( selector )

.index( nodeOrSelection )

Search for a given element from among the matched elements.

$('.pear').index()
//=> 2
$('.orange').index('li')
//=> 1
$('.apple').index($('#fruit, li'))
//=> 1

.end()

End the most recent filtering operation in the current chain and return the set of matched elements to its previous state.

$('li').eq(0).end().length
//=> 3

.add( selector [, context] )

.add( element )

.add( elements )

.add( html )

.add( selection )

Add elements to the set of matched elements.

$('.apple').add('.orange').length
//=> 2

.addBack( [filter] )

Add the previous set of elements on the stack to the current set, optionally filtered by a selector.

$('li').eq(0).addBack('.orange').length
//=> 2

Manipulation

Methods for modifying the DOM structure.

.append( content, [content, ...] )

Inserts content as the last child of each of the selected elements.

$('ul').append('<li class="plum">Plum</li>')
$.html()
//=>  <ul id="fruits">
//      <li class="apple">Apple</li>
//      <li class="orange">Orange</li>
//      <li class="pear">Pear</li>
//      <li class="plum">Plum</li>
//    </ul>

.appendTo( target )

Insert every element in the set of matched elements to the end of the target.

$('<li class="plum">Plum</li>').appendTo('#fruits')
$.html()
//=>  <ul id="fruits">
//      <li class="apple">Apple</li>
//      <li class="orange">Orange</li>
//      <li class="pear">Pear</li>
//      <li class="plum">Plum</li>
//    </ul>

.prepend( content, [content, ...] )

Inserts content as the first child of each of the selected elements.

$('ul').prepend('<li class="plum">Plum</li>')
$.html()
//=>  <ul id="fruits">
//      <li class="plum">Plum</li>
//      <li class="apple">Apple</li>
//      <li class="orange">Orange</li>
//      <li class="pear">Pear</li>
//    </ul>

.prependTo( target )

Insert every element in the set of matched elements to the beginning of the target.

$('<li class="plum">Plum</li>').prependTo('#fruits')
$.html()
//=>  <ul id="fruits">
//      <li class="plum">Plum</li>
//      <li class="apple">Apple</li>
//      <li class="orange">Orange</li>
//      <li class="pear">Pear</li>
//    </ul>

.after( content, [content, ...] )

Insert content next to each element in the set of matched elements.

$('.apple').after('<li class="plum">Plum</li>')
$.html()
//=>  <ul id="fruits">
//      <li class="apple">Apple</li>
//      <li class="plum">Plum</li>
//      <li class="orange">Orange</li>
//      <li class="pear">Pear</li>
//    </ul>

.insertAfter( target )

Insert every element in the set of matched elements after the target.

$('<li class="plum">Plum</li>').insertAfter('.apple')
$.html()
//=>  <ul id="fruits">
//      <li class="apple">Apple</li>
//      <li class="plum">Plum</li>
//      <li class="orange">Orange</li>
//      <li class="pear">Pear</li>
//    </ul>

.before( content, [content, ...] )

Insert content previous to each element in the set of matched elements.

$('.apple').before('<li class="plum">Plum</li>')
$.html()
//=>  <ul id="fruits">
//      <li class="plum">Plum</li>
//      <li class="apple">Apple</li>
//      <li class="orange">Orange</li>
//      <li class="pear">Pear</li>
//    </ul>

.insertBefore( target )

Insert every element in the set of matched elements before the target.

$('<li class="plum">Plum</li>').insertBefore('.apple')
$.html()
//=>  <ul id="fruits">
//      <li class="plum">Plum</li>
//      <li class="apple">Apple</li>
//      <li class="orange">Orange</li>
//      <li class="pear">Pear</li>
//    </ul>

.remove( [selector] )

Removes the set of matched elements from the DOM and all their children. selector filters the set of matched elements to be removed.

$('.pear').remove()
$.html()
//=>  <ul id="fruits">
//      <li class="apple">Apple</li>
//      <li class="orange">Orange</li>
//    </ul>

.replaceWith( content )

Replaces matched elements with content.

const plum = $('<li class="plum">Plum</li>')
$('.pear').replaceWith(plum)
$.html()
//=> <ul id="fruits">
//     <li class="apple">Apple</li>
//     <li class="orange">Orange</li>
//     <li class="plum">Plum</li>
//   </ul>

.empty()

Empties an element, removing all its children.

$('ul').empty()
$.html()
//=>  <ul id="fruits"></ul>

.html( [htmlString] )

Gets an html content string from the first selected element. If htmlString is specified, each selected element's content is replaced by the new content.

$('.orange').html()
//=> Orange

$('#fruits').html('<li class="mango">Mango</li>').html()
//=> <li class="mango">Mango</li>

.text( [textString] )

Get the combined text contents of each element in the set of matched elements, including their descendants. If textString is specified, each selected element's content is replaced by the new text content.

$('.orange').text()
//=> Orange

$('ul').text()
//=>  Apple
//    Orange
//    Pear

.wrap( content )

The .wrap() function can take any string or object that could be passed to the $() factory function to specify a DOM structure. This structure may be nested several levels deep, but should contain only one inmost element. A copy of this structure will be wrapped around each of the elements in the set of matched elements. This method returns the original set of elements for chaining purposes.

const redFruit = $('<div class="red-fruit"></div>')
$('.apple').wrap(redFruit)

//=> <ul id="fruits">
//     <div class="red-fruit">
//      <li class="apple">Apple</li>
//     </div>
//     <li class="orange">Orange</li>
//     <li class="plum">Plum</li>
//   </ul>

const healthy = $('<div class="healthy"></div>')
$('li').wrap(healthy)

//=> <ul id="fruits">
//     <div class="healthy">
//       <li class="apple">Apple</li>
//     </div>
//     <div class="healthy">
//       <li class="orange">Orange</li>
//     </div>
//     <div class="healthy">
//        <li class="plum">Plum</li>
//     </div>
//   </ul>

.css( [propertName] )
.css( [ propertyNames] )
.css( [propertyName], [value] )
.css( [propertName], [function] )
.css( [properties] )

Get the value of a style property for the first element in the set of matched elements or set one or more CSS properties for every matched element.

Rendering

When you're ready to render the document, you can use the html utility function:

$.html()
//=>  <ul id="fruits">
//      <li class="apple">Apple</li>
//      <li class="orange">Orange</li>
//      <li class="pear">Pear</li>
//    </ul>

If you want to return the outerHTML you can use $.html(selector):

$.html('.pear')
//=> <li class="pear">Pear</li>

By default, html will leave some tags open. Sometimes you may instead want to render a valid XML document. For example, you might parse the following XML snippet:

const $ = cheerio.load('<media:thumbnail url="http://www.foo.com/keyframe.jpg" width="75" height="50" time="12:05:01.123"/>');

... and later want to render to XML. To do this, you can use the 'xml' utility function:

$.xml()
//=>  <media:thumbnail url="http://www.foo.com/keyframe.jpg" width="75" height="50" time="12:05:01.123"/>

You may also render the text content of a Cheerio object using the text static method:

const $ = cheerio.load('This is <em>content</em>.')
$.text()
//=> This is content.

The method may be called on the Cheerio module itself--be sure to pass a collection of nodes!

const $ = cheerio.load('<div>This is <em>content</em>.</div>')
cheerio.text($('div'))
//=> This is content.

Miscellaneous

DOM element methods that don't fit anywhere else

.toArray()

Retrieve all the DOM elements contained in the jQuery set as an array.

$('li').toArray()
//=> [ {...}, {...}, {...} ]

.clone()

Clone the cheerio object.

const moreFruit = $('#fruits').clone()

Utilities

$.root

Sometimes you need to work with the top-level root element. To query it, you can use $.root().

$.root().append('<ul id="vegetables"></ul>').html();
//=> <ul id="fruits">...</ul><ul id="vegetables"></ul>

$.contains( container, contained )

Checks to see if the contained DOM element is a descendant of the container DOM element.

$.parseHTML( data [, context ] [, keepScripts ] )

Parses a string into an array of DOM nodes. The context argument has no meaning for Cheerio, but it is maintained for API compatability.

$.load( html[, options ] )

Create a querying function, bound to a document created from the provided markup. Note that similar to web browser contexts, this operation may introduce <html>, <head>, and <body> elements. See the previous section titled "Loading" for usage information.

Plugins

Once you have loaded a document, you may extend the prototype or the equivalent fn property with custom plugin methods:

const $ = cheerio.load('<html><body>Hello, <b>world</b>!</body></html>');
$.prototype.logHtml = function() {
  console.log(this.html());
};

$('body').logHtml(); // logs "Hello, <b>world</b>!" to the console

The "DOM Node" object

Cheerio collections are made up of objects that bear some resemblence to browser-based DOM nodes. You can expect them to define the following properties:

  • tagName
  • parentNode
  • previousSibling
  • nextSibling
  • nodeValue
  • firstChild
  • childNodes
  • lastChild
make setup
make test

This will download the development packages and run the test suite.

License

MIT

changelog

1.0.0-rc.2 / 2017-07-02

This release changes Cheerio's default parser to the Parse5 HTML parser. Parse5 is an excellent project that rigorously conforms to the HTML standard. It does not support XML, so Cheerio continues to use htmlparser2 when working with XML documents.

This switch addresses many long-standing bugs in Cheerio, but some users may experience slower behavior in performance-critical applications. In addition, htmlparser2 is more forgiving of invalid markup which can be useful when input sourced from a third party and cannot be corrected. For these reasons, the load method also accepts a DOM structure as produced by the htmlparser2 library. See the project's "readme" file for more details on this usage pattern.

Migrating from version 0.x

cheerio.load( html[, options ] )` This method continues to produce jQuery-like functions, bound to the provided input text. In prior releases, the provided string was interpreted as a document fragment. This meant that in a statement such as:

var $ = cheerio.load('<p>Hello, <b>world</b>!</p>');

The resulting $ function would operate on a tree whose root element was a paragraph tag.

With this release of Cheerio, strings provided to the load method are interpreted as documents. The same example will produce a $ function that operates on a full HTML document, including an <html> document element with nested <head> and <body> tags. This mimics web browser behavior much more closely, but may require alterations to existing code. To work with fragments, first load an empty document, and then use the resulting $ to parse the input:

var $ = cheerio.load('');
var $fragment = $('<p>Hello, <b>world</b>!</p>');
  • Update History.md (and include migration guide) (Mike Pennisi)
  • Rename useHtmlParser2 option (Mike Pennisi)
  • Remove documentation for xmlMode option (Mike Pennisi)
  • Document advanced usage with htmlparser2 (Mike Pennisi)
  • Correct errors in Readme.md (Mike Pennisi)
  • Improve release process (Mike Pennisi)
  • 1.0.0-rc.1 (Mike Pennisi)
  • Update unit test (Mike Pennisi)
  • Normalize code style (Mike Pennisi)
  • Added support for nested wrapping. (Diane Looney)
  • Add nested wrapping test (Toni Helenius)
  • Added $.merge following the specification at https://api.jquery.com/jquery.merge/ Added test cases for $.merge (Diane Looney)
  • Clarify project scope in README file (Mike Pennisi)
  • .text() ignores script and style tags (#1018) (Haleem Assal)
  • Test suite housekeeping (#1016) (DianeLooney)
  • experiment with a job board (Matthew)
  • Change options format (inikulin)
  • Add test for #997 (inikulin)
  • Update .filter function docs. (Konstantin)
  • Standardise readme on ES6 variable declarations (Dekatron)
  • Use documents via $.load (inikulin)
  • Use parse5 as a default parser (closes #863) (inikulin)
  • Fix small typo in Readme (Darren Scerri)
  • Report test failures in CI (Mike Pennisi)
  • serializeArray should not ignore input elements without value attributes (Ricardo Gladwell)
  • Disallow variable shadowing (Mike Pennisi)
  • Update hasClass method (sufisaid)
  • Added MIT License fixes #902 (Prasanth Vaaheeswaran)
  • chore(package): update dependencies (greenkeeper[bot])
  • Use modular lodash package (#913) (Billy Janitsch)

0.22.0 / 2016-08-23

  • Return undefined in .prop if given an invalid element or tag (#880)
  • Merge pull request #884 from cheeriojs/readme-cleanup
  • readme updates
  • Merge pull request #881 from piamancini/patch-1
  • Added backers and sponsors from OpenCollective
  • Use jQuery from the jquery module in benchmarks (#871)
  • Document, test, and extend static $.text method (#855)
  • Fix typo on calling _.extend (#861)
  • Update versions (#870)
  • Use individual lodash functions (#864)
  • Added .serialize() support. Fixes #69 (#827)
  • Update Readme.md (#857)
  • add extension for JSON require call
  • remove gittask badge
  • Merge pull request #672 from underdogio/dev/checkbox.radio.values.sqwished
  • Added default value for checkboxes/radios

0.20.0 / 2016-02-01

  • Add coveralls badge, remove link to old report (Felix Böhm)
  • Update lodash dependeny to 4.1.0 (leif.hanack)
  • Fix PR #726 adding 'appendTo()' and 'prependTo()' (Delgan)
  • Added appendTo and prependTo with tests #641 (digihaven)
  • Fix #780 by changing options context in '.find()' (Felix Böhm)
  • Add an unit test checking the query of child (Delgan)
  • fix #667: attr({foo: null}) removes attribute foo, like attr('foo', null) (Ray Waldin)
  • Include reference to dedicated "Loading" section (Mike Pennisi)
  • Added load method to $ (alanev)
  • update css-select to 1.2.0 (Felix Böhm)
  • Fixing Grammatical Error (Dan Corman)
  • Test against node v0.12 --> v4.2 (Jason Kurian)
  • Correct output in example (Felix Böhm)
  • Fix npm files filter (Bogdan Chadkin)
  • Enable setting data on all elements in selection (Mike Pennisi)
  • Reinstate $.fn.toArray (Mike Pennisi)
  • update css-select to 1.1.0 (Thomas Shafer)
  • Complete implementation of wrap (Mike Pennisi)
  • Correct name of unit test (Mike Pennisi)
  • Correct grammar in test titles (Mike Pennisi)
  • Normalize whitespace (Mike Pennisi)
  • Insert omitted assertion (Mike Pennisi)
  • Update invocation of children (Mike Pennisi)
  • Begin implementation of wrap method (Dandlezzz)
  • Update Readme.md (Sven Slootweg)
  • fix document's mistake in Readme.md (exoticknight)
  • Add tests for setting text and html as non-strings (Ryc O'Chet)
  • Fix for passing non-string values to .html or .text (Ryc O'Chet)
  • use a selector to filter form elements (fb55)
  • fix README.md typo (Yutian Li)
  • README: fix spelling (Chris Rebert)
  • Added support for options without a value attribute. Fixes #633 (Todd Wolfson)
  • responding to pull request feedback - remove item() method and related tests (Ray Waldin)
  • add length property and item method to object returned by prop('style'), plus tests (Ray Waldin)
  • Added .prop method to readme (Artem Burtsev)
  • Added .prop method (Artem Burtsev)
  • Added Gitter badge (The Gitter Badger)

0.19.0 / 2015-03-21

  • fixed allignment (fb55)
  • added test case for malformed json in data attributes (fb55)
  • fix: handle some extreme cases like data-custom="{{templatevar}}". There is possibility error while parsing json . (Harish.K)
  • Add missing optional selector doc for {prev,next}{All,Until} (Jérémie Astori)
  • update to dom-serializer@0.1.0 (Felix Böhm)
  • Document Cheerio#serialzeArray (Mike Pennisi)
  • Fixed up serializeArray() and added multiple support (Todd Wolfson)
  • Implement serializeArray() (Jarno Leppänen)
  • recognize options in $.xml() (fb55)
  • lib/static.js: text(): rm errant space before ++ (Chris Rebert)
  • Do not expose internal children array (Mike Pennisi)
  • Change lodash dependencies to ^3.1.0 (Samy Pessé)
  • Update lodash@3.1.0 (Samy Pessé)
  • Updates Readme.md: .not(function (index, elem)) (Patrick Ward)
  • update to css-select@1.0.0 (fb55)
  • Allow failures in Node.js v0.11 (Mike Pennisi)
  • Added: Gittask badge (Matthew Mueller)
  • Isolate prototypes of functions created via load (Mike Pennisi)
  • Updates Readme.md: adds JS syntax highlighting (frankcash)
  • 608 -- Add support for insertBefore/insertAfter syntax. Supports target types of: $, [$], selector (both single and multiple results) (Ben Cochran)

  • Clone input nodes when inserting over a set (Mike Pennisi)
  • Move unit test files (Mike Pennisi)
  • remove unnecessarily tricky code (David Chambers)
  • pass options to $.html in toString (fb55)
  • add license info to package.json (Chris Rebert)
  • xyz@~0.5.0 (David Chambers)
  • Remove unofficial signature of children (Mike Pennisi)
  • Fix bug in css method (Mike Pennisi)
  • Correct bug in implementation of Cheerio#val (Mike Pennisi)

0.18.0 / 2014-11-06

  • bump htmlparser2 dependency to ~3.8.1 (Chris Rebert)
  • Correct unit test titles (Mike Pennisi)
  • Correct behavior of after and before (Mike Pennisi)
  • implement jQuery's .has() (Chris Rebert)
  • Update repository url (haqii)
  • attr() should return undefined or name for booleans (Raoul Millais)
  • Update Readme.md (Ryan Breen)
  • Implement Cheerio#not (Mike Pennisi)
  • Clone nodes according to original parsing options (Mike Pennisi)
  • fix lint error (David Chambers)
  • Add explicit tests for DOM level 1 API (Mike Pennisi)
  • Expose DOM level 1 API for Node-like objects (Mike Pennisi)
  • Correct error in documentation (Mike Pennisi)
  • Return a fully-qualified Function from $.load (Mike Pennisi)
  • Update tests to avoid duck typing (Mike Pennisi)
  • Alter "loaded" functions to produce true instances (Mike Pennisi)
  • Organize tests for cheerio.load (Mike Pennisi)
  • Complete $.prototype.find (Mike Pennisi)
  • Use JSHint's extends option (Mike Pennisi)
  • Remove aliases for exported methods (Mike Pennisi)
  • Disallow unused variables (Mike Pennisi)
  • Remove unused internal variables (Mike Pennisi)
  • Remove unused variables from unit tests (Mike Pennisi)
  • Remove unused API method references (Mike Pennisi)
  • Move tests for contains method (Mike Pennisi)
  • xyz@0.4.0 (David Chambers)
  • Created a wiki for companies using cheerio in production (Matthew Mueller)
  • Implement $.prototype.index (Mike Pennisi)
  • Implement $.prototype.addBack (Mike Pennisi)
  • Added double quotes to radio attribute name to account for characters such as brackets (akant10)
  • Update History.md (Gabriel Falkenberg)
  • add 0.17.0 changelog (David Chambers)
  • exit prepublish script if tag not found (David Chambers)
  • alphabetize devDependencies (fb55)
  • ignore coverage dir (fb55)
  • submit coverage to coveralls (fb55)
  • replace jscoverage with istanbul (fb55)

0.17.0 / 2014-06-10

  • Fix bug in internal uniqueSplice function (Mike Pennisi)
  • accept buffer argument to cheerio.load (David Chambers)
  • Respect options on the element level (Alex Indigo)
  • Change state definition to more readable (Artem Burtsev)
  • added test (0xBADC0FFEE)
  • add class only if doesn't exist (Artem Burtsev)
  • Made it less insane. (Alex Indigo)
  • Implement Cheerio#add (Mike Pennisi)
  • Use "loaded" instance of Cheerio in unit tests (Mike Pennisi)
  • Be more strict with object check. (Alex Indigo)
  • Added options argument to .html() static method. (Alex Indigo)
  • Fixed encoding mishaps. Adjusted tests. (Alex Indigo)
  • use dom-serializer module (fb55)
  • don't test on 0.8, don't ignore 0.11 (Felix Böhm)
  • parse: rm unused variables (coderaiser)
  • cheerio: rm unused variable (coderaiser)
  • Fixed test (Avi Kohn)
  • Added test (Avi Kohn)
  • Changed == to === (Avi Kohn)
  • Fixed a bug in removing type="hidden" attr (Avi Kohn)
  • sorted (Alexey Raspopov)
  • add muted attr to booleanAttributes (Alexey Raspopov)
  • fixed context of this in .html (Felix Böhm)
  • append new elements for each element in selection (fb55)

0.16.0 / 2014-05-08

  • fix make bench (David Chambers)
  • makefile: add release-* targets (David Chambers)
  • alphabetize dependencies (David Chambers)
  • Rewrite data internals with caching behavior (Mike Pennisi)
  • Fence .val example as js (Kevin Sawicki)
  • Fixed typos. Deleted trailing whitespace from test/render.js (Nattaphoom Ch)
  • Fix manipulation APIs with removed elements (kpdecker)
  • Perform manual string parsing for hasClass (kpdecker)
  • Fix existing element removal (kpdecker)
  • update render tests (Felix Böhm)
  • fixed cheerio path (Felix Böhm)
  • use entities.escape for attribute values (Felix Böhm)
  • bump entities version (Felix Böhm)
  • remove lowerCaseTags option from readme (Felix Böhm)
  • added test case for .html in xmlMode (fb55)
  • render xml in html() when xmlMode: true (fb55)
  • use a map for booleanAttributes (fb55)
  • update singleTags, use utils.isTag (fb55)
  • update travis badge URL (Felix Böhm)
  • use typeof instead of _.isString and _.isNumber (fb55)
  • use Array.isArray instead of _.isArray (fb55)
  • replace _.isFunction with typeof (fb55)
  • removed unnecessary error message (fb55)
  • decode entities in htmlparser2 (fb55)
  • pass options object to CSSselect (fb55)

0.15.0 / 2014-04-08

  • Update callbacks to pass element per docs (@kpdecker)
  • preserve options (@fb55)
  • Use SVG travis badge (@t3chnoboy)
  • only use static requires (@fb55)
  • Optimize manipulation methods (@kpdecker)
  • Optimize add and remove class cases (@kpdecker)
  • accept dom of DomHandler to cheerio.load (@nleush)
  • added parentsUntil method (@finspin)
  • Add performance optimization and bug fix empty method (@kpdecker)

0.14.0 / 2014-04-01

  • call encodeXML and directly expose decodeHTML (@fb55)
  • use latest htmlparser2 and entities versions (@fb55)
  • Deprecate $.fn.toArray (@jugglinmike)
  • Implement $.fn.get (@jugglinmike)
  • .replaceWith now replaces all selected elements. (@xavi-)
  • Correct arguments for 'replaceWith' callback (@jugglinmike)
  • switch to lodash (@fb55)
  • update to entities@0.5.0 (@fb55)
  • Fix attr when $ collection contains text modules (@kpdecker)
  • Update to latest version of expect.js (@jugglinmike)
  • Remove nodes from their previous structures (@jugglinmike)
  • Update render.js (@stevenvachon)
  • CDATA test (@stevenvachon)
  • only ever one child index for cdata (@stevenvachon)
  • don't loop through cdata children array (@stevenvachon)
  • proper rendering of CDATA (@stevenvachon)
  • Add cheerio-only bench option (@kpdecker)
  • Avoid delete operations (@kpdecker)
  • Add independent html benchmark (@kpdecker)
  • Cache tag check in render (@kpdecker)
  • Simplify attribute rendering step (@kpdecker)
  • Add html rendering bench case (@kpdecker)
  • Remove unnecessary check from removeAttr (@kpdecker)
  • Remove unnecessary encoding step for attrs (@kpdecker)
  • Add test for removeAttr+attr on boolean attributes (@kpdecker)
  • Add single element benchmark case (@kpdecker)
  • Optimize filter with selector (@kpdecker)
  • Fix passing context as dom node (@alfred-nsh)
  • Fix bug in nextUntil (@jugglinmike)
  • Fix bug in nextAll (@jugglinmike)
  • Implement selector argument of next method (@jugglinmike)
  • Fix bug in prevUntil (@jugglinmike)
  • Implement selector argument of prev method (@jugglinmike)
  • Fix bug in prevAll (@jugglinmike)
  • Fix bug in siblings (@jugglinmike)
  • Avoid unnecessary indexOf from toggleClass (@kpdecker)
  • Use strict equality rather than falsy check in eq (@kpdecker)
  • Add benchmark coverage for all $ APIs (@kpdecker)
  • Optimize filter Cheerio intermediate creation (@kpdecker)
  • Optimize siblings cheerio instance creation (@kpdecker)
  • Optimize identity cases for first/last/eq (@kpdecker)
  • Use domEach for traversal (@kpdecker)
  • Inline children lookup in find (@kpdecker)
  • Use domEach in data accessor (@kpdecker)
  • Avoid cheerio creation in add/remove/toggleClass (@kpdecker)
  • Implement getAttr local helper (@kpdecker)

0.13.1 / 2014-01-07

  • Fix select with context in Cheerio function (@jugglinmike)
  • Remove unecessary DOM maintenance logic (@jugglinmike)
  • Deprecate support for node 0.6

0.13.0 / 2013-12-30

  • Remove "root" node (@jugglinmike)
  • Fix bug in prevAll, prev, nextAll, next, prevUntil, nextUntil (@jugglinmike)
  • Fix replaceWith method (@jugglinmike)
  • added nextUntil() and prevUntil() (@finspin)
  • Remove internal connect function (@jugglinmike)
  • Rename Cheerio#make to document private status (@jugginmike)
  • Remove extraneous call to _.uniq (@jugglinmike)
  • Use CSSselect library directly (@jugglinmike)
  • Run CI against Node v0.11 as an allowed failure (@jugginmike)
  • Correct bug in Cheerio#parents (@jugglinmike)
  • Implement $.fn.end (@jugginmike)
  • Ignore colons inside of url(.*) when parsing css (@Meekohi)
  • Introduce rudimentary benchmark suite (@jugglinmike)
  • Update HtmlParser2 version (@jugglinmike)
  • Correct inconsistency in $.fn.map (@jugglinmike)
  • fixed traversing tests (@finspin)
  • Simplify make method (@jugglinmike)
  • Avoid shadowing instance methods from arrays (@jugglinmike)

0.12.4 / 2013-11-12

  • Coerce JSON values returned by data (@jugglinmike)
  • issue #284: when rendering HTML, use original data attributes (@Trott)
  • Introduce JSHint for automated code linting (@jugglinmike)
  • Prevent find from returning duplicate elements (@jugglinmike)
  • Implement function signature of replaceWith (@jugglinmike)
  • Implement function signature of before (@jugglinmike)
  • Implement function signature of after (@jugglinmike)
  • Implement function signature of append/prepend (@jugglinmike)
  • Extend iteration methods to accept nodes (@jugglinmike)
  • Improve removeClass (@jugglinmike)
  • Complete function signature of addClass (@jugglinmike)
  • Fix bug in removeClass (@jugglinmike)
  • Improve contributing.md (@jugglinmike)
  • Fix and document .css() (@jugglinmike)

0.12.3 / 2013-10-04

  • Add .toggleClass() function (@cyberthom)
  • Add contributing guidelines (@jugglinmike)
  • Fix bug in siblings (@jugglinmike)
  • Correct the implementation filter and is (@jugglinmike)
  • add .data() function (@andi-neck)
  • add .css() (@yields)
  • Implements contents() (@jlep)

0.12.2 / 2013-09-04

  • Correct implementation of $.fn.text (@jugglinmike)
  • Refactor Cheerio array creation (@jugglinmike)
  • Extend manipulation methods to accept Arrays (@jugglinmike)
  • support .attr(attributeName, function(index, attr)) (@xiaohwan)

0.12.1 / 2013-07-30

  • Correct behavior of Cheerio#parents (@jugglinmike)
  • Double quotes inside attributes kills HTML (@khoomeister)
  • Making next({}) and prev({}) return empty object (@absentTelegraph)
  • Implement $.parseHTML (@jugglinmike)
  • Correct bug in jQuery.fn.closest (@jugglinmike)
  • Correct behavior of $.fn.val on 'option' elements (@jugglinmike)

0.12.0 / 2013-06-09

  • Breaking Change: Changed context from parent to the actual passed one (@swissmanu)
  • Fixed: jquery checkbox val behavior (@jhubble)
  • Added: output xml with $.xml() (@Maciek416)
  • Bumped: htmlparser2 to 3.1.1
  • Fixed: bug in attr(key, val) on empty objects (@farhadi)
  • Added: prevAll, nextAll (@lessmind)
  • Fixed: Safety check in parents and closest (@zero21xxx)
  • Added: .is(sel) (@zero21xxx)

0.11.0 / 2013-04-22

  • Added: .closest() (@jeremy-dentel)
  • Added: .parents() (@zero21xxx)
  • Added: .val() (@rschmukler & @leahciMic)
  • Added: Travis support for node 0.10.0 (@jeremy-dentel)
  • Fixed: .find() if no selector (@davidchambers)
  • Fixed: Propagate syntax errors caused by invalid selectors (@davidchambers)

0.10.8 / 2013-03-11

  • Add slice method (SBoudrias)

0.10.7 / 2013-02-10

  • Code & doc cleanup (davidchambers)
  • Fixed bug in filter (jugglinmike)

0.10.6 / 2013-01-29

  • Added $.contains(...) (jugglinmike)
  • formatting cleanup (davidchambers)
  • Bug fix for .children() (jugglinmike & davidchambers)
  • Remove global render bug (wvl)

0.10.5 / 2012-12-18

  • Fixed botched publish from 0.10.4 - changes should now be present

0.10.4 / 2012-12-16

  • $.find should query descendants only (@jugglinmike)
  • Tighter underscore dependency

0.10.3 / 2012-11-18

  • fixed outer html bug
  • Updated documentation for $(...).html() and $.html()

0.10.2 / 2012-11-17

  • Added a toString() method (@bensheldon)
  • use _.each and _.map to simplify cheerio namesakes (@davidchambers)
  • Added filter() with tests and updated readme (@bensheldon & @davidchambers)
  • Added spaces between attributes rewritten by removeClass (@jos3000)
  • updated docs to remove reference to size method (@ironchefpython)
  • removed HTML tidy/pretty print from cheerio

0.10.1 / 2012-10-04

  • Fixed regression, filtering with a context (#106)

0.10.0 / 2012-09-24

  • Greatly simplified and reorganized the library, reducing the loc by 30%
  • Now supports mocha's test-coverage
  • Deprecated self-closing tags (HTML5 doesn't require them)
  • Fixed error thrown in removeClass(...) @robashton

0.9.2 / 2012-08-10

  • added $(...).map(fn)
  • manipulation: refactor makeCheerioArray
  • make .removeClass() remove all occurrences (#64)

0.9.1 / 2012-08-03

  • fixed bug causing options not to make it to the parser

0.9.0 / 2012-07-24

  • Added node 8.x support
  • Removed node 4.x support
  • Add html(dom) support (@wvl)
  • fixed xss vulnerabilities on .attr(), .text(), & .html() (@benatkin, @FB55)
  • Rewrote tests into javascript, removing coffeescript dependency (@davidchambers)
  • Tons of cleanup (@davidchambers)

0.8.3 / 2012-06-12

  • Fixed minor package regression (closes #60)

0.8.2 / 2012-06-11

  • Now fails gracefully in cases that involve special chars, which is inline with jQuery (closes #59)
  • text() now decode special entities (closes #52)
  • updated travis.yml to test node 4.x

0.8.1 / 2012-06-02

  • fixed regression where if you created an element, it would update the root
  • compatible with node 4.x (again)

0.8.0 / 2012-05-27

  • Updated CSS parser to use FB55/CSSselect. Cheerio now supports most CSS3 psuedo selectors thanks to @FB55.
  • ignoreWhitespace now on by default again. See #55 for context.
  • Changed $(':root') to $.root(), cleaned up $.clone()
  • Support for .eq(i) thanks to @alexbardas
  • Removed support for node 0.4.x
  • Fixed memory leak where package.json was continually loaded
  • Tons more tests

0.7.0 / 2012-04-08

  • Now testing with node v0.7.7
  • Added travis-ci integration
  • Replaced should.js with expect.js. Browser testing to come
  • Fixed spacing between attributes and their values
  • Added HTML tidy/pretty print
  • Exposed node-htmlparser2 parsing options
  • Revert .replaceWith(...) to be consistent with jQuery

0.6.2 / 2012-02-12

  • Fixed .replaceWith(...) regression

0.6.1 / 2012-02-12

  • Added .first(), .last(), and .clone() commands.
  • Option to parse using whitespace added to .load.
  • Many bug fixes to make cheerio more aligned with jQuery.
  • Added $(':root') to select the highest level element.

Many thanks to the contributors that made this release happen: @ironchefpython and @siddMahen

0.6.0 / 2012-02-07

  • Important: $(...).html() now returns inner HTML, which is in line with the jQuery spec
  • $.html() returns the full HTML string. $.html([cheerioObject]) will return the outer(selected element's tag) and inner HTML of that object
  • Fixed bug that prevented HTML strings with depth (eg. append('<ul><li><li></ul>')) from getting parent, next, prev attributes.
  • Halted htmlparser2 at v2.2.2 until single attributes bug gets fixed.

0.5.1 / 2012-02-05

  • Fixed minor regression: $(...).text(fn) would fail

0.5.1 / 2012-02-05

  • Fixed regression: HTML pages with comments would fail

0.5.0 / 2012-02-04

  • Transitioned from Coffeescript back to Javascript
  • Parser now ignores whitespace
  • Fixed issue with double slashes on self-enclosing tags
  • Added boolean attributes to html rendering

0.4.2 / 2012-01-16

  • Multiple selectors support: $('.apple, .orange'). Thanks @siddMahen!
  • Update package.json to always use latest cheerio-soupselect
  • Fix memory leak in index.js

0.4.1 / 2011-12-19

  • Minor packaging changes to allow make test to work from npm installation

0.4.0 / 2011-12-19

  • Rewrote all unit tests as cheerio transitioned from vows -> mocha
  • Internally, renderer.render -> render(...), parser.parse -> parse(...)
  • Append, prepend, html, before, after all work with only text (no tags)
  • Bugfix: Attributes can now be removed from script and style tags
  • Added yield as a single tag
  • Cheerio now compatible with node >=0.4.7

0.3.2 / 2011-12-1

  • Fixed $(...).text(...) to work with "root" element

0.3.1 / 2011-11-25

  • Now relying on cheerio-soupselect instead of node-soupselect
  • Removed all lingering htmlparser dependencies
  • parser now returns parent "root" element. Root now never needs to be updated when there is multiple roots. This fixes ongoing issues with before(...), after(...) and other manipulation functions
  • Added jQuery's $(...).replaceWith(...)

0.3.0 / 2011-11-19

  • Now using htmlparser2 for parsing (2x speed increase, cleaner, actively developed)
  • Added benchmark directory for future speed tests
  • $('...').dom() was funky, so it was removed in favor of $('...').get(). $.dom() still works the same.
  • $.root now correctly static across all instances of $
  • Added a screencast

0.2.2 / 2011-11-9

  • Traversing will select <script> and <style> tags (Closes Issue: #8)
  • .text(string) now working with empty elements (Closes Issue: #7)
  • Fixed before(...) & after(...) again if there is no parent (Closes Issue: #2)

0.2.1 / 2011-11-5

  • Fixed before(...) & after(...) if there is no parent (Closes Issue: #2)
  • Comments now rendered correctly (Closes Issue: #5)

< 0.2.0 / 2011-10-31

  • Initial release (untracked development)