NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #1305 most downloaded on npm
The fast, flexible & elegant library for parsing and manipulating HTML and XML.
Last release 8 months ago
23 Jan 2026
Release timing varies
gaps range from 4 weeks to 2.1 years
Most releases are documented
notes for 50 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
15 years old
74 releases · first in 2011
.val() now supports button values by @kaioduarte in #4175
.val() now supports button values by @kaioduarte in #4175.find() now properly scopes :scope selectors by @T0nd0Tara in #4967isHtml utility now runtime-validates input types by @Mallikarjun-0 in #4523Full Changelog: v1.1.2...v1.2.0
One column per quarter.
Fix fromURL baseURI issues by @fb55 in #4696
Fix Undici issues ( #4689 ) 91a2b3d
fix(attributes): support .prop on document nodes by @fb55 in #4320
.prop on document nodes by @fb55 in #4320browser to package.json root by @UNIDY2002 in #4033.html with .prop for outerHTML by @fb55 in #4321Full Changelog: v1.0.0...v1.1.0
The deprecated default Cheerio instance and static methods were removed. #3974
Cheerio 1.0 is here! 🎉
The minimum NodeJS version is now 18.17 or higher #3959
Import paths were simplified. For example, use cheerio/slim instead of
cheerio/lib/slim. #3970
The deprecated default Cheerio instance and static methods were removed. #3974
Before, it was possible to write code like this:
import cheerio, { html } from 'cheerio';
html(cheerio('<test></test>')); // ~ '<test></test>' -- NO LONGER WORKSMake sure to always load documents first:
import * as cheerio from 'cheerio';
cheerio.load('<test></test>').html();Node types previously re-exported by Cheerio must now be imported directly
from (domhandler)(https://github.com/fb55/domhandler). #3969
htmlparser2 options now reside exclusively under the xml key (#2916):
const $ = cheerio.load('<html>', {
xml: {
withStartIndices: true,
},
});cheerio/utils by @blixt in #2601data, and simplify by @fb55 in #2818closest be able to start from text nodes by @Qualtagh in #2811Full Changelog: v1.0.0-rc.12...v1.0.0
Align prop undefined handling with jQuery by @fb55 in #2557
cheerio@1.0.0-rc.11 is hopefully the last RC before the 1.0.0 release of Cheerio. There are two APIs that will be added for the next major release: An
cheerio@1.0.0-rc.11 is hopefully the last RC before the 1.0.0 release of Cheerio. There are two APIs that will be added for the next major release: An exract method (#2523) and NodeJS specific loader methods (#2051). These are still in flux and I'd appreciate feedback on the proposals.
A big thank you to everyone that contributed to this release! This includes code contributors, as well as the amazing financial support on GitHub Sponsors!
Under the hood, a lot of work for this release went into updating parse5, cheerio's default HTML parser. Have a look at parse5's release notes to see what has changed there.
script and style contents are added again in .text() #2509
.text() to .prop('innerText')cheerio-select #2511
pseudos option..prop() method:
slim export, which will always use htmlparser2 #1960text turn passed values to strings #2047undefined in the return type of get by @glen-84 in #2392undefined return value #2505domutils module directly #1928isHTML #1935load #1951closest #2057Full Changelog: v1.0.0-rc.10...v1.0.0-rc.11
.html(node) now moves passed nodes ( #1923 , fixes #940 ) 258b26b
Fixes:
.html(node) now moves passed nodes (#1923, fixes #940) 258b26bfilter work on all collections (#1870, fixes #1867) fb8d31eDocumentation:
require 5dfbd35Refactors:
Breaking change: If you were using the function exported by Cheerio directly instead of first load() ing a document, you will now have to update the r…
Port to TypeScript
Cheerio has been ported entirely to TypeScript (in #1816)! This eliminates a lot of edge-cases within Cheerio and will allow you to use Cheerio with confidence. This release also features a new documentation website based on TypeDoc, allowing you to quickly navigate all available methods: https://cheerio.js.org
Breaking change: If you were using the function exported by Cheerio directly instead of first load()ing a document, you will now have to update the require to use the default export.
- const cheerio = require("cheerio");
+ const cheerio = require("cheerio").default;
cheerio('div', dom)Please note that this way of using Cheerio is deprecated and might be removed in a future version. Please consider updating your code to:
const cheerio = require("cheerio");
const $ = cheerio.load(dom)
$('div')Note: Cheerio uses template literal types to determine return types. These are available starting with TypeScript 4.1, so you might have to bump your TypeScript version.
For TypeScript types, Cheerio now implements the ArrayLike<T> interface. That means that Cheerio instances can contain objects of arbitrary types, but not all methods can be called on them.
The TypeScript compiler will figure out what structures you are operating on:
$('<div>'), it will product a Cheerio<Node> type.
Node is the base class for DOM elements and includes eg. comment and text nodes.$('.foo'), it will produce a Cheerio<Element>, as only Elements can be part of the result set.
Element is the class representing tags.$('...').map() to map to arbitrary values, and will get a compiler error when trying to call method that are not supported.
$('.foo').map((i, el) => $(el).text()).attr('test') will no longer be possible, as .attr is not allowed to be called on a Cheerio<string>.This release does not contain other changes to functionality. Feedback is greatly appreciated; if you encounter a problem, please file an issue!
Second botched release. Please use v1.0.0-rc.9 instead.
Second botched release. Please use v1.0.0-rc.9 instead.
_Published without a lib directory — please ignore._
Published without a lib directory — please ignore.
_This release contains three breaking changes inherited from dependencies._
Breaking:
prevAll, prevUntil and parentsUntil. The new order matches jQuery.This release contains three breaking changes inherited from dependencies.
type: 'tag'.New features:
.unwrap (#1651 by @5saviahv) 2037d83.wrapAll (#1590 by @5saviahv) cd4a4d9prop('innerHTML') (#1578 by @fb55) c58258fscriptingEnabled parse5 option (#1707 by @5saviahv) 7eb4cc4
scriptingEnabled to false, it is now possible to parse the contents of <noscript> tags.Types:
.load type (#1584 by @f0x52) 6a90bda.get (#1759 by @karlhorky) d706976.wrapAll (#1740 by @5saviahv) b360762for of loops (#1704 by @mcpiroman) 8fef5aaAttrFunction arguments (#1669 by @maxma241) 5f2e9c3Bug fixes:
undefined as value in .attr() (#1757 by @5saviahv) 98186e8{prev,next}Until (#1728 by @fb55) f2615d2find function (#1680 by @5saviahv) 9b28b49.add modifying previous selections (#1656 by @5saviahv) 9f9b493.find siblings (#1583 by @fb55) 1062a6creplaceWith replacing element with itself (#1581 by @fb55) 88ae636attr handling of undefined as value (#1582 by @fb55) 3b35ae4load (#1580 by @fb55) 0855be6.prop (#1579 by @fb55) db3fce7Documentation updates:
after, before, slice arguments, improve handling (#1721 by @5saviahv) 732d539package.json (#1609 by @XhmikosR) ad3e30bRefactors:
quickExpr (#1716 by @fb55) 4aa3d39wrapAll, add some tests (#1640 by @5saviahv) b6d3840eqeqeq eslint rule except for null (#1638 by @XhmikosR) 52f37a1block-scoped-var eslint rule (#1631 by @XhmikosR) b072df8no-unused-expressions eslunt rule (#1630 by @XhmikosR) fc2c7d5--ignore-path (#1612 by @XhmikosR) 17f0d08CI:
actions-gh-pages (#1626 by @fb55) 9ee60ccversioning-strategy: increase for dependabot, format 71d2aafTest changes:
.map test was actually calling .each (#1711 by @Pustur) 456fbe5.toBeUndefined() (#1659 by @XhmikosR) 5aa4272Commit Range: https://github.com/cheeriojs/cheerio/compare/v1.0.0-rc.5...v1.0.0-rc.6
fix(package): Use cheerio-select-tmp until naming issue is resolved 3751929
Hotfix release
cheerio-select-tmp until naming issue is resolved 3751929https://github.com/cheeriojs/cheerio/compare/v1.0.0-rc.4...v1.0.0-rc.5
Formally test deprecated APIs (#1184 by @jugglinmike)
Welcome to cheerio@1.0.0-rc.4! This is the last pre-release before a full 1.0.0 release — please make sure to test this release and report any issues you might find.
This release was made possible by our supporters on Open Collective. If you want to support this project going forward, have a look at sponsorship options!
Breaking:
parse5, cheerio temporarily has a minimum Node version of Node 6. See #1585 for details.root reference. The root node is now referenced by the parent property.New Features:
for...of iterator via Symbol.iterator (#1197 by @papandreou)wrapInner (9ffc557 by @fb55, based on work by @tomjw64 and @warrengm)removeAttr accept a list of attributes to remove (#1561 by @fb55)prop(‘outerHTML’) implementation (#945 by @bill-bishop)Bug Fixes:
.prev() after replaceWith() (#1254 by @Gei0r).xml calls on HTML documents (#1572 by @fb55)cheerio.load() (#1087 by @zeke)locationInfo option to parse5 (#1155 by @trevorhreed)Other notable changes:
domhandler nodes directly (#1564 by @fb55)https://github.com/cheeriojs/cheerio/compare/1.0.0-rc.2...v1.0.0-rc.4
This release corrects a test expectation that was fixed by one of the project's dependencies.
This release corrects a test expectation that was fixed by one of the project's dependencies.
This release changes Cheerio's default parser to the Parse5 HTML parser. Parse5 is an excellent project that rigorously conforms to the HTML standard.
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.
cheerio.load( html[, options ] ) This method continues to act as a "factory"
function. It produces functions that define an API that is similar to the
global jQuery function provided by the jQuery library. The generated function
operates on a DOM structure based on the provided HTML.
In releases prior to version 1.0, the provided HTML was interpreted as a
document fragment. Following version 1.0, 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.
For example, the following code will produce different results between 0.x and 1.0 releases:
const $ = cheerio.load('<p>Hello, <b>world</b>!</p>');
$.root().html();
//=> In version 0.x: '<p>Hello, <b>world</b>!</p>'
//=> In version 1.0: '<html><head></head><body><p>Hello, <b>world</b>!</p></body></html>'
Users wishing to parse, manipulate, and render full documents should not need
to modify their code. Likewise, code that does not interact with the "root"
element should not be effected by this change. (In the above example, the
expression $('p') returns the same result across Cheerio versions--a Cheerio
collection whose only member is a paragraph element.)
However, users wishing to render document fragments should now explicitly create a "wrapper" element to contain their input.
// First, create a Cheerio function "bound" to an empty document (this is
// similar to loading an empty page in a web browser)
var $ = cheerio.load('');
// Next, create a "wrapper" element for the input fragment:
var $wrapper = $('<div/>');
// Finally, supply the input markup as the content for the wrapper:
$wrapper.append('<p>Hello, <b>world</b>!</p>');
$wrapper.html();
//=> '<p>Hello, <b>world</b>!</p>'
Change log:
useHtmlParser2 option (Mike Pennisi)xmlMode option (Mike Pennisi)Nothing published for this version
Return undefined in .prop if given an invalid element or tag
$.text method (#855).serialize() support. Fixes #69 (#827)Add coveralls badge, remove link to old report (Felix Böhm)
$.fn.toArray (Mike Pennisi)wrap (Mike Pennisi)children (Mike Pennisi)wrap method (Dandlezzz)value attribute. Fixes #633 (Todd Wolfson)added test case for malformed json in data attributes (fb55)
data-custom="{{templatevar}}". There is possibility error while parsing json . (Harish.K)Cheerio#serialzeArray (Mike Pennisi)serializeArray() and added multiple support (Todd Wolfson)children array (Mike Pennisi)load (Mike Pennisi)children (Mike Pennisi)css method (Mike Pennisi)Cheerio#val (Mike Pennisi)bump htmlparser2 dependency to ~3.8.1 (Chris Rebert)
after and before (Mike Pennisi)Cheerio#not (Mike Pennisi)$.load (Mike Pennisi)cheerio.load (Mike Pennisi)$.prototype.find (Mike Pennisi)extends option (Mike Pennisi)contains method (Mike Pennisi)$.prototype.index (Mike Pennisi)$.prototype.addBack (Mike Pennisi)Fix bug in internal uniqueSplice function (Mike Pennisi)
uniqueSplice function (Mike Pennisi)Cheerio#add (Mike Pennisi)muted attr to booleanAttributes (Alexey Raspopov)this in .html (Felix Böhm)fix make bench (David Chambers)
make bench (David Chambers)data internals with caching behavior (Mike Pennisi)entities.escape for attribute values (Felix Böhm)html() when xmlMode: true (fb55)Update callbacks to pass element per docs (@kpdecker)
empty method (@kpdecker)Deprecate $.fn.toArray (@jugglinmike)
$.fn.toArray (@jugglinmike)$.fn.get (@jugglinmike)nextUntil (@jugglinmike)nextAll (@jugglinmike)selector argument of next method (@jugglinmike)prevUntil (@jugglinmike)selector argument of prev method (@jugglinmike)prevAll (@jugglinmike)siblings (@jugglinmike)Fix select with context in Cheerio function (@jugglinmike)
Remove "root" node (@jugglinmike)
prevAll, prev, nextAll, next, prevUntil, nextUntil (@jugglinmike)replaceWith method (@jugglinmike)connect function (@jugglinmike)Cheerio#make to document private status (@jugginmike)_.uniq (@jugglinmike)Cheerio#parents (@jugglinmike)$.fn.end (@jugginmike)$.fn.map (@jugglinmike)make method (@jugglinmike)Coerce JSON values returned by data (@jugglinmike)
data (@jugglinmike)find from returning duplicate elements (@jugglinmike)replaceWith (@jugglinmike)before (@jugglinmike)after (@jugglinmike)append/prepend (@jugglinmike)removeClass (@jugglinmike)addClass (@jugglinmike)removeClass (@jugglinmike)Add .toggleClass() function (@cyberthom)
siblings (@jugglinmike)filter and is (@jugglinmike)Correct implementation of $.fn.text (@jugglinmike)
$.fn.text (@jugglinmike)Correct behavior of Cheerio#parents (@jugglinmike)
Cheerio#parents (@jugglinmike)Breaking Change: Changed context from parent to the actual passed one (@swissmanu)
Added: .closest() (@jeremy-dentel)
- Add slice method (SBoudrias)
Code & doc cleanup (davidchambers)
Added $.contains(...) (jugglinmike)
$.contains(...) (jugglinmike).children() (jugglinmike & davidchambers)render bug (wvl)Fixed botched publish from 0.10.4 - changes should now be present
\$.find should query descendants only (@jugglinmike)
Updated documentation for $(...).html() and $.html()
Added a toString() method (@bensheldon)
_.each and _.map to simplify cheerio namesakes (@davidchambers)Fixed regression, filtering with a context
Deprecated self-closing tags (HTML5 doesn't require them)
manipulation: refactor makeCheerioArray
makeCheerioArrayfixed bug causing options not to make it to the parser
fixed xss vulnerabilities on .attr(), .text(), & .html() (@benatkin, @FB55)
Fixed minor package regression (closes #60)
Now fails gracefully in cases that involve special chars, which is inline with jQuery (closes #59)
fixed regression where if you created an element, it would update the root
Updated CSS parser to use FB55/CSSselect. Cheerio now supports most CSS3 psuedo selectors thanks to @FB55.
Replaced should.js with expect.js. Browser testing to come
Fixed .replaceWith(...) regression
Added .first(), .last(), and .clone() commands.
.load.Many thanks to the contributors that made this release happen: @ironchefpython and @siddMahen
_Important:_ $(...).html() now returns inner HTML, which is in line with the jQuery spec
$(...).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 objectappend('<ul><li><li></ul>')) from getting parent, next, prev attributes.Nothing published for this version
Fixed minor regression: \$(...).text(fn) would fail
Transitioned from Coffeescript back to Javascript
Multiple selectors support: \$('.apple, .orange'). Thanks @siddMahen!
Minor packaging changes to allow make test to work from npm installation
make test to work from npm installationRewrote all unit tests as cheerio transitioned from vows -> mocha
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
Fixed $(...).text(...) to work with "root" element
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(...)
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →