mrkeyoor.com_
Wed 23 Sept 04:38 UTC
npmUtilsupdated 23 Sept 2026

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.

Verdict

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

Lab card: what happened when we installed css-select-base-adapterScreenshot of css-select-base-adapter documentation
Install✓ · 0.3s1 package on disk · 1 MB
ImportESM import works · require() works · CommonJS package
Browser0.9 KBgzipped (1.9 KB minified), bundled with esbuild
Typesno TypeScript types found
Known vulns00 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.

API stability4/5The package exports one factory, requires the same 6 primitive methods, and adds the same 6 defaults as the original source. User methods overwrite generated methods because the implementation is assigned last. No runtime commit has changed those rules since 2016. That makes pinned legacy behavior easy to predict, although the lack of releases also means it has not followed changes in the external `css-select` adapter interface.
Docs2/5The README clearly names all 12 adapter methods, separates the 6 mandatory primitives from generated helpers, and shows the factory call. It never defines arguments, return values, mutation, identity rules, root behavior, or traversal through non-tag nodes. There is no TypeScript example or supported `css-select` version. Reading `index.js` is required to discover several outcomes that determine whether selectors are correct.
Maintenance1/5GitHub shows the last push on October 24, 2018 and only 4 stars. The final commit updates `package.json`; the implementation itself traces back to the initial November 2016 work. The repository is open and reports zero issues and pull requests, but version 0.1.1 has no current test signal, release activity, or declared peer range tying it to a supported `css-select` major.
Ecosystem2/5npm counted 5,013,729 downloads in the latest completed week, which reflects its place in dependency graphs around selector tooling. The package itself declares no dependencies or peers and has only 4 GitHub stars. It contributes one narrow bridge, without types or companion integrations. Most applications can stay within the maintained htmlparser2, DomUtils, Cheerio, and `css-select` path without choosing this helper directly.

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`.
Skip it if

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

PackageRegistryPick it when
css-selectnpmUse its default DomUtils path when htmlparser2 or domhandler already owns the tree.
domutilsnpmUse its maintained DOM traversal helpers for domhandler nodes instead of adapting that same model again.
cheerionpmUse it when the actual job is parsing HTML and querying it through a jQuery-like API.
css-whatnpmUse 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.