fuse.js vs lunr vs flexsearch vs search-index vs elasticlunr
JavaScript Search Libraries
fuse.jslunrflexsearchsearch-indexelasticlunrSimilar Packages:

JavaScript Search Libraries

JavaScript search libraries provide tools for implementing search functionality within web applications. These libraries can index data, perform searches, and return results based on user queries. They vary in features, performance, and complexity, catering to different use cases such as simple text search, full-text search, and search with advanced features like ranking, highlighting, and fuzzy matching. Choosing the right search library depends on factors like the size of the dataset, the complexity of search queries, and the need for features like real-time indexing or multi-language support.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
fuse.js9,184,00920,232312 kB3a month agoApache-2.0
lunr6,232,9009,206-1296 years agoMIT
flexsearch1,095,37913,6872.33 MB308 months agoApache-2.0
search-index47,3911,424693 kB5a year agoMIT
elasticlunr28,9162,070-7710 years agoMIT

Feature Comparison: fuse.js vs lunr vs flexsearch vs search-index vs elasticlunr

Indexing Method

  • fuse.js:

    fuse.js does not create a traditional index. Instead, it builds a lightweight, in-memory structure that supports fuzzy searching. This approach is simple and effective for small to medium datasets but may not scale well for larger datasets.

  • lunr:

    lunr builds a compact inverted index that is stored in memory. It supports multi-field indexing, custom tokenization, and provides a simple API for searching. The index is created once and used for fast search queries.

  • flexsearch:

    flexsearch offers multiple indexing strategies, including traditional inverted indexing and a more memory-efficient approach. It supports real-time indexing and allows for fine-tuning of the indexing process, making it highly versatile.

  • search-index:

    search-index creates a full-text index using inverted indexing. It supports real-time indexing, multi-field indexing, and allows for complex queries. The indexing process is highly configurable, making it suitable for dynamic datasets.

  • elasticlunr:

    elasticlunr creates an inverted index in memory, allowing for efficient search operations. It supports custom tokenization and stemming, making it flexible for different types of text data.

Fuzzy Search Support

  • fuse.js:

    fuse.js is known for its fuzzy search capabilities, allowing for approximate matching of strings. It provides configurable fuzziness, making it easy to adjust the sensitivity of the search.

  • lunr:

    lunr does not natively support fuzzy searching. However, it can be extended with plugins to add this feature. By default, it focuses on exact and partial matches.

  • flexsearch:

    flexsearch provides advanced fuzzy search capabilities with configurable algorithms. It allows for fine-tuning the fuzziness level, making it one of the most feature-rich libraries for fuzzy searching.

  • search-index:

    search-index supports fuzzy searching as part of its full-text search capabilities. It allows for configurable fuzziness, making it suitable for applications that require approximate matching.

  • elasticlunr:

    elasticlunr supports basic fuzzy searching through configurable edit distance. It allows for approximate matching, but the implementation is relatively simple compared to more advanced libraries.

Real-time Indexing

  • fuse.js:

    fuse.js does not support real-time indexing as it requires the dataset to be loaded into memory before searching. However, the dataset can be updated dynamically, and the search will reflect the changes immediately.

  • lunr:

    lunr does not support real-time indexing. The index is built once and cannot be updated without rebuilding it. This makes it more suitable for static datasets.

  • flexsearch:

    flexsearch supports real-time indexing, allowing for updates to the index without needing to rebuild it. This feature makes it suitable for dynamic applications where data changes frequently.

  • search-index:

    search-index supports real-time indexing, allowing for continuous updates to the index as new data is added. This feature is ideal for applications with frequently changing data.

  • elasticlunr:

    elasticlunr does not support real-time indexing out of the box. Indexing is done manually, and the library is designed for static or semi-static datasets.

