{"id":13290,"library":"hast-util-select","title":"HAST Selector Utilities","description":"hast-util-select provides a suite of utilities for querying and matching nodes within a HAST (HTML Abstract Syntax Tree) structure using CSS selectors. It offers functions equivalent to DOM's `matches`, `querySelector`, and `querySelectorAll` for HTML trees. The current stable version is 6.0.4, with active maintenance and a regular release cadence, including recent major updates. A key differentiator is its specific application to HAST, which means it operates differently from DOM selectors in certain aspects, particularly regarding parent-sensitive selectors (e.g., `:first-child`, descendant selectors) due to HAST nodes not storing parent references. While powerful for targeted queries, it advises caution for high-frequency use, suggesting `unist-util-visit` for bulk modifications due to its tree-walking overhead.","status":"active","version":"6.0.4","language":"javascript","source_language":"en","source_url":"https://github.com/syntax-tree/hast-util-select","tags":["javascript","css","hast-util","hast","html","match","matches","query","selectall","typescript"],"install":[{"cmd":"npm install hast-util-select","lang":"bash","label":"npm"},{"cmd":"yarn add hast-util-select","lang":"bash","label":"yarn"},{"cmd":"pnpm add hast-util-select","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"ESM-only since v6. Attempting to use CommonJS `require` will result in a runtime error.","wrong":"const { matches } = require('hast-util-select')","symbol":"matches","correct":"import { matches } from 'hast-util-select'"},{"note":"This package uses named exports only. There is no default export.","wrong":"import select from 'hast-util-select'","symbol":"select","correct":"import { select } from 'hast-util-select'"},{"note":"For Node.js versions prior to 16, a polyfill for ESM might be required, though v6 explicitly requires Node.js 16+.","wrong":"const selectAll = require('hast-util-select').selectAll","symbol":"selectAll","correct":"import { selectAll } from 'hast-util-select'"}],"quickstart":{"code":"import {h} from 'hastscript';\nimport {matches, select, selectAll} from 'hast-util-select';\n\nconst tree = h('section', [\n  h('p', 'Alpha'),\n  h('p', 'Bravo'),\n  h('h1', 'Charlie'),\n  h('p', 'Delta'),\n  h('p', 'Echo'),\n  h('p', 'Foxtrot'),\n  h('p', 'Golf')\n]);\n\nconsole.log('Matches section:', matches('section', tree)); // true\n\nconsole.log('Select single:', select('h1 ~ :nth-child(even)', tree));\n// Expected output: { type: 'element', tagName: 'p', properties: {}, children: [ { type: 'text', value: 'Delta' } ] }\n\nconsole.log('Select all:', selectAll('h1 ~ :nth-child(even)', tree));\n// Expected output: [\n//   { type: 'element', tagName: 'p', properties: {}, children: [ { type: 'text', value: 'Delta' } ] },\n//   { type: 'element', tagName: 'p', properties: {}, children: [ { type: 'text', value: 'Foxtrot' } ] }\n// ]","lang":"javascript","description":"Demonstrates how to use `matches`, `select`, and `selectAll` functions with a HAST tree to find and match elements based on CSS selectors."},"warnings":[{"fix":"Migrate your project to use ESM imports (`import ... from 'pkg'`) and ensure Node.js 16+ is used. Update your `package.json` with `\"type\": \"module\"` if necessary for your environment.","message":"Version 6.0.0 changed to be ESM-only and explicitly requires Node.js 16 or higher. CommonJS `require` statements will fail.","severity":"breaking","affected_versions":">=6.0.0"},{"fix":"Update your code to expect and handle `undefined` when no element is found, instead of `null`. E.g., `if (node === undefined)` rather than `if (node === null)`.","message":"The return value for `select` when no node matches changed from `null` to `undefined` in version 6.0.0.","severity":"breaking","affected_versions":">=6.0.0"},{"fix":"Review and update complex CSS selectors to adhere to modern CSS Selectors Level 4 syntax. Replace `:any` with `:is()` where appropriate.","message":"Version 6.0.0 updated its CSS selector parsing to match CSS Selectors Level 4. While generally compatible, older, non-standard selectors like `:any` are no longer supported and should be replaced with `:is`.","severity":"breaking","affected_versions":">=6.0.0"},{"fix":"Avoid parent-sensitive CSS selectors. For operations requiring tree traversal or parent context, consider using utilities like `unist-util-visit` or performing manual tree traversal after selecting direct children.","message":"HAST nodes, unlike DOM nodes, do not maintain references to their parents. This means selectors that rely on parent-child relationships or tree context (e.g., `:first-child`, `p b`, `p > b`, `:nth-child`) will not work with `matches` and may behave unexpectedly or not at all with `select` and `selectAll`.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"If performance is critical for large trees or frequent operations, consider using `unist-util-visit` to traverse the tree once and apply transformations or checks, rather than multiple calls to `select` or `selectAll`.","message":"This utility walks the entire tree for each call, making it potentially slow if used repeatedly for many small queries. For bulk modifications or processing many nodes, alternative methods might be more performant.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Change your import statement from `const { symbol } = require('hast-util-select')` to `import { symbol } from 'hast-util-select'`. Ensure your `package.json` is configured for ESM (`\"type\": \"module\"`).","cause":"Attempting to use `require()` to import `hast-util-select` in an environment that enforces ESM, or after upgrading to v6 without migrating to ESM imports.","error":"TypeError: require is not a function"},{"fix":"Replace `:any` with the standard `:is()` pseudo-class in your selectors. Review other deprecated CSS selectors and update them to modern equivalents.","cause":"Using outdated CSS pseudo-classes like `:any` that are no longer supported by the updated CSS Selectors Level 4 parsing logic in v6.","error":"Selector parsing error related to ':any' or similar pseudos"},{"fix":"Update your conditional checks from `if (node === null)` to `if (node === undefined)` (or `if (!node)` for both `null` and `undefined`).","cause":"Code written for `hast-util-select` versions prior to 6.0.0 expected `null` for no match, but v6 returns `undefined`.","error":"Result of `select` is `null` but expected `undefined` (or vice-versa)"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":"","cli_version":null}