A lightweight, powerful, and flexible fuzzy search library for JavaScript with zero dependencies. Perfect for implementing search functionality with typo tolerance, autocomplete, and intelligent matching.
- Multiple algorithms: Levenshtein distance and Jaro-Winkler similarity
- Zero dependencies: Lightweight and fast
- Flexible configuration: Customizable thresholds, case sensitivity, and more
- Object search: Search through object properties with dot notation
- Match highlighting: Built-in text highlighting with customizable markup
- TypeScript ready: Works in both JavaScript and TypeScript projects
- Browser & Node.js: Universal compatibility
- Typo tolerance: Users don't need perfect spelling - "javscript" matches "javascript"
- Smart ranking: Results are sorted by relevance, not just exact matches
- Flexible matching: Handles abbreviations, partial matches, and common misspellings
- Lightweight: <5KB minified, no external dependencies
- Fast: Optimized algorithms suitable for real-time search
- Configurable: Adjust sensitivity and behavior for your specific needs
- Multiple data types: Search strings, objects, or complex nested data
- Simple API: Get started with just a few lines of code
- Rich features: Highlighting, scoring, match positions out of the box
- Well tested: Reliable algorithms used in production applications
# Via npm
npm install fuzzysearch-js
# Via yarn
yarn add fuzzysearch-js
# Or just download and include the fileimport FuzzySearch from 'fuzzysearch-js';
// or const FuzzySearch = require('fuzzysearch-js');
// Basic usage
const fuzzy = new FuzzySearch();
const fruits = ['apple', 'banana', 'cherry', 'grape'];
console.log(fuzzy.search('aple', fruits));
// Output: ['apple']
console.log(fuzzy.search('bnan', fruits));
// Output: ['banana']const fuzzy = new FuzzySearch({
threshold: 0.6, // Minimum similarity score (0-1)
caseSensitive: false, // Case sensitive matching
includeScore: false, // Include similarity scores in results
includeMatches: false, // Include match positions
shouldSort: true, // Sort results by score
keys: null, // Object properties to search
minMatchCharLength: 1, // Minimum character length to match
algorithm: 'levenshtein' // Algorithm: 'levenshtein' or 'jaro-winkler'
});Search through an array of strings or objects.
// String search
const results = fuzzy.search('query', ['item1', 'item2']);
// With scores
const fuzzy = new FuzzySearch({ includeScore: true });
const results = fuzzy.search('apple', ['apple', 'application']);
// [{ item: 'apple', score: 1 }, { item: 'application', score: 0.45 }]Highlight matching characters in text.
const highlighted = fuzzy.highlight('app', 'application');
// Output: '<mark>app</mark>lication'
// Custom highlighting
const highlighted = fuzzy.highlight('app', 'application', {
pre: '<strong class="highlight">',
post: '</strong>'
});const fuzzy = new FuzzySearch({ threshold: 0.4 });
const languages = ['JavaScript', 'Python', 'TypeScript', 'Java', 'C++'];
console.log(fuzzy.search('java', languages));
// Output: ['JavaScript', 'Java']const users = [
{ name: 'John Doe', email: 'john@company.com', role: 'developer' },
{ name: 'Jane Smith', email: 'jane@company.com', role: 'designer' },
{ name: 'Bob Johnson', email: 'bob@startup.com', role: 'manager' }
];
const userSearch = new FuzzySearch({
keys: ['name', 'email', 'role'],
includeScore: true,
threshold: 0.3
});
console.log(userSearch.search('john', users));
// Finds John Doe and Bob Johnson (contains 'john')const products = [
{
name: 'iPhone',
details: { brand: 'Apple', category: 'smartphone' }
},
{
name: 'Galaxy',
details: { brand: 'Samsung', category: 'smartphone' }
}
];
const productSearch = new FuzzySearch({
keys: ['name', 'details.brand', 'details.category']
});
console.log(productSearch.search('apple', products));
// Finds iPhoneconst fuzzy = new FuzzySearch();
const query = 'javascript';
const text = 'Learning JavaScript programming';
const highlighted = fuzzy.highlight(query.slice(0, 4), text);
console.log(highlighted);
// Output: 'Learning <mark>Java</mark>Script programming'class SearchComponent {
constructor() {
this.fuzzy = new FuzzySearch({
keys: ['title', 'description'],
threshold: 0.3,
includeScore: true
});
this.data = []; // Your data array
}
search(query) {
if (!query.trim()) return this.data;
const results = this.fuzzy.search(query, this.data);
return results.map(result => ({
...result.item,
_score: result.score,
_highlighted: this.fuzzy.highlight(query, result.item.title)
}));
}
}// High precision search
const preciseSearch = new FuzzySearch({
threshold: 0.8,
algorithm: 'jaro-winkler',
caseSensitive: true
});
// Loose matching for large datasets
const looseSearch = new FuzzySearch({
threshold: 0.2,
minMatchCharLength: 2,
shouldSort: true
});
// Debug mode with full details
const debugSearch = new FuzzySearch({
includeScore: true,
includeMatches: true,
threshold: 0.1
});- Search bars: Add intelligent search to your web applications
- Autocomplete: Build smart autocomplete with typo tolerance
- Command palettes: Create VS Code-style command interfaces
- Data filtering: Filter large datasets with flexible matching
- Content discovery: Help users find content even with imperfect queries
- Contact/user search: Search through user directories
- Product catalogs: E-commerce search with brand/category matching
- Use appropriate thresholds: Lower values (0.3-0.5) for loose matching, higher (0.7-0.9) for precise
- Limit search keys: Only search the fields you need for better performance
- Pre-index large datasets: Use
createIndex()for repeated searches - Consider minimum query length: Avoid searching very short queries for better UX
// Optimized for large datasets
const optimizedSearch = new FuzzySearch({
threshold: 0.5,
keys: ['title'], // Only search title, not all fields
minMatchCharLength: 2 // Don't search single characters
});| Algorithm | Best For | Strengths | Example |
|---|---|---|---|
| Levenshtein | Typos, character substitutions | Simple, predictable | "color" β "colour" |
| Jaro-Winkler | Transpositions, similar strings | Better for name matching | "martha" β "marhta" |
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
MIT License - see LICENSE file for details.