fuzzysort: a JavaScript fuzzy search library with prepared targets and multi-key scoring
Fast SublimeText-like fuzzy search for JavaScript.
At a glance
- What is it?
- fuzzysort is a zero-dependency fuzzy search library for JavaScript, published as v4.0.2 under MIT. It scores and ranks matches, highlights them, and offers snapshot() and prepare() for repeated searches over stable data.
- Who is it for?
- Adopt fuzzysort when you need ranked, highlighted fuzzy matching over a list you already hold in memory and can prepare or snapshot ahead of time. Do not adopt it as a server-side full-text index, and do not expect it to search fields you never passed to key or keys.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 50 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem fuzzysort solves for JavaScript interfaces
A user types ui and expects UserInterface.cpp to appear above Guide.cpp. A substring check cannot do that, because the letters are not contiguous. A regular expression built from the query can match, but it gives you a boolean, not an ordering, and it will not tell you which characters matched so you can bold them.
fuzzysort is aimed at that gap. The README describes it as "Fast, tiny, good fuzzy search for JavaScript" and the package keywords list autocomplete, typeahead and filter alongside fuzzy-search. The intended setting is a client-side list: command palettes, file pickers, dropdown filters, anything where the candidate set is already in memory and the query changes on every keystroke. The package has no runtime dependencies and ships fuzzysort.js, fuzzysort.min.js and index.d.ts, so it works both from a bundler and from a script tag.
It is not a search engine. There is no index on disk, no tokenizer, no persistence and no query language. If your candidates live in a database or a remote API, fuzzysort will not fetch them for you; it ranks an array you hand it.
How fuzzysort.go ranks targets and returns highlights
The entry point is fuzzysort.go(search, targets, options). It returns an array of result objects, each carrying score, target, indexes and obj. The score runs from 0 to 1, where the README says 1 is a perfect match, 0.5 is a good match and 0 is no match. The indexes array holds the positions of the matched characters in the target, which is what makes highlighting possible without re-running the match.
The options object exposes limit, threshold, key, keys and scoreFn. limit caps the number of results and 0 means unlimited; threshold sets the minimum score and 0 accepts any match. key searches a single property of each object, keys searches several, and scoreFn lets you override the final score, for example to multiply by a favourite flag. v4.0.0 notes that scoreFn now works with all search modes, which was not true earlier.
Normalization happens before matching. Searches use NFKD normalization, strip diacritics, and remap common quote, dash, slash, ellipsis and lookalike characters. fuzzysort.remap() adds or overrides mappings, and the README's example is fuzzysort.remap({',': '.'}) so that 12,5 matches 12.5. That behaviour is on by default, which is convenient for prose but means the string you match against is not byte-identical to the string you supplied.
Installing fuzzysort and running a first search
The README gives one install command. It pulls version 4.0.2, which is what package.json declares.
npm i fuzzysortIn a module context you import the default export. There is no named export for go, single, prepare or snapshot; they are properties of the default object.
import fuzzysort from 'fuzzysort'The quick start in the README searches an array of objects by property. Note the option name: key, singular, takes the property to search.
const files = [
{file: 'Guide.cpp'},
{file: 'UserInterface.cpp'},
]
const results = fuzzysort.go('ui', files, {key: 'file'})
results[0].obj.file // 'UserInterface.cpp'After that call, results[0].obj is the original object, not a copy, and results[0].score is a number you can log. If you want the matched characters wrapped in markup, call result.highlight('<b>', '</b>') on a result from fuzzysort.single, which returns one result rather than an array. For a browser without a build step, the README shows a module script pointing at the jsdelivr copy of fuzzysort.min.js.
snapshot, prepare and the cost of re-normalizing every keystroke
The performance section of the README is explicit that the library does work per call that you can move out of the loop. Its first suggestion is to filter out targets you do not need, especially long ones, with a plain array filter before searching.
The second is snapshot(). When the target list does not change, fuzzysort.snapshot(targets, {key: 'file'}) returns a prepared structure that can be searched repeatedly. The README's example runs three queries against the same snapshot.
targets = fuzzysort.snapshot(targets, {key: 'file'})
fuzzysort.go('gotta', targets)
fuzzysort.go('go', targets)
fuzzysort.go('fast', targets)If a snapshot is not possible, the next option is fuzzysort.prepare(), which converts a raw string into a prepared target you store on your own object and then name in the key option.
targets.forEach(t => t.filePrepared = fuzzysort.prepare(t.file))
fuzzysort.go('fast', targets, {key: 'filePrepared'})The trade-off is memory and cache invalidation. A snapshot is a second copy of your data in prepared form, and a prepared property must be recomputed whenever the underlying string changes. That is a real burden in an app where records are edited in place. It is also the reason this library fits a picker over a mostly static list better than a live-updating table.
Multi-key search, custom scoring and where the ranking is opaque
For richer records, fuzzysort.snapshot accepts a keys array whose entries can be property names, dotted paths like meta.desc, or functions that return a string. The README's berry example builds targets from title, meta.desc and a joined tags array, then passes a scoreFn that doubles the score for objects marked favorite.
The result of that call is a nested structure: results[0] is the first target's result set, and result[0].highlight() and result[1].highlight() highlight the first and second key respectively, while result.obj returns the original object. Multi-key highlighting was improved in v4.0.0, and the example shows why it matters: a single query can match the title of one record and the description of another, and you need to know which field produced the hit.
What the README does not give is a written model of the scoring function itself. You get a number between 0 and 1 and a sentence describing the endpoints, but no breakdown of how word boundaries, gaps or prefix matches are weighted. In practice you tune by adjusting threshold and by writing scoreFn rules, not by reasoning about the algorithm. For a typeahead that is usually fine. For a product where ranking is a visible feature, the absence of documentation on the scoring internals is a genuine limitation, and the only authoritative reference is the source in fuzzysort.js.
Cloned results, Web Workers and the fuzzysort.score escape hatch
Result objects carry getters, and the README warns that structured cloning can remove them. That matters if you search inside a Web Worker and post the results back to the main thread, which is a plausible arrangement given that the library is CPU-bound on the main thread otherwise.
For cloned results the README provides two free functions, fuzzysort.score(result) and fuzzysort.highlight(result), added in v4.0.0. They take a plain result object and recompute what the getters would have returned. If you move a search off the main thread, you should plan on using these rather than calling result.highlight() directly.
The v4.0.0 changelog also records that the package moved from UMD to ESM, that default threshold and limit values were added, and that options.all was removed so an empty search now returns results. Anyone upgrading from v3 should treat those as behaviour changes rather than cosmetic ones, particularly the empty-query case, which can turn an idle search box into a full result list.
Alternatives and when fuzzysort is the wrong choice
The related searches around this project include uFuzzy and Microfuzz, which are the natural comparisons. Microfuzz is a much smaller fuzzy matcher aimed at the same in-memory filtering job; the difference is scope. fuzzysort ships a result object with score, indexes, obj and a highlight helper, plus snapshot and prepare for repeated queries and a multi-key mode. A minimal matcher gives you a match and a position and leaves ranking, highlighting and multi-field search to you. If all you need is a yes-or-no test on short strings, the extra surface of fuzzysort is weight you will not use.
If your problem is searching text you do not hold in memory, the right tool is a full-text index such as the ones built into databases, not a JavaScript scorer. fuzzysort will not tokenize, stem or search across documents, and it will not survive a candidate set large enough that shipping it to the client stops being reasonable. The README's own advice to filter out long targets points at the same boundary: this is a ranker for a list you have already decided to keep.
Maintenance, licence and what an upgrade costs
The repository is not archived, and the last push was on 2026-08-13. The licence is MIT, declared in both LICENSE and package.json, which permits use, modification and redistribution provided the copyright notice and permission notice are retained. That is a permissive licence, but it is still worth reading the file rather than taking this summary as legal advice, particularly if you redistribute the minified build inside a product.
The release history retrieved for this project is empty, so the only version signal is package.json at 4.0.2 and the changelog section in the README covering v4.0.0. There is no published migration guide beyond that changelog, and no deprecation policy is documented. The build is simple: npm run build runs terser to produce fuzzysort.min.js and then npm run check, which runs the test script against both the source and the minified file plus the ESM and CommonJS import tests. A fork or an upgrade can be validated with npm test and npm run test-min without any additional setup, which is a low bar for a dependency of this size. The upgrade cost from v3 is the ESM move and the empty-query behaviour change, both of which are stated in the changelog.
Editorial conclusion
Adopt fuzzysort when you need ranked, highlighted fuzzy matching over a list you already hold in memory and can prepare or snapshot ahead of time. Do not adopt it as a server-side full-text index, and do not expect it to search fields you never passed to key or keys. Before committing, run npm test in a checkout and confirm the ranking your own data produces under the default threshold of .5, because the README does not document tuning guidance for that value.
Frequently asked questions
How can I use fuzzy search in JavaScript with fuzzysort?
Install it with npm i fuzzysort, import the default export, and call fuzzysort.go with a query, an array of targets and an options object such as {key: 'file'}. Each result exposes score, target, indexes and obj, and result.highlight() wraps the matched characters in markup.
How does fuzzy match work in fuzzysort?
Targets are normalized with NFKD, diacritics are stripped and common lookalike characters are remapped before matching, and each result receives a score between 0 and 1 where 0.5 is described as a good match. The README does not document the internal weighting of the scoring function.
How do I add fuzzy search to an existing list of objects?
Pass the array to fuzzysort.go with the key option naming the property to search, or use fuzzysort.snapshot with a keys array when several properties should be searched. The result's obj property is a reference to your original object.
What is fuzzysort in JavaScript?
It is a zero-dependency fuzzy search library for JavaScript, described in the README as "Fast, tiny, good fuzzy search for JavaScript". It ranks an array of targets you provide and returns scored results with the indexes of the matched characters.
What is fuzzy search and how does fuzzysort implement it?
Fuzzy search matches a query against a target even when the characters are not contiguous, then orders the candidates by how good the match is. fuzzysort returns a score from 0 to 1 per target and an indexes array for highlighting, with options for limit, threshold, key, keys and scoreFn.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/farzher-fuzzysort)