uFuzzy

A tiny, dependency-free fuzzy search library for matching short phrases against large lists with no index to build.

Library
npm
v1.0.19
3,029stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
46/100Fair
Development Activity0
Maintenance44
Community44
Maturity56
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
59/100Fair
Architecture72
Code Quality32
Innovation78
Learning Curve55

uFuzzy is a micro fuzzy-search library built to match a relatively short search phrase against a large list of short-to-medium strings, the classic shape behind autocomplete, typeahead, and list-filtering UIs. Rather than building and maintaining a search index up front, it compiles the search term into a small set of dynamically-generated regular expressions and runs a fast filter pass over the whole haystack, so startup cost is near zero and there’s nothing to keep in sync as the dataset changes.

It exposes two matching strategies: a default MultiInsert mode that requires every alphanumeric character of the search term to appear in the same order, and a SingleError mode that tolerates one substitution, transposition, insertion, or deletion per term. A three-phase pipeline (filter, then info, then sort) lets callers cheaply prune a huge haystack before paying for the more detailed match statistics and custom ranking used to order the final results, and a search() convenience method chains all three for the common case, including out-of-order multi-term matching and substring exclusions like fruit -green -melon.

What You Get

  • A uFuzzy(opts) factory whose instances expose filter, info, sort, and a combined search() method returning [idxs, info, order]
  • Two matching modes: order-preserving MultiInsert (default) and typo-tolerant SingleError (Damerau-Levenshtein distance of 1 per term)
  • Out-of-order multi-term matching (uf.search(haystack, needle, true)) and multi-substring exclusion syntax (fruit -green -melon)
  • A uFuzzy.highlight() helper that renders matched ranges with a customizable mark/append function, usable for innerHTML, DOM nodes, or JSX
  • A uFuzzy.latinize() utility for stripping accents/diacritics before matching, plus an alpha/unicode option for non-Latin alphabets

Common Use Cases

  • Client-side autocomplete or typeahead search boxes over a fixed list of suggestions
  • Filtering large in-memory lists (file names, command palettes, product titles) as the user types
  • Fuzzy-matching function/symbol names or filenames in developer tools without server round-trips
  • Ranking and highlighting search results with a custom sort function based on match quality stats

Under The Hood

Architecture uFuzzy ships as a single ~1,000-line ES module (src/uFuzzy.mjs) exporting one factory function, uFuzzy(opts), whose returned instance closes over the merged options object rather than relying on classes or dependency injection. Internally it implements a three-phase pipeline: prepQuery() compiles the search phrase into option-driven RegExp templates (governed by flags like intraMode, interLft/interRgt, and intraSlice), filter() runs a cheap RegExp.test() pass to prune the haystack down to candidates, and info() re-matches the survivors with capture-group-heavy RegExps to derive per-candidate statistics (contiguous characters matched, boundary counts, fuzz distance) that a pluggable sort function then uses for final ordering. There is no external state or side effects outside the option object; replacing the RegExp-generation core with an index-based approach (trie, n-gram) would require rewriting info() and sort() together, since ranking is derived directly from regex capture-group positions.

Tech Stack The library is pure, dependency-free JavaScript authored as an ES module and built with Rollup (rollup.config.js) plus @rollup/plugin-terser, producing CJS, ESM, and browser IIFE bundles alongside a hand-maintained TypeScript declaration file (dist/uFuzzy.d.ts). There is no runtime framework, database, or server component — it is published to npm and also usable directly via a <script> tag. The bundled demos (demos/compare.html) are plain HTML/JS pages that benchmark uFuzzy against libraries like fuzzysort, QuickScore, and Fuse.js over a 162,000-entry fixture dataset, with no bundler or framework involved.

Code Quality No test suite is present anywhere in the repository — the package.json test script is a placeholder (echo "Error: no test specified" && exit 1) — and there is no CI workflow configured. Naming is terse but internally consistent, with a systematic intra/inter prefix convention distinguishing allowances within a search term from allowances between terms, and the source carries extensive inline comments explaining non-obvious regex construction and edge cases. There is no linter or formatter configuration (only a bare .editorconfig), and the source itself is plain JavaScript with types provided only via the separately maintained .d.ts file rather than being derived from a typed source.

API Design The public surface is intentionally small: constructing new uFuzzy() with no arguments and calling .search(haystack, needle) covers the common case with zero configuration, while roughly twenty named options (documented in a large README table and typed in uFuzzy.d.ts) let advanced users tune fuzziness rules, boundary strictness, or supply a custom sort/alpha charset for other alphabets. Static helpers (uFuzzy.highlight, uFuzzy.latinize, uFuzzy.permute) hang off the same default export rather than requiring separate imports, and highlight() is generic enough to target innerHTML strings, DOM nodes, or JSX via injectable mark/append callbacks. The tradeoff is that the option names themselves (intraIns, interLft2) are dense and require reading the README table to use confidently beyond the zero-config path.

Used by 5 apps in this directory

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search