Fuse README

The project's README from github.com/krisk/Fuse. As one markdown file: README.md.

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.

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

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 }
  ]
})

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

Object Query Syntax

Prefer a structured, self-documenting alternative to the magic characters? Express the same operators as an object. Unlike the string form, this needs no useExtendedSearch flag (the operators are unambiguous), autocompletes in TypeScript, and needs no quoting or escaping.

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

fuse.search({ title: { $startsWith: 'old' }, author: { $eq: 'Kay' } })

Each operator maps to a string equivalent:

Object String Matches when the field
$fuzzy term fuzzy-matches (typo tolerant)
$eq =term equals the value
$contains 'term contains the value
$startsWith ^term starts with the value
$endsWith term$ ends with the value

Negate with $not, which wraps exactly one of $contains, $startsWith, or $endsWith:

fuse.search({ title: { $not: { $contains: 'draft' } } }) // === '!draft'
fuse.search({ title: { $not: { $startsWith: 'old' } } }) // === '!^old'
fuse.search({ title: { $not: { $endsWith: '.go' } } }) // === '!.go$'

Multiple operators on one field are AND-ed; use field-local $and / $or for more, and compose across fields with logical search:

// starts with "old" AND does not contain "draft"
fuse.search({ title: { $startsWith: 'old', $not: { $contains: 'draft' } } })

// title starts with "old" OR ends with "war"
fuse.search({ title: { $or: [{ $startsWith: 'old' }, { $endsWith: 'war' }] } })

Object queries return identical results to the equivalent string query, and validate strictly: unknown operators, empty or non-string values, and illegal nesting throw instead of silently degrading to a fuzzy search. Available in the full build. See the Extended Search docs for the full grammar.

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

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

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:

Build Includes Min + gzip
Full Fuzzy + Extended + Logical + Token search ~8.6 kB
Basic Fuzzy 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

Supporting Fuse.js

Develop

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

Contribute

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

Fuse (krisk/Fuse)

text
Searching Database…

20.5K ·GitHub
What is this?Fuse.js is a lightweight, zero-dependency fuzzy-search library for JavaScript and TypeScript. It runs in the browser and on Node, and is built for searching small-to-medium datasets client-side instead of standing up a dedicated search backend.
So is it a library I bundle into my own code, not a hosted service?Right — it's a library you import into your own JavaScript project, with no server component. You index your data in memory and call .search() wherever the code runs, browser or server.
How do I add it to a project?Install from npm (npm install fuse.js) or include it directly via a CDN, then wrap your data with new Fuse(docs, options) and call .search(query).
Does it pull in other packages or need anything special?No — it has zero runtime dependencies. Any modern browser works, and on the server Node.js 10 or newer is enough.
How big can my dataset be before it's a bad fit?It targets small-to-medium client-side datasets where you don't have a dedicated search backend. For large sets — around 100K documents — use FuseWorker to search in parallel instead of the main thread.
What is Token Search?An opt-in mode (useTokenSearch: true) for multi-word queries: each word is fuzzy-matched independently and results are ranked with BM25-style IDF weighting, so rare terms count more and word order doesn't matter. Type 'javascrpt paterns' and it still finds 'JavaScript Patterns'.
Can it do exact filters, not just fuzzy matching?Yes — extended search adds operators like exact match (=) and prefix (^), combinable with $and/$or. There's also an object query syntax ($eq, $startsWith, $not) that needs no flag and throws on invalid input instead of silently degrading to fuzzy search.
Can I add or remove documents without rebuilding the index?Yes — dynamic collections let you add and remove documents from a live index without rebuilding it.
Is there a version for Swift or iOS apps?Yes — fuse-swift is an official port for iOS, macOS, tvOS, watchOS, visionOS and Linux, with byte-equivalent results and an idiomatic Swift API. It's currently at 2.0.0-rc.1.
Creator
krisk
Size
11.1 MB
Stars
20.5K
Age
14y
Commits · 90 Days