Memory Usage

  • fuse.js:

    fuse.js has a low memory footprint, making it suitable for small to medium datasets. However, memory usage can increase significantly with larger datasets due to its in-memory search structure.

  • lunr:

    lunr is relatively memory-efficient for the features it provides. However, memory usage grows with the size of the dataset, particularly during indexing.

  • flexsearch:

    flexsearch is designed to be memory-efficient, especially with its configurable indexing options. It uses advanced algorithms to minimize memory usage while providing fast search performance.

  • search-index:

    search-index can be memory-intensive, especially with large datasets, due to its full-text indexing approach. However, it provides options for optimizing memory usage during indexing and searching.

  • elasticlunr:

    elasticlunr is lightweight and has a low memory footprint, making it suitable for client-side applications. However, memory usage increases with the size of the dataset due to the in-memory index.

Ease of Use: Code Examples

  • fuse.js:

    Simple Fuzzy Search with fuse.js

    const Fuse = require('fuse.js');
    const data = [
      { id: 1, title: 'Hello World', body: 'This is a test document.' },
      { id: 2, title: 'Elastic Search', body: 'Searching with fuse.js.' },
    ];
    
    const fuse = new Fuse(data, { keys: ['title', 'body'], threshold: 0.3 });
    const results = fuse.search('test');
    console.log(results);
    
  • lunr:

    Simple Search with lunr

    const lunr = require('lunr');
    const index = lunr(function () {
      this.ref('id');
      this.field('title');
      this.field('body');
    });
    
    index.add({ id: 1, title: 'Hello World', body: 'This is a test document.' });
    index.add({ id: 2, title: 'Elastic Search', body: 'Searching with lunr.js.' });
    
    const results = index.search('test');
    console.log(results);
    
  • flexsearch:

    Simple Search with flexsearch

    const FlexSearch = require('flexsearch');
    const index = new FlexSearch.Index();
    
    index.add(1, { title: 'Hello World', body: 'This is a test document.' });
    index.add(2, { title: 'Elastic Search', body: 'Searching with flexsearch.' });
    
    index.search('test').then(results => {
      console.log(results);
    });
    
  • search-index:

    Simple Search with search-index

    const si = require('search-index');
    const index = si({ name: 'my-index' });
    
    index({ id: 1, title: 'Hello World', body: 'This is a test document.' });
    index({ id: 2, title: 'Elastic Search', body: 'Searching with search-index.' });
    
    index.search('test').then(results => {
      console.log(results);
    });
    
  • elasticlunr:

    Simple Search with elasticlunr

    const elasticlunr = require('elasticlunr');
    const index = elasticlunr(function () {
      this.addField('title');
      this.addField('body');
      this.setRef('id');
    });
    
    index.addDoc({ id: 1, title: 'Hello World', body: 'This is a test document.' });
    index.addDoc({ id: 2, title: 'Elastic Search', body: 'Searching with elasticlunr.js.' });
    
    const results = index.search('test');
    console.log(results);
    

How to Choose: fuse.js vs lunr vs flexsearch vs search-index vs elasticlunr

  • fuse.js:

    Choose fuse.js if you need a simple, lightweight library for fuzzy searching within a dataset. It works well for small to medium-sized datasets and allows for easy configuration of search algorithms, making it ideal for applications that require approximate matching.

  • lunr:

    Choose lunr if you want a simple, self-contained full-text search library that creates an index in the browser. It is suitable for static sites or applications with a fixed dataset, providing fast search capabilities without the need for a server.

  • flexsearch:

    Choose flexsearch if you require a high-performance, feature-rich search library with support for fuzzy searching, multi-language indexing, and real-time updates. It is suitable for applications that need fast search capabilities with minimal memory usage.

  • search-index:

    Choose search-index if you need a full-featured, Node.js-based search indexing solution that supports real-time indexing, multi-field search, and advanced features like faceting and ranking. It is ideal for applications that require more control over the indexing and search process.

  • elasticlunr:

    Choose elasticlunr if you need a lightweight, client-side search library that mimics Elasticsearch's API. It's great for small to medium datasets and offers features like stemming, tokenization, and custom scoring.

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.

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

Available in the full build. See TOKEN_SEARCH.md 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]] }

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 kB
BasicFuzzy search only~6.5 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.

Supporting Fuse.js

Develop

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

Contribute

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