Use Cheerio’s siblings() to select every other element sharing a parent, next() or prev() for the adjacent element, and nextAll() or prevAll() for all element siblings in one direction. For a bounded run, use nextUntil() or prevUntil(). These methods traverse the parsed markup; they do not execute a page’s JavaScript.
Install Cheerio and load markup
Install the package with npm install cheerio. The official introduction currently lists Node.js 22.19 or later; check its compatibility guidance when setting up a new project because runtime requirements can change. Cheerio introduction and setup.
Here is a complete ES module example. Save it as sibling-example.mjs and run it with node sibling-example.mjs in a project where Cheerio is installed:
import * as cheerio from 'cheerio';
const html = `
<ul>
<li class="first">One</li>
<li class="target">Two</li>
<li class="last">Three</li>
</ul>
`;
const $ = cheerio.load(html);
const target = $('li.target');
console.log(target.siblings().map((_, el) => $(el).text()).get());
// [ 'One', 'Three' ]
console.log(target.next().text());
// Three
console.log(target.prev().text());
// One
console.log(target.nextAll().map((_, el) => $(el).text()).get());
// [ 'Three' ]
Cheerio’s introduction also documents CommonJS loading with const cheerio = require('cheerio');. The examples below use $ as the function returned by cheerio.load(), so the traversal API looks familiar to jQuery users. See the official loading examples.
#1 Best Overall
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
Choose the traversal method that matches the relationship
All of these methods operate on element siblings: elements with the same parent. Traversal returns a new selection; it does not replace or mutate the original selection. Cheerio traversal guide.
| What you need | Method | What it selects |
|---|---|---|
| Other siblings, on either side | siblings() |
All sibling elements except the selected element itself |
| One immediately following sibling | next() |
At most the next element sibling |
| One immediately preceding sibling | prev() |
At most the previous element sibling |
| All following siblings | nextAll() |
Every following element sibling |
| All preceding siblings | prevAll() |
Every preceding element sibling |
| Following siblings up to a boundary | nextUntil(selector) |
Following element siblings before, but not including, the boundary match |
| Preceding siblings up to a boundary | prevUntil(selector) |
Preceding element siblings before, but not including, the boundary match |
The API reference documents optional selector filters for traversal methods. For example, $('.apple').nextAll('.orange') selects following siblings that match .orange. Cheerio API reference.
Get all siblings, adjacent siblings, or a directional run
All siblings except the target
Use siblings() when you need elements before and after the target under the same parent. The selected node is excluded:
const otherItems = target.siblings();
const labels = otherItems.map((_, el) => $(el).text()).get();
console.log(labels); // [ 'One', 'Three' ]
If only certain siblings matter, pass a selector filter where supported or filter the returned selection:
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Rank #2
const otherListItems = target.siblings('li');
Only the next or previous element
Use next() and prev() for the nearest element sibling in the requested direction:
const nextItem = target.next();
const previousItem = target.prev();
console.log(nextItem.text()); // Three
console.log(previousItem.text()); // One
These methods do not mean “the next matching element anywhere in the document.” They stay among siblings of the target.
Every sibling in one direction
Use nextAll() for all following siblings, or prevAll() for all preceding siblings:
const laterItems = target.nextAll();
const earlierItems = target.prevAll();
console.log(laterItems.map((_, el) => $(el).text()).get());
console.log(earlierItems.map((_, el) => $(el).text()).get());
To retain only matching siblings, use an optional selector filter such as target.nextAll('.visible').
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Rank #3
Stop before a boundary sibling
Use nextUntil() or prevUntil() when a matching sibling marks where traversal should stop. The boundary element is not included:
const html = `
<div>
<p class="start">Start</p>
<p>Keep this</p>
<p>Keep this too</p>
<p class="stop">Boundary</p>
<p>After boundary</p>
</div>
`;
const $ = cheerio.load(html);
const start = $('.start');
const beforeStop = start.nextUntil('.stop');
console.log(beforeStop.map((_, el) => $(el).text()).get());
// [ 'Keep this', 'Keep this too' ]
The reverse pattern is $('.stop').prevUntil('.start'). For exact method behavior and available filters, consult the traversal guide and API reference.
Use CSS sibling combinators when a selector is enough
If the relationship can be expressed in a selector, sibling combinators can select directly. The adjacent-sibling combinator + matches the immediately following sibling that satisfies the selector; the general-sibling combinator ~ matches following siblings under the same parent.
const immediatelyFollowingParagraph = $('h2 + p');
const followingParagraphs = $('h2 ~ p');
These expressions differ from descendant selectors. div p can match paragraphs anywhere inside a div, including nested descendants; div > p matches only paragraphs that are direct children of the div. The + and ~ relationships are also limited to siblings under the same parent. Cheerio selector guide.
Rank #4
- Brand: Wiley
- Set of 2 Volumes
- A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers
Choose between traversal and a combinator
- Use traversal when you already have a target selection and want to inspect or filter its neighbors.
- Use a sibling combinator when one selector clearly describes the target and related elements together.
- Use
find()for descendants andchildren()for direct children; neither is sibling traversal.
Handle empty selections and real-world markup
Check that your starting selector matched
A selector can return an empty Cheerio selection. In that case, traversal also has no matching target from which to find siblings. Check the starting selection before using its text or attributes:
const target = $('li.target');
if (target.length === 0) {
console.error('No element matched li.target');
} else {
const next = target.next();
if (next.length === 0) {
console.log('The target has no following element sibling');
} else {
console.log(next.text());
}
}
Whitespace and comments are not element siblings
Indentation in HTML produces whitespace text, and markup can also contain comments. The documented traversal methods are for element siblings, so next() means the next element, not “the next byte of source” or the next text node. If your task specifically depends on text nodes or comment nodes, use an API designed for those node types rather than assuming element traversal includes them.
Multiple targets can produce multiple results
A selector such as $('li.target') can match more than one element. Traversal then operates from that selection; if you expect one target, verify the count or make the selector more specific. This avoids treating a multi-element result as a single unique neighbor.
Cheerio does not run page JavaScript
Cheerio parses the markup supplied to cheerio.load(); it is not a browser renderer and does not execute client-side page scripts. If the target element is inserted only after a site runs JavaScript, it will not appear in traversal over the original markup. Use browser automation or a DOM-emulation approach when the rendered, JavaScript-generated page is essential. Cheerio introduction.
Best Value
Troubleshoot common sibling-selection problems
| Symptom | Likely cause | What to do |
|---|---|---|
next() returns an empty selection |
The target has no following element sibling, or the starting selector matched nothing. | Check target.length; verify the markup and selector; confirm a following sibling actually exists. |
A nested element is not returned by siblings() |
It is a descendant, not an element sharing the target’s parent. | Use find() for descendants, or select the correct parent-level target. |
| The expected target is absent from results | The selector may be too broad, too narrow, or pointed at a different element than intended. | Inspect the initial selection and test a more specific selector before traversing. |
| Markup visible in a browser is missing | The element may have been generated client-side after the initial HTML was delivered. | Provide the rendered markup to Cheerio or use browser automation when script execution is required. |
| Results include the wrong related elements | A boundary or selector filter may not match the siblings you intended; a descendant selector may be confused with a sibling relationship. | Use the right direction and boundary method, and verify that the boundary shares the target’s parent. |
When debugging, first inspect the input HTML and the target selector, then verify the parent relationship, then choose the traversal direction and any filter or stop selector. This isolates selection mistakes from traversal mistakes.
Or skip the browser setup
If you need an actual page screenshot rather than parsing HTML into a Cheerio tree, ScreenshotNeo is a website screenshot API and MCP server. One GET request can return a PNG, JPEG, WebP or PDF; its cleaning steps accept cookie and consent banners like a visitor and remove more than 60 known consent platforms, newsletter popups and chat widgets, with each step configurable. Only clean shots are billed: bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits cost nothing, and response headers identify the page verdict and billing status. Its MCP server exposes take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients.
Install a current Node.js release and use the following example with your API key and target URL; see the ScreenshotNeo API documentation for request options and response details:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo offers 1,000 screenshots monthly free with no card; paid plans start at $5 for 3,000, and every feature is on every plan. Sign up for 1,000 free screenshots a month, with no card.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsFrequently Asked Questions
Does siblings() include the selected element?
No. It returns the other sibling elements and excludes the selected element itself.
Does next() skip over nonmatching elements to find a match?
It selects the immediately following element sibling. Use a filtered directional method such as nextAll(selector) if you want matching elements farther along the sibling run.
Can Cheerio find elements created by a website’s JavaScript?
Not from the original markup alone. Cheerio does not execute page JavaScript; it can parse those elements only if they are present in the markup you give it.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

