mrkeyoor.com_
Sat 08 Aug 22:53 UTC
npmWeb Frontendupdated 08 Aug 2026

style-search

style-search is a tiny CommonJS scanner for finding text inside CSS and CSS-like source while tracking whether each match sits in a string, comment, function argument, function name, or any parenthesized section. Unlike indexOf or a regular expression, it skips strings, comments, and function names by default and reports start and end indexes through a callback. It is a narrow lexical utility, not a CSS parser: it does not build an AST, validate syntax, understand declarations, or apply edits for you.

Verdict

Keep it only for a narrow legacy scanning job where literal indexes and context flags are enough. New CSS tooling should usually pay the small complexity cost for a maintained parser whose output represents syntax rather than character-state guesses.

API stability4/5The public surface is one function, one options object, and one callback shape, and npm has remained on 0.1.0 since June 2016. That makes accidental API churn unlikely and existing consumers have had years of identical behavior. The missing 1.0 release and lack of formal types still mean the contract is documented convention rather than a versioning promise backed by recent releases.
Docs3/5The README clearly lists every option, its default, the callback fields, and the rule that only one syntax feature may use the only mode. It also states when to choose full PostCSS parsers. Documentation stops there: there is no migration guide, TypeScript declaration, complexity discussion, edge-case reference, or maintained documentation site, and the sole open issue concerns a documented match field.
Maintenance1/5The latest npm release is 0.1.0 from June 2016 and GitHub records the last repository push in August 2021. The repository is not archived and has only one open issue, but there is no recent release, commit activity, roadmap, or modern package metadata. Its simplicity reduces the maintenance burden; it does not turn the absence of maintenance into active support.
Ecosystem2/5The package recorded 3,916,760 downloads for the measured week, largely consistent with use deep inside CSS tooling dependency trees, yet the repository has only 7 stars and exposes no plugin system or companion packages. Its options are tailored to CSS-like text, but most new tooling composes around PostCSS ASTs and specialized parsers instead of building directly on this callback scanner.

Use it if

  • You maintain an older CommonJS CSS tool and need the same lightweight scanner used by parts of the Stylelint ecosystem
  • You need character indexes for literal tokens while excluding comments and quoted values without constructing a PostCSS AST
  • You are scanning CSS-like syntaxes such as Sass and need awareness of parenthesized sections and function arguments
  • You can pin a tiny, dependency-free package whose 0.1.0 API already does exactly what the project needs
Skip it if

Setup reality

Installation is only npm install style-search, and there are no runtime dependencies, peer dependencies, native modules, configuration files, or build steps. The friction is in the old API contract. Version 0.1.0 is CommonJS, so modern ESM code may need createRequire or a default-style interop import supplied by its bundler. There are no bundled TypeScript declarations, which means typed projects must add a local declaration or keep the call behind a typed wrapper. Both source and target are required in practice, but the function performs no friendly argument validation; bad inputs fail inside the scanner. Matches arrive synchronously through a callback and endIndex is the exclusive boundary, so collect them yourself if later code expects an array. Defaults matter: comments, strings, and function names are skipped, while function arguments and other parenthesized content are checked. Each syntax option accepts skip, check, or only, and the code throws if more than one option uses only. The scanner recognizes slash-star comments plus double-slash comments, and it decides that a parenthesis starts a function when the preceding character is an ASCII letter. Those deliberately simple rules can misclassify modern or unusual CSS. Pin the version and test representative source before using it in a formatter, codemod, or lint rule.

Patterns

Collect matches with the default exclusionsfind-default-matches

const styleSearch = require('style-search');

const matches = [];
styleSearch({
  source: 'a { color: pink; content: \"pink\"; } /* pink */',
  target: 'pink',
}, (match, count) => {
  matches.push({ ...match, count });
});

console.log(matches);

Only the declaration value is reported because strings and comments default to skip. The count argument starts at 1.

Stop after the first eligible matchstop-after-first

let first = null;
styleSearch({
  source: 'a { color: red; border-color: red; }',
  target: 'red',
  once: true,
}, (match) => {
  first = match;
});

once stops scanning after the first match that passes all context filters; it does not return the match from styleSearch.

Search for several literal targetssearch-multiple-targets

const found = [];
styleSearch({
  source: 'a { color: red; background: blue; }',
  target: ['red', 'blue'],
}, (match) => {
  found.push({ token: match.target, at: match.startIndex });
});

Array order matters when targets overlap: at each index the scanner accepts the first target that matches.

Include matches inside commentsinclude-comments

styleSearch({
  source: '/* TODO: replace px */ a { width: 10px; }',
  target: 'px',
  comments: 'check',
}, (match) => {
  console.log(match.startIndex, match.insideComment);
});

check includes both comment and non-comment matches. The scanner treats double-slash text as a comment too, even though that is not standard CSS.

Restrict a search to commentssearch-comments-only

const todos = [];
styleSearch({
  source: '/* TODO: remove */ a { content: \"TODO\"; }',
  target: 'TODO',
  comments: 'only',
}, (match) => todos.push(match));

Only one syntax option can be set to only. Combining comments: 'only' with strings: 'only' throws an error.

Include matches inside quoted stringsinclude-strings

styleSearch({
  source: 'a::before { content: \"draft\"; color: draft; }',
  target: 'draft',
  strings: 'check',
}, (match) => {
  console.log(match.startIndex, match.insideString);
});

Strings default to skip. The scanner handles single and double quotes but only checks the immediately preceding backslash when deciding whether a quote is escaped.

Include function names in the searchsearch-function-names

styleSearch({
  source: 'a { color: rgb(10 20 30); }',
  target: 'rgb',
  functionNames: 'check',
}, (match) => console.log(match));

Function names default to skip. Detection uses ASCII letters immediately before an opening parenthesis, not a complete CSS identifier grammar.

Ignore matches inside function argumentsskip-function-arguments

styleSearch({
  source: 'a { color: var(--brand); --brand: red; }',
  target: '--brand',
  functionArguments: 'skip',
}, (match) => console.log(match.startIndex));

Function arguments default to check, so set skip explicitly when a var(), calc(), or similar call should be excluded.

Search only inside parenthesized sectionssearch-parentheticals-only

styleSearch({
  source: '$map: (brand: red); a { color: red; }',
  target: 'red',
  parentheticals: 'only',
}, (match) => console.log(match.startIndex, match.insideParens));

parentheticals is broader than functionArguments and is useful for Sass-like maps. Nested parentheses are tracked with one depth counter.

Replace matches safely using reported indexesreplace-from-indexes

const source = 'a { color: red; border-color: red; }';
const matches = [];
styleSearch({ source, target: 'red' }, (match) => matches.push(match));

let output = source;
for (const match of matches.reverse()) {
  output = output.slice(0, match.startIndex) + 'blue' + output.slice(match.endIndex);
}
console.log(output);

endIndex is exclusive. Apply edits from the end toward the start so earlier indexes remain valid.

Alternatives

PackageRegistryPick it when
postcssnpmUse it when you need a real CSS AST, source locations, transformations, and syntax-aware plugins
postcss-value-parsernpmUse it when the search is confined to declaration values and functions need proper tokenization
postcss-selector-parsernpmUse it when selectors, pseudo-classes, attributes, and selector rewrites are the actual problem