css-select-base-adapter review
css-select-base-adapter 0.1.1 fills six traversal methods around a partial adapter for `css-select`. You supply `isTag`, attribute lookup, child and parent access, tag naming, and recursive text extraction. The factory adds searches, sibling lookup, attribute presence, and subset removal, while preserving any replacements you supplied. It neither parses markup nor runs a selector by itself. The current release changed package metadata in October 2018; the repository shows no runtime-code commit after the initial 2016 implementation.
Our 0.3-second install produced a 0.9 KB gzipped helper with zero dependencies and zero audit findings, but its adapter contract has seen no runtime work since 2016. Keep it for a tested legacy tree; current projects should use the adapter shipped with their node model or write the 6 required methods with local types.
We installed it
| Install | ✓ · 0.3s | 1 package on disk · 1 MB |
| Import | ✓ | ESM import works · require() works · CommonJS package |
| Browser | 0.9 KB | gzipped (1.9 KB minified), bundled with esbuild |
| Types | — | no TypeScript types found |
| Known vulns | 0 | 0 critical · 0 high · 0 moderate · 0 low (npm audit) |
Answers from our run
Does css-select-base-adapter install cleanly?
Yes. In a fresh container with an empty cache, npm install css-select-base-adapter finished in 0.3s, leaving 1 package and 1 MB on disk. npm audit reported no known vulnerabilities.
How much does css-select-base-adapter add to a browser bundle?
0.9 KB gzipped (1.9 KB minified) when the whole package is bundled for the browser with esbuild. Importing only part of it is usually smaller.
Does css-select-base-adapter work with both ESM and CommonJS?
Yes. Both import 'css-select-base-adapter' and require('css-select-base-adapter') worked in Node 22 in our run. The package is published as CommonJS.
Does css-select-base-adapter include TypeScript types?
No type declarations were found in our install, so TypeScript users need their own declarations.
css-select-base-adapter or css-select: which should you use?
css-select: Use its default DomUtils path when htmlparser2 or domhandler already owns the tree. Our 0.3-second install produced a 0.9 KB gzipped helper with zero dependencies and zero audit findings, but its adapter contract has seen no runtime work since 2016.
When should you not use css-select-base-adapter?
You parse ordinary HTML into htmlparser2 nodes. css-select already works with DomUtils, so another adapter layer adds code without changing the result.
Use it if
- A custom tree already has parent links and child arrays, and you only want the repetitive `css-select` traversal methods filled in.
- You can audit a short CommonJS implementation and pin its behavior alongside an older `css-select` integration.
- Your nodes use stable object identity, which matches the package's duplicate and ancestor checks.
- You want caller-defined methods to replace any generated default through the factory's final `Object.assign`.
- You parse ordinary HTML into htmlparser2 nodes. `css-select` already works with DomUtils, so another adapter layer adds code without changing the result.
- You require maintained TypeScript declarations. Our 0.1.1 inspection found no types, and the README gives method names without parameter or return contracts.
- Your root is a non-tag document node. The included `existsOne` stops at every node where `isTag` is false and will not inspect that node's children.
- Your selection array must remain untouched. `removeSubsets` edits the array in place while removing duplicates and descendants.
- You need demonstrated compatibility with current `css-select` 7. Version 0.1.1 predates it by years and declares no peer dependency that states a supported range.
- Your tree can contain cycles or reconstructed node objects. The defaults recursively walk children and compare ancestors with strict object identity.
Setup reality
We installed css-select-base-adapter 0.1.1 in 0.3 seconds. One package occupied 1 MB on disk; its own unpacked files total 40 KB. It has zero direct dependencies and zero peer dependencies, and npm audit found zero known vulnerabilities. The package is CommonJS with no exports map. require() and ESM import both worked in our Node 22 sandbox, while TypeScript declarations were absent.
Nothing asks for credentials, a native compiler, or a config file. The factory rejects a partial implementation unless all 6 primitives are functions: tag testing, attribute reads, children, name, parent, and text. It only checks their presence. Wrong return values, mismatched parent links, and cyclic trees pass construction and then fail through incorrect matches or recursive calls.
The generated behavior has sharp edges visible in its 73 lines of source. getSiblings returns the parent's full child list, including the current node, and produces a falsy value at a parentless root. hasAttrib treats every result except undefined as present. findOne tests non-tag entries too, while findAll skips non-tags and their descendants. removeSubsets mutates its input and uses indexOf, so copied nodes do not compare equal.
Our browser bundle measured 1.9 KB minified and 0.9 KB gzipped, so download weight is not the objection. Contract age is. The last push was in October 2018, the repository has no compatibility matrix, and 0.1.1 does not install css-select for you. Pin the selector version, test the adapter against your real tree, and override any default whose traversal assumptions do not fit.
Patterns
Complete a partial tree adapter build-adapter
const completeAdapter = require('css-select-base-adapter')
function textOf(node) {
if (node.type === 'text') return node.value
return (node.children || []).map(textOf).join('')
}
const adapter = completeAdapter({
isTag: (node) => node.type === 'element',
getAttributeValue: (node, name) => node.attrs?.[name],
getChildren: (node) => node.children || [],
getName: (node) => node.name,
getParent: (node) => node.parent || null,
getText: textOf,
})Version 0.1.1 throws during construction unless all 6 named primitives are functions.
Run css-select with the adapter select-custom-tree
const CSSselect = require('css-select')
const completeAdapter = require('css-select-base-adapter')
const adapter = completeAdapter(treeMethods)
const cards = CSSselect.selectAll('section.card > h2', roots, { adapter })0.1.1 does not install `css-select`; pin and test a selector version separately.
Define attribute presence for your model override-attribute-check
const adapter = completeAdapter({
...treeMethods,
hasAttrib(node, name) {
return Object.prototype.hasOwnProperty.call(node.attrs, name)
},
})A supplied `hasAttrib` replaces the default, whose only test is `getAttributeValue(...) !== undefined`.
Find the first matching node find-first-node
const result = adapter.findOne(
(node) => adapter.isTag(node) && adapter.getName(node) === 'main',
roots
)The default `findOne` calls its predicate on non-tag nodes, so guard element-only access with `isTag`.
Collect matching elements find-all-elements
const headings = adapter.findAll(
(node) => /^h[1-6]$/.test(adapter.getName(node)),
roots
)`findAll` tests tag nodes only and walks children depth first; non-tag wrappers are skipped with their subtrees.
Check a tag subtree for one match test-descendant
const containsLink = adapter.existsOne(
(node) => adapter.getName(node) === 'a',
elementRoots
)Every root in `elementRoots` must satisfy `isTag`; version 0.1.1 does not descend through a document wrapper that fails that check.
Get the parent's children read-sibling-group
const siblingsAndSelf = adapter.getSiblings(node) || [node]
const index = siblingsAndSelf.indexOf(node)The default result includes `node` itself and is falsy when `getParent(node)` is falsy.
Keep only top-level selected nodes remove-nested-results
const topLevel = adapter.removeSubsets([...selectedNodes])Use a copied array because 0.1.1 mutates the input while deleting duplicates and nodes whose ancestor is also selected.
Expose missing adapter methods during startup validate-primitives
try {
completeAdapter({ isTag() {}, getChildren() {} })
} catch (error) {
console.error(error.message)
}The factory lists missing functions in its error, but it cannot check their return types or tree consistency.
Import the CommonJS factory in ESM load-from-esm
import completeAdapter from 'css-select-base-adapter'
const adapter = completeAdapter(treeMethods)ESM import worked in our Node 22 test despite the absence of an exports map; the package still ships no declarations.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| css-select | npm | Use its default DomUtils path when htmlparser2 or domhandler already owns the tree. |
| domutils | npm | Use its maintained DOM traversal helpers for domhandler nodes instead of adapting that same model again. |
| cheerio | npm | Use it when the actual job is parsing HTML and querying it through a jQuery-like API. |
| css-what | npm | Use it when you only need to parse selector text into tokens and will perform matching yourself. |
More utils guides
lru-cache · ajv · type-fest · p-limit · find-up · js-yaml · the whole shelf →
How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.

