Fuzzy Search
Fuse.js uses a modified Bitap algorithm for approximate string matching. It finds strings that are approximately equal to a given pattern — tolerating typos, transpositions, and missing characters.
const fuse = new Fuse(['apple', 'banana', 'orange'], {
includeScore: true
})
fuse.search('aple')
// [{ item: 'apple', refIndex: 0, score: 0.25 }]
How It Works
The Bitap algorithm computes the edit distance between the search pattern and each position in the text. The implementation uses bitwise operations for speed, with a pattern length limit of 32 characters per search term.
The algorithm produces a fuzziness score between 0 and 1:
0— perfect match1— complete mismatch
This score is then combined with key weight and field-length norm to produce the final relevance score.
Controlling Fuzziness
Three options work together to determine what counts as a match:
threshold
- Default:
0.6
The cutoff for the fuzziness score. A threshold of 0.0 requires a perfect match. A threshold of 1.0 matches anything.
// Strict matching
const fuse = new Fuse(list, { keys: ['title'], threshold: 0.2 })
// Permissive matching
const fuse = new Fuse(list, { keys: ['title'], threshold: 0.8 })
location
- Default:
0
The expected position of the pattern in the text. The algorithm penalizes matches that are far from this position.
distance
- Default:
100
How far from location a match can be before being penalized to the point of exclusion. The effective search window is:
threshold × distance = maximum offset from location
With defaults (threshold: 0.6, distance: 100), the pattern must appear within 60 characters of position 0 to match. For example, searching for "zero" in "Fuse.js is a powerful, lightweight fuzzy-search library, with zero dependencies" would not match — "zero" appears at index 62, just outside the window.
ignoreLocation
- Default:
false
When true, disables location-based scoring entirely. The pattern can appear anywhere in the text and still match. This is useful when you don't know or care where the match might be.
const fuse = new Fuse(list, {
keys: ['description'],
ignoreLocation: true
})
TIP
The default options effectively search only the first ~60 characters of each field. If your data has long text fields, either increase distance, or set ignoreLocation: true.
Other Options
isCaseSensitive
- Default:
false
When true, comparisons are case-sensitive.
ignoreDiacritics
- Default:
false
When true, comparisons ignore diacritics (accents). For example, é matches e.
findAllMatches
- Default:
false
When true, the algorithm continues searching to the end of the text even after finding a perfect match. Useful when you need all match indices for highlighting.
minMatchCharLength
- Default:
1
Only return matches whose length exceeds this value. Set to 2 to ignore single-character matches.
Scoring
The final relevance score for a result combines three factors:
- Fuzziness score — the raw Bitap score described above
- Key weight — optional per-key
weight(defaults to1). Higher weight = more influence on ranking. Weights are normalized internally. - Field-length norm — shorter fields rank higher. A match in a title is more significant than the same match in a long description.
Scores range from 0 (perfect match) to 1 (complete mismatch). Enable with includeScore: true.
ignoreFieldNorm
- Default:
false
When true, field length has no effect on scoring. Useful when you only care whether a term exists, not how prominent it is.
fieldNormWeight
- Default:
1
Adjusts the strength of the field-length norm. 0 is equivalent to ignoring it. 0.5 reduces the effect. 2.0 amplifies it.
