Core fuzzy search functionality for finding approximate matches in collections of strings or objects using the Bitap algorithm. Provides configurable matching, scoring, and result formatting with support for both simple and complex data structures.
Creates a new Fuse search instance with data and configuration options.
/**
* Creates a new Fuse search instance
* @param list - Array of items to search (strings or objects)
* @param options - Search configuration options
* @param index - Optional pre-built FuseIndex for performance
*/
constructor(
list: ReadonlyArray<T>,
options?: IFuseOptions<T>,
index?: FuseIndex<T>
);Usage Examples:
import Fuse from "fuse.js";
// String array search
const fruits = ["apple", "banana", "cherry", "grape"];
const fruitFuse = new Fuse(fruits);
// Object array search with keys
const users = [
{ name: "John Doe", email: "john@example.com" },
{ name: "Jane Smith", email: "jane@example.com" }
];
const userFuse = new Fuse(users, { keys: ["name", "email"] });
// Complex configuration
const bookFuse = new Fuse(books, {
keys: ["title", "author", "genre"],
threshold: 0.3,
includeScore: true,
includeMatches: true
});Performs fuzzy search on the dataset with optional search-time configuration.
/**
* Performs fuzzy search on the dataset
* @param pattern - Search pattern (string or logical expression)
* @param options - Optional search-time configuration
* @returns Array of search results with items and metadata
*/
search<R = T>(
pattern: string | Expression,
options?: FuseSearchOptions
): FuseResult<R>[];Usage Examples:
// Basic string search
const results = fuse.search("javascript");
// Limited results
const limitedResults = fuse.search("react", { limit: 5 });
// Complex logical expressions (requires useExtendedSearch: true)
const logicalResults = fuse.search({
$and: [
{ title: "javascript" },
{ author: "crockford" }
]
});Structure of search results returned by the search method.
interface FuseResult<T> {
/** The matched item from the original dataset */
item: T;
/** Original index of the item in the source array */
refIndex: number;
/** Match score (0 = perfect match, 1 = no match) */
score?: number;
/** Match details for highlighting (when includeMatches: true) */
matches?: ReadonlyArray<FuseResultMatch>;
}
interface FuseResultMatch {
/** Character ranges of matches for highlighting */
indices: ReadonlyArray<RangeTuple>;
/** Field name that matched (for object searches) */
key?: string;
/** Reference index for array fields */
refIndex?: number;
/** Matched text value */
value?: string;
}
type RangeTuple = [number, number];Usage Examples:
const results = fuse.search("pattern", { includeScore: true, includeMatches: true });
results.forEach(result => {
console.log(`Item: ${result.item}`);
console.log(`Score: ${result.score}`);
console.log(`Original index: ${result.refIndex}`);
if (result.matches) {
result.matches.forEach(match => {
console.log(`Matched field: ${match.key}`);
console.log(`Matched value: ${match.value}`);
console.log(`Match indices: ${match.indices}`);
});
}
});Core algorithm parameters that control how fuzzy matching works.
interface FuzzyOptions {
/** Expected pattern location in text (default: 0) */
location?: number;
/** Match threshold - 0.0 requires perfect match, 1.0 matches anything (default: 0.6) */
threshold?: number;
/** Maximum distance from expected location (default: 100) */
distance?: number;
}
interface MatchOptions {
/** Include match scores in results (default: false) */
includeScore?: boolean;
/** Include match indices for highlighting (default: false) */
includeMatches?: boolean;
/** Continue searching after finding perfect match (default: false) */
findAllMatches?: boolean;
/** Minimum characters that must match (default: 1) */
minMatchCharLength?: number;
}
interface BasicOptions {
/** Case sensitive matching (default: false) */
isCaseSensitive?: boolean;
/** Ignore diacritics/accents (default: false) */
ignoreDiacritics?: boolean;
/** Sort results by score (default: true) */
shouldSort?: boolean;
/** Custom sort function for results */
sortFn?: FuseSortFunction;
}
type FuseSortFunctionItem = {
[key: string]: { $: string } | { $: string; idx: number }[];
};
type FuseSortFunctionMatch = {
score: number;
key: string;
value: string;
indices: ReadonlyArray<number>[];
};
type FuseSortFunctionMatchList = FuseSortFunctionMatch & {
idx: number;
};
type FuseSortFunctionArg = {
idx: number;
item: FuseSortFunctionItem;
score: number;
matches?: (FuseSortFunctionMatch | FuseSortFunctionMatchList)[];
};
type FuseSortFunction = (
a: FuseSortFunctionArg,
b: FuseSortFunctionArg
) => number;Usage Examples:
// High precision search
const preciseFuse = new Fuse(data, {
threshold: 0.1,
distance: 50,
location: 0
});
// Case sensitive search with highlights
const caseSensitiveFuse = new Fuse(data, {
isCaseSensitive: true,
includeMatches: true,
includeScore: true
});
// Flexible matching
const relaxedFuse = new Fuse(data, {
threshold: 0.8,
ignoreLocation: true,
findAllMatches: true
});Configuration for searching within object properties and nested data.
type FuseOptionKey<T> = FuseOptionKeyObject<T> | string | string[];
interface FuseOptionKeyObject<T> {
/** Field path(s) to search */
name: string | string[];
/** Field importance weight (default: 1) */
weight?: number;
/** Custom value extraction function */
getFn?: (obj: T) => ReadonlyArray<string> | string;
}
type FuseGetFunction<T> = (
obj: T,
path: string | string[]
) => ReadonlyArray<string> | string;Usage Examples:
// Simple field names
const simpleFuse = new Fuse(books, {
keys: ["title", "author", "isbn"]
});
// Nested field paths
const nestedFuse = new Fuse(users, {
keys: ["profile.name", "profile.bio", "contact.email"]
});
// Weighted fields
const weightedFuse = new Fuse(articles, {
keys: [
{ name: "title", weight: 2 }, // Title matches weighted higher
{ name: "content", weight: 1 },
{ name: "tags", weight: 1.5 }
]
});
// Custom getter functions
const customFuse = new Fuse(products, {
keys: [
{
name: "searchText",
getFn: (product) => `${product.title} ${product.description} ${product.tags.join(" ")}`
}
]
});Advanced options for fine-tuning search scoring and relevance calculation.
interface AdvancedOptions {
/** Custom value extraction function */
getFn?: FuseGetFunction<T>;
/** Ignore location in scoring (default: false) */
ignoreLocation?: boolean;
/** Ignore field length normalization (default: false) */
ignoreFieldNorm?: boolean;
/** Field length normalization weight (default: 1) */
fieldNormWeight?: number;
}
type FuseSortFunction = (
a: FuseSortFunctionArg,
b: FuseSortFunctionArg
) => number;
interface FuseSortFunctionArg {
idx: number;
item: FuseSortFunctionItem;
score: number;
matches?: (FuseSortFunctionMatch | FuseSortFunctionMatchList)[];
}Usage Examples:
// Custom scoring that ignores field length
const customScoreFuse = new Fuse(data, {
ignoreFieldNorm: true,
ignoreLocation: true,
fieldNormWeight: 0.5
});
// Custom sort function
const customSortFuse = new Fuse(data, {
shouldSort: true,
sortFn: (a, b) => {
// Sort by score, then by alphabetical order
if (a.score !== b.score) {
return a.score - b.score;
}
return a.item.name.localeCompare(b.item.name);
}
});Common errors that may be thrown during Fuse operations and their meanings.
Configuration Errors:
// Thrown when extended search is used but not enabled
try {
const fuse = new Fuse(data, { useExtendedSearch: false });
fuse.search({ $and: [{ title: "test" }] });
} catch (error) {
console.error(error.message); // "Extended search is not available"
}
// Thrown when logical search is used but not available
try {
fuse.search({ $or: [{ title: "test" }] });
} catch (error) {
console.error(error.message); // "Logical search is not available"
}
// Thrown when incorrect index type is provided
try {
const fuse = new Fuse(data, {}, "invalid-index");
} catch (error) {
console.error(error.message); // "Incorrect 'index' type"
}Key Configuration Errors:
// Invalid key weight values
try {
const fuse = new Fuse(data, {
keys: [{ name: "title", weight: -1 }] // Negative weight
});
} catch (error) {
console.error(error.message); // "Property 'weight' in key 'title' must be a positive integer"
}
// Missing key properties
try {
const fuse = new Fuse(data, {
keys: [{ weight: 1 }] // Missing name property
});
} catch (error) {
console.error(error.message); // "Missing name property in key"
}Search Pattern Errors:
// Pattern too long (if there's a max length limit)
try {
const veryLongPattern = "a".repeat(10000);
fuse.search(veryLongPattern);
} catch (error) {
console.error(error.message); // "Pattern length exceeds max of [limit]"
}