mrkeyoor.com_
Sat 08 Aug 20:59 UTC
npmUtilsupdated 08 Aug 2026

fuzzy

fuzzy is a tiny CommonJS utility for subsequence matching. Give it a short pattern such as `bcn` and a list of strings, and it keeps entries whose characters appear in that order, scores consecutive matches more highly, and can wrap the matched characters for display. It works in Node and through a direct browser script, but it is a simple filter and highlighter, not typo correction, token search, indexing, or natural-language search.

Verdict

Install it only for a tiny legacy-friendly subsequence filter whose limitations are acceptable. Fuse.js or fuzzysort is a better default when ranking quality, multi-field data, TypeScript ergonomics, or active maintenance matters.

API stability4/5The public surface is only `test`, `match`, `filter`, and `simpleFilter`, and version 0.1.3 has preserved that shape since 2016. That makes accidental churn unlikely, but the confidence comes from inactivity rather than a stated compatibility policy, and quirks such as first-occurrence matching are effectively frozen alongside the API.
Docs3/5The README explains string filtering, highlighting, object extraction, browser use, result fields, and the scoring limitation with runnable examples. The source and tests cover the remaining behavior, but there is no separate API reference, performance guidance, security note for HTML wrappers, or modern ESM and TypeScript setup documentation.
Maintenance1/5The latest npm release is 0.1.3 from October 2016 and GitHub reports the last repository push in December 2021. The repository is not archived and npm does not mark the package deprecated, but its README still carries unresolved algorithm, multi-field, asynchronous batching, and performance TODOs, so users should treat it as dormant.
Ecosystem3/5The package recorded 5,050,566 downloads for the measured week and has no runtime dependencies, so it remains deeply embedded in dependency trees. Its ecosystem surface is otherwise narrow: CommonJS plus a direct browser file, a small bundled declaration, no plugins, no framework adapters, and no indexing or worker integration.

Use it if

  • You need a very small, dependency-free subsequence filter for a command palette or short in-memory list
  • You want match positions rendered with configurable prefix and suffix strings without writing a highlighter
  • Your data is objects and a synchronous extract function can select the one string to search
  • You maintain CommonJS or direct-script code and do not need a modern module build
Skip it if

Setup reality

Installation is only `npm install fuzzy`; there are no runtime dependencies, native builds, peer dependencies, credentials, or configuration files. The friction is age and API shape. The package exports CommonJS, so native ESM projects normally use a default import backed by Node interoperability, while older TypeScript settings may require `import fuzzy = require('fuzzy')`. A declaration file is included, but it models the small 2016 API rather than providing modern generics and rich option types. Matching is synchronous and scans every candidate, then `filter` sorts every match by score, so put debouncing or list limits around browser search boxes yourself. Highlight output is created by concatenating the `pre` and `post` strings into the original text. If those wrappers are HTML, render only trusted source strings or escape them first; the library does no sanitization. Matching is case-insensitive unless `caseSensitive: true`, accepts only one extracted string per object, and returns result objects rather than the original array. Empty patterns match everything, a non-string pattern passed to `filter` returns the input array itself, and a failed `match` returns `null`. Those details are easy to miss because the README is the complete documentation and the last release predates current Node module conventions.

Patterns

Filter and rank a list of stringsfilter-strings

const fuzzy = require('fuzzy');

const results = fuzzy.filter('bcn', [
  'baconing',
  'narwhal',
  'a mighty bear canoe',
]);
const matches = results.map((result) => result.original);

Results are sorted by descending score and contain `string`, `score`, `index`, and `original`; they are not the original values directly.

Check whether one string matchestest-one-string

const matches = fuzzy.test('bcn', 'a mighty bear canoe');
console.log(matches); // true

This is ordered subsequence matching: all pattern characters must appear in order, but they do not need to be adjacent.

Read one match scoreinspect-match

const match = fuzzy.match('abc', 'a-b-c');

if (match) {
  console.log(match.rendered); // a-b-c
  console.log(match.score);
}

`match` returns `null` when the pattern fails; exact matches receive `Infinity` as their score.

Wrap matching charactershighlight-match

const result = fuzzy.match('bcn', 'baconing', {
  pre: '<mark>',
  post: '</mark>',
});

console.log(result?.rendered);

The returned string is not sanitized. Escape untrusted candidate text before inserting HTML wrappers and rendering it.

Search objects through one fieldfilter-objects

const commands = [
  { id: 'open', label: 'Open file' },
  { id: 'close', label: 'Close editor' },
];

const results = fuzzy.filter('of', commands, {
  extract: (command) => command.label,
});
console.log(results[0].original.id);

`extract` must return one string. The library cannot assign weights to several fields or report which field matched.

Require matching letter casecase-sensitive-match

const exactCase = fuzzy.match('Ab', 'Abacus', {
  caseSensitive: true,
});
const wrongCase = fuzzy.match('Ab', 'abacus', {
  caseSensitive: true,
}); // null

Matching is case-insensitive by default; set `caseSensitive` on `match` or `filter` when case carries meaning.

Return only matching stringssimple-filter

const values = fuzzy.simpleFilter('ab', [
  'alphabet',
  'cab',
  'clock',
]);
console.log(values); // ['alphabet', 'cab']

`simpleFilter` preserves input order and discards scores and highlighting; use `filter` when ranking matters.

Limit work shown by an autocompletelimit-results

function searchCommands(query, commands) {
  if (!query) return commands.slice(0, 20);
  return fuzzy
    .filter(query, commands, { extract: (item) => item.label })
    .slice(0, 20)
    .map((result) => result.original);
}

The limit is applied after the package filters and sorts the whole list, so it limits rendering but not matching cost.

Debounce synchronous browser filteringdebounce-browser-search

let timer;
input.addEventListener('input', (event) => {
  clearTimeout(timer);
  timer = setTimeout(() => {
    const results = fuzzy.filter(event.target.value, labels);
    render(results.slice(0, 25));
  }, 100);
});

The package has no asynchronous or worker API. Debouncing reduces repeated calls but a large single search can still block the main thread.

Use the CommonJS package from Node ESMesm-import

import fuzzy from 'fuzzy';

const found = fuzzy.filter('cfg', ['config.js', 'package.json']);

There is no native ESM export. This default import relies on Node's CommonJS interoperability and may need bundler-specific interop settings.

Alternatives

PackageRegistryPick it when
fuzzysortnpmYou want fast fuzzy ranking, match indexes, and a browser-oriented API for larger candidate sets
fuse.jsnpmYou need typo tolerance, weighted multi-key object search, thresholds, and a maintained search index
fast-fuzzynpmYou want a maintained TypeScript-friendly matcher with configurable normalization and sorting