
Fuzzysort is a dependency-free JavaScript fuzzy search library that ranks approximate matches in strings and object data. It’s ideal for client-side search, live filters, command palettes, autocomplete, and other UI where your users rarely type an exact value.
The library exposes a compact API for single-string matching, multi-field object search, result highlighting, custom scoring, and repeated searches over static datasets. Current builds use ES modules and include TypeScript declarations.
Features:
- Ranked fuzzy matching for strings and object fields.
- Single-key and multi-key object search.
- Character-level match indexes and custom highlighting.
- Custom score functions for project-specific ranking.
- Immutable snapshots for repeated searches over static data.
- Prepared targets for reusable search data.
- Unicode normalization, diacritic stripping, and character remapping.
- Helpers for search results returned from Web Workers.
- ES module packaging and TypeScript declarations.
- Zero runtime dependencies.
Use Cases:
- Command palettes match commands from partial or mistyped input.
- Documentation search checks titles, headings, tags, and other local metadata.
- Product and file pickers rank close matches as users type.
- Autocomplete fields highlight the characters that matched a query.
How to use it:
Installation
Install fuzzysort from npm in projects that use a bundler or native ES module imports.
# NPM $ npm install fuzzysort
import fuzzysort from 'fuzzysort';
Browser-only projects can import the minified ES module from jsDelivr.
<script type="module"> import fuzzysort from 'https://cdn.jsdelivr.net/npm/fuzzysort/fuzzysort.min.js'; </script>
Basic Usage
Pass a query, an array of searchable values, and an optional configuration object to fuzzysort.go(). Object collections use key or keys to identify the searchable fields.
const pages = [
{ title: 'JavaScript Date Picker', category: 'Forms' },
{ title: 'Responsive Image Gallery', category: 'Gallery' },
{ title: 'Keyboard Shortcut Manager', category: 'Utility' },
];
const results = fuzzysort.go('date piker', pages, {
key: 'title',
});
results.forEach((result) => {
console.log(result.obj.title, result.score);
});Search a List of Strings
Plain string arrays need no key configuration. Each returned result exposes the original string through result.target.
const commands = [
'Open Settings',
'Preview Page',
'Publish Draft',
'Clear Cache',
];
const results = fuzzysort.go('publsh', commands, {
limit: 5,
});
console.log(results.map((result) => result.target));Search Multiple Object Fields
Use keys when a query should match several properties. Keys can use property paths or getter functions for values that need preprocessing.
const products = [
{
name: 'Wireless Keyboard',
category: 'Computer Accessories',
tags: ['bluetooth', 'portable'],
featured: true,
},
{
name: 'Mechanical Keypad',
category: 'Input Devices',
tags: ['wired', 'compact'],
},
];
const results = fuzzysort.go('wireles input', products, {
keys: [
'name',
'category',
(product) => product.tags?.join(' '),
],
scoreFn: (result) =>
result.score * (result.obj.featured ? 1.15 : 1),
});
const bestMatch = results[0];
console.log(bestMatch.obj.name);
console.log(bestMatch.score);Highlight Fuzzy Matches
Each normal result exposes highlight(). Pass opening and closing strings to wrap the matched characters in your own markup.
const result = fuzzysort.single('javascrpt', 'JavaScript search library');
if (result) {
const highlighted = result.highlight('<mark>', '</mark>');
console.log(highlighted);
}A callback can return custom values for component-based rendering.
const parts = result.highlight((match, index) => ({
type: 'match',
key: index,
text: match,
}));Speed Up Repeated Searches With snapshot()
Static datasets benefit from fuzzysort.snapshot(). Create the snapshot once, then reuse it for subsequent queries.
const searchIndex = fuzzysort.snapshot(products, {
keys: ['name', 'category'],
});
const firstResults = fuzzysort.go('wireles', searchIndex, {
limit: 8,
threshold: 0.45,
});
const secondResults = fuzzysort.go('keyboard', searchIndex, {
limit: 8,
threshold: 0.45,
});Prepare Individual Targets
fuzzysort.prepare() prepares reusable target strings when an immutable snapshot does not fit the data flow.
const entries = [
{ label: 'Account Settings' },
{ label: 'Notification Settings' },
{ label: 'Billing Settings' },
];
entries.forEach((entry) => {
entry.searchLabel = fuzzysort.prepare(entry.label);
});
const results = fuzzysort.go('notif set', entries, {
key: 'searchLabel',
});Customize Character Remapping
Fuzzysort applies NFKD normalization, strips diacritics, and remaps common lookalike characters during search. Add or replace a mapping with fuzzysort.remap().
fuzzysort.remap({
',': '.',
});
const results = fuzzysort.go('12.5', ['12,5', '8,4', '20,0']);Use Results From a Web Worker
Structured cloning can remove getter behavior from result objects. Use the top-level score() and highlight() helpers after a result crosses a worker boundary.
const workerResult = structuredClone(
fuzzysort.single('seting', 'Application Settings')
);
const score = fuzzysort.score(workerResult);
const highlighted = fuzzysort.highlight(
workerResult,
'<mark>',
'</mark>'
);All Configuration Options
limit(number): Sets the maximum number of returned results. Defaults to10. Set it to0for no limit.threshold(number): Sets the minimum accepted score. Defaults to0.5. Set it to0to accept any match.key(string, path array, or function): Selects one searchable value from each object.keys(array): Selects multiple searchable values from each object. Each entry accepts the same key formats askey.scoreFn(function): Replaces the result score used for ranking.
Result Data
Normal results expose the score, original target, and matched character indexes. Object searches also expose the original object. Multi-key searches return one result entry per searched key. The parent result also exposes a combined score and the original obj.
const result = results[0]; result.score; // 1 = exact match, 0.5 = good match, 0 = no match result.target; // original matched string result.indexes; // matched character indexes result.obj; // original object when object search is used results.total; // matches found before the limit is applied
API Methods
// Match one query against one target. fuzzysort.single(search, target); // Search a list, object collection, or snapshot. fuzzysort.go(search, targets, options); // Prepare one target string for reuse. fuzzysort.prepare(target); // Create an immutable search snapshot. fuzzysort.snapshot(targets, options); // Highlight a normal or structured-cloned result. fuzzysort.highlight(result, highlightOpen, highlightClose); // Read the score from a normal or structured-cloned result. fuzzysort.score(result); // Add or override character mappings used during normalization. fuzzysort.remap(mappings); // Clear fuzzysort's internal caches. fuzzysort.cleanup();
fuzzysort vs Fuse.js
Both libraries handle client-side fuzzy search and object fields. Their APIs target different levels of search configuration. Fuzzysort suits compact local-search flows that need ranked fuzzy matches, direct highlighting, and reusable static search data. Fuse.js is worth comparing when your project needs field weights, advanced query operators, logical conditions, or a mutable search index.
| Area | Difference |
|---|---|
| Core API | fuzzysort centers on direct ranked matching with a small set of search functions. Fuse.js exposes a broader configuration surface. |
| Object search | Both search object fields. Fuse.js adds field weighting and structured query features. |
| Highlighting | fuzzysort returns matched indexes and includes result highlighting helpers. Fuse.js exposes match ranges when match data is enabled. |
| Repeated static searches | fuzzysort provides immutable snapshots and prepared targets. Fuse.js supports pre-built indexes. |
| Advanced query rules | Fuse.js supports extended operators, logical queries, and dynamic index updates. fuzzysort keeps the query model more focused. |
Alternatives:
- Fuzzy Search Library for Client-Side JavaScript – Fuse.js
- Fuzzy Search & Autocomplete Library For JavaScript – fuzzy-search
- Simple Performant Fuzzy Search Library – Microfuzz
FAQs:
Q: Does fuzzysort create an autocomplete or search UI?
A: No. Fuzzysort ranks fuzzy matches and returns search data. Your application provides the input, result list, keyboard interactions, and styles.
Q: How do I search several fields in each object?
A: Pass a keys array to fuzzysort.go() or fuzzysort.snapshot(). Keys accept property paths and getter functions.
Q: Why am I getting too many weak matches?
A: Increase the threshold above its default value of 0.5. Set a practical limit as well when the interface only displays a small result set.
Q: How should I search the same large static dataset repeatedly?
A: Create one immutable dataset with fuzzysort.snapshot() and reuse it for each query. Use fuzzysort.prepare() for reusable individual targets when snapshotting does not fit the data flow.
Changelog:
v4.0.2 (08/12/2026)
- Switched the package from UMD to ESM.
- Added
fuzzysort.snapshot()for repeated searches over static targets. - Added
fuzzysort.score()andfuzzysort.highlight()for structured-cloned results. - Added
fuzzysort.remap()for custom character normalization. - Added automatic remapping for common lookalike characters.
- Added default values for
thresholdandlimit. - Improved multi-key highlighting and substring scoring.
- Removed
options.all. Empty searches now return results. - Extended
scoreFnsupport across search modes.







