fuse.js vs fuzzy vs fuzzy-search vs fuzzyset.js
Client-Side Fuzzy Search Libraries for JavaScript
fuse.jsfuzzyfuzzy-searchfuzzyset.jsSimilar Packages:

Client-Side Fuzzy Search Libraries for JavaScript

fuse.js, fuzzy, fuzzy-search, and fuzzyset.js are JavaScript libraries designed to perform approximate string matching directly in the browser or Node.js environment. They allow users to find relevant results even when their input contains typos or does not exactly match the target data. While they share the same goal, they differ significantly in algorithm complexity, configuration options, and intended use cases — ranging from simple list filtering to complex weighted search across nested objects.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
fuse.js020,453417 kB1a month agoApache-2.0
fuzzy0835-2910 years ago-
fuzzy-search0229-167 years agoISC
fuzzyset.js01,37535.6 kB15 years agosee LICENSE.md

Client-Side Fuzzy Search: fuse.js vs fuzzy vs fuzzy-search vs fuzzyset.js

When building search features, autocomplete inputs, or data filtering tools in JavaScript, exact string matching is rarely enough. Users make typos, forget spacing, or use partial terms. The fuse.js, fuzzy, fuzzy-search, and fuzzyset.js packages solve this problem by allowing approximate matching. However, they approach the task differently. Let's compare how they handle initialization, configuration, and result ranking.

🔍 Core Initialization & Data Input

The way you feed data into these libraries sets the tone for your implementation. Some expect a simple array of strings, while others handle complex objects.

fuse.js accepts an array of strings or objects. It is designed to handle rich data structures out of the box.

import Fuse from 'fuse.js';

const list = [
  { title: "Old Man's War", author: { name: "John Scalzi" } },
  { title: "The Lock Artist", author: { name: "Steve Hamilton" } }
];

const fuse = new Fuse(list, { keys: ['title', 'author.name'] });

fuzzy works primarily with arrays of strings. If you have objects, you must map them to strings first.

import fuzzy from 'fuzzy';

const list = ["John Scalzi", "Steve Hamilton", "Isaac Asimov"];

// No initialization class, just direct function calls
const results = fuzzy.filter("john", list);

fuzzy-search is similar to fuse.js in that it accepts a list of objects and specific keys to search.

import FuzzySearch from 'fuzzy-search';

const list = [
  { name: "John Scalzi", book: "Old Man's War" },
  { name: "Steve Hamilton", book: "The Lock Artist" }
];

const searcher = new FuzzySearch(list, ['name', 'book']);

fuzzyset.js focuses on creating a set of strings to query against. It is optimized for finding the best match from a predefined set.

import FuzzySet from 'fuzzyset.js';

const list = ["John Scalzi", "Steve Hamilton", "Isaac Asimov"];

const set = FuzzySet(list);
// Ready to query immediately

⚙️ Configuration & Weighting

Search relevance is rarely one-size-fits-all. You often need to prioritize certain fields or adjust sensitivity.

fuse.js offers deep configuration. You can assign weights to specific keys and adjust the threshold for what counts as a match.

const fuse = new Fuse(list, {
  keys: [
    { name: 'title', weight: 0.8 },
    { name: 'author.name', weight: 0.2 }
  ],
  threshold: 0.4, // 0.0 is exact, 1.0 matches anything
  includeScore: true
});

fuzzy has minimal configuration. It relies on the underlying algorithm's defaults. You cannot easily weight specific parts of the string.

// No config object passed during filtering
const results = fuzzy.filter("scalzi", list, {
  // Limited options, mostly for pre-processing
  pre: (str) => str.toLowerCase()
});

fuzzy-search allows some options during initialization, such as case sensitivity, but lacks the granular weighting of fuse.js.

const searcher = new FuzzySearch(list, ['name'], {
  caseSensitive: false,
  sort: true
});

fuzzyset.js allows you to adjust the minimum match score when querying. It does not support field weighting since it treats items as single strings.

// Second argument is the minimum match score (0 to 1)
const results = set.get("John Scalzi", 0.5);
// Returns array of [score, string] pairs

📦 Return Values & Data Shape

Understanding the output format is critical for integrating search results into your UI.

fuse.js returns an array of result objects containing the item, its index, and a relevance score.

const results = fuse.search("scalzi");
// Output: [{ item: {...}, refIndex: 0, score: 0.15 }, ...]

fuzzy returns an array of objects containing the original string, the matched index, and the rendered string with highlights.

const results = fuzzy.filter("john", list);
// Output: [{ string: "John Scalzi", index: 0, matched: [0,1,2,3], ... }]

fuzzy-search returns the original objects from your list that matched the query.

const results = searcher.search("john");
// Output: [{ name: "John Scalzi", book: "Old Man's War" }, ...]

fuzzyset.js returns an array of arrays containing the score and the matched string. You often need to map this to a usable format.

const results = set.get("scalzi");
// Output: [[0.85, "John Scalzi"], [0.4, "Steve Hamilton"]]

🛠️ Maintenance & Ecosystem Status

Long-term support matters when choosing a dependency for production apps.

fuse.js is actively maintained with regular updates. It has a large community and extensive documentation. It is the safest choice for new projects.

// Importing from modern bundle
import Fuse from 'fuse.js';

fuzzy is stable but sees infrequent updates. It is a "set it and forget it" library that works well for simple tasks but lacks modern features.

// CommonJS or ES module support is standard
import fuzzy from 'fuzzy';

fuzzy-search has seen periods of inactivity. Before using, check the repository for recent commits. It may require forks or patches for modern build tools.

// Verify package health before installing
import FuzzySearch from 'fuzzy-search';

fuzzyset.js is older and primarily maintained for stability. It is not deprecated but is not evolving rapidly. It remains the go-to for Levenshtein-based correction.

// Standard import
import FuzzySet from 'fuzzyset.js';

📊 Summary: Key Differences

Featurefuse.jsfuzzyfuzzy-searchfuzzyset.js
Best ForComplex searchSimple filteringObject searchTypo correction
Data InputStrings or ObjectsStringsObjectsStrings
Weighting✅ Advanced❌ None⚠️ Basic❌ None
Return TypeRich Result ObjectMatch ObjectOriginal Item[Score, String]
Maintenance🟢 Active🟡 Stable🟠 Check Status🟡 Stable

💡 The Big Picture

fuse.js is the heavy lifter 🏋️. Use it when search quality is a core feature of your app. It handles nested data and scoring better than the rest.

fuzzy is the utility knife 🔪. Keep it in your back pocket for quick scripts or simple filters where adding a heavier dependency is not worth it.

fuzzy-search is the middle ground ⚖️. It structures data like fuse.js but with less configuration. Use it if fuse.js feels too complex, but verify maintenance first.

fuzzyset.js is the specialist 🎯. Use it when you need to correct a user's input to the closest known value, rather than returning a list of matches.

Final Thought: For most modern frontend applications, fuse.js provides the best balance of power and ease of use. Reserve the others for specific constraints like bundle size or unique algorithmic needs.

How to Choose: fuse.js vs fuzzy vs fuzzy-search vs fuzzyset.js

  • fuse.js:

    Choose fuse.js if you need a robust, feature-rich search engine for complex data structures. It supports weighted searches across nested object keys, custom scoring, and filtering. It is the industry standard for applications requiring high-quality search results with minimal setup.

  • fuzzy:

    Choose fuzzy if you need a lightweight, no-frills solution for simple string matching. It is ideal for basic filtering tasks where you do not need to search across multiple object properties or configure scoring thresholds. It works well for small lists and straightforward use cases.

  • fuzzy-search:

    Choose fuzzy-search if you want a middle ground between simplicity and structure. It allows searching across specific keys in a list of objects without the extensive configuration of fuse.js. However, verify its maintenance status before adopting, as it receives fewer updates than fuse.js.

  • fuzzyset.js:

    Choose fuzzyset.js if your primary goal is typo correction or finding the single closest match rather than filtering a list. It uses Levenshtein distance to rank results by similarity score. It is best suited for autocomplete suggestions or data deduplication tasks.

README for fuse.js

Fuse.js

Node.js CI Version Downloads code style: prettier Contributors License

Fuse.js is a lightweight, zero-dependency fuzzy-search library written in TypeScript. It works in the browser and on the server, and is designed for searching small-to-medium datasets on the client side where you can't rely on a dedicated search backend.

✨ What's New: Token Search

Multi-word fuzzy search with relevance ranking. Type "javascrpt paterns" and find "JavaScript Patterns" — typo tolerance, multiple words, and smart ranking all at once.

const fuse = new Fuse(docs, {
  useTokenSearch: true,
  keys: ['title', 'author', 'description']
})

fuse.search('javascrpt paterns')
// → [{ item: { title: 'JavaScript Patterns', ... } }]

See Token Search below for details.

Web Workers

Search large datasets without freezing the UI. FuseWorker splits your data across multiple Web Workers and searches in parallel — ~5x faster on 100K documents.

import { FuseWorker } from 'fuse.js/worker'

const fuse = new FuseWorker(docs, {
  keys: ['title', 'author', 'description']
})

const results = await fuse.search('query')
fuse.terminate()

Same options and results as Fuse — just async. Function-valued options (sortFn, getFn, keys[].getFn) aren't supported because functions can't be transferred to a worker; everything else carries over. See the Web Workers docs for the interactive demo and full API.

Installation

npm install fuse.js
yarn add fuse.js

Or include directly via CDN:

<script src="https://cdn.jsdelivr.net/npm/fuse.js/dist/fuse.min.mjs"></script>

Quick Start

import Fuse from 'fuse.js'

const books = [
  { title: "Old Man's War", author: 'John Scalzi' },
  { title: 'The Lock Artist', author: 'Steve Hamilton' },
  { title: 'HTML5', author: 'Remy Sharp' },
  { title: 'JavaScript: The Good Parts', author: 'Douglas Crockford' }
]

const fuse = new Fuse(books, {
  keys: ['title', 'author']
})

fuse.search('javscript')
// → [{ item: { title: 'JavaScript: The Good Parts', ... }, ... }]

Features

Fuzzy Search

The core of Fuse.js. Uses the Bitap algorithm for approximate string matching — handles typos, misspellings, and partial matches out of the box.

fuse.search('javscript')
// → [{ item: { title: 'JavaScript: The Good Parts', author: 'Douglas Crockford' } }]

Weighted Keys

Search across multiple fields with different importance levels. Title matches can rank higher than description matches.

const fuse = new Fuse(docs, {
  keys: [
    { name: 'title', weight: 2 },
    { name: 'description', weight: 1 }
  ]
})

Extended Search

Use operators for precise control: exact match (=), prefix (^), suffix (!), and more. Enable with useExtendedSearch: true.

const fuse = new Fuse(list, {
  useExtendedSearch: true,
  keys: ['title']
})

fuse.search('=exact match')   // exact match
fuse.search('^prefix')        // starts with
fuse.search('!term')          // does not include

Token Search

Splits multi-word queries into individual terms, fuzzy-matches each independently, and ranks results using BM25-style IDF weighting. Enable with useTokenSearch: true.

const fuse = new Fuse(docs, {
  useTokenSearch: true,
  keys: ['title', 'body']
})

fuse.search('express midleware rout')
// Finds "Express Middleware" and "Express Routing Guide" despite typos
  • Typo tolerance per word — each term is fuzzy-matched independently
  • Relevance ranking — rare terms are weighted higher than common ones
  • Word order independent — "patterns javascript" and "javascript patterns" return identical results
  • No query length limit — long multi-word queries work naturally since each term is searched separately
  • AND or OR — tokenMatch: 'all' returns only records matching every word (filtering); the default 'any' matches any word
  • Custom tokenizer — pass a regex or function via tokenize for tokens with internal punctuation (node.js, c++), or use Intl.Segmenter for CJK / Thai word segmentation. Unicode-aware by default

Available in the full build. See the Token Search docs for details and performance benchmarks.

Logical Search

Combine conditions with $and and $or for complex queries. Available in the full build.

fuse.search({
  $and: [
    { title: 'javascript' },
    { author: 'crockford' }
  ]
})

Match Highlighting

Get character-level match indices for highlighting search results in your UI.

const fuse = new Fuse(list, {
  includeMatches: true,
  keys: ['title']
})

const result = fuse.search('javscript')
// result[0].matches[0].indices → [[0, 9]]

Single String Matching

Use Fuse.match() to fuzzy-match a pattern against a single string without creating an index. Useful for one-off comparisons or custom filtering.

const result = Fuse.match('javscript', 'JavaScript: The Good Parts')
// → { isMatch: true, score: 0.04, indices: [[0, 9]] }

Fuse.match() does not support useTokenSearch — token search requires corpus-level statistics (df, fieldCount) that a one-off string comparison can't provide. Passing useTokenSearch: true throws an explicit error. Use new Fuse(docs, { useTokenSearch: true }).search(query) for token-search behavior.

Dynamic Collections

Add and remove documents from a live index without rebuilding.

fuse.add({ title: 'New Book', author: 'New Author' })
fuse.remove((doc) => doc.title === 'Old Book')

Builds

Fuse.js ships in two variants:

BuildIncludesMin + gzip
FullFuzzy + Extended + Logical + Token search~8.6 kB
BasicFuzzy search only~6.8 kB

Use the basic build if you only need fuzzy search and want the smallest bundle size.

Documentation

For the full API reference, configuration options, scoring theory, and interactive demos, visit fusejs.io.

Official ports

  • fuse-swift: Swift port for iOS, macOS, tvOS, watchOS, visionOS, and Linux. Byte-equivalent results, idiomatic Swift API, syncs with each upstream release. Currently in 2.0.0-rc.1.

Supporting Fuse.js

Develop

See DEVELOPERS.md for setup, scripts, and project structure.

Contribute

See CONTRIBUTING.md for guidelines on issues and pull requests.