fuzzysort: Fast Fuzzy Search Library for Vanilla JavaScript

Category: Javascript , Recommended | August 12, 2026
Authorfarzher
Last UpdateAugust 12, 2026
LicenseMIT
Views2,013 views
fuzzysort: Fast Fuzzy Search Library for Vanilla JavaScript

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 to 10. Set it to 0 for no limit.
  • threshold (number): Sets the minimum accepted score. Defaults to 0.5. Set it to 0 to 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 as key.
  • 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.

AreaDifference
Core APIfuzzysort centers on direct ranked matching with a small set of search functions. Fuse.js exposes a broader configuration surface.
Object searchBoth search object fields. Fuse.js adds field weighting and structured query features.
Highlightingfuzzysort returns matched indexes and includes result highlighting helpers. Fuse.js exposes match ranges when match data is enabled.
Repeated static searchesfuzzysort provides immutable snapshots and prepared targets. Fuse.js supports pre-built indexes.
Advanced query rulesFuse.js supports extended operators, logical queries, and dynamic index updates. fuzzysort keeps the query model more focused.

Alternatives:

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() and fuzzysort.highlight() for structured-cloned results.
  • Added fuzzysort.remap() for custom character normalization.
  • Added automatic remapping for common lookalike characters.
  • Added default values for threshold and limit.
  • Improved multi-key highlighting and substring scoring.
  • Removed options.all. Empty searches now return results.
  • Extended scoreFn support across search modes.

You Might Be Interested In:


Leave a Reply