### Quick Fuse.js Example Source: https://github.com/krisk/fuse/blob/main/docs/index.md Demonstrates how to initialize Fuse.js with data and options, and then perform a fuzzy search. Use this to quickly get started with searching your data. ```javascript import Fuse from 'fuse.js' const books = [ { title: "Old Man's War", author: 'John Scalzi' }, { title: 'The Lock Artist', author: 'Steve Hamilton' }, { title: 'JavaScript Patterns', author: 'Stoyan Stefanov' } ] const fuse = new Fuse(books, { keys: ['title', 'author'], includeScore: true }) fuse.search('jon') // [{ item: { title: "Old Man's War", author: "John Scalzi" }, refIndex: 0, score: 0.25 }] fuse.search('patterns') // [{ item: { title: "JavaScript Patterns", ... }, refIndex: 2, score: 0.0 }] ``` -------------------------------- ### Fuse.js Quick Start Source: https://github.com/krisk/fuse/blob/main/README.md Basic example demonstrating how to initialize Fuse.js and perform a fuzzy search on a list of books. ```javascript 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', ... }, ... }] ``` -------------------------------- ### Install react-window for Virtualized Rendering Source: https://github.com/krisk/fuse/blob/main/docs/articles/using-fuse-with-react.md Install the `react-window` library to enable virtualized rendering for displaying large lists of search results efficiently. ```bash npm install react-window ``` -------------------------------- ### Install Fuse.js with bun Source: https://github.com/krisk/fuse/blob/main/docs/getting-started.md Install Fuse.js using bun. bun is a new, fast JavaScript runtime and toolkit. ```sh bun add fuse.js ``` -------------------------------- ### Basic Fuse.js Usage Example Source: https://github.com/krisk/fuse/blob/main/docs/getting-started.md Demonstrates how to initialize Fuse.js with data and perform a search. Results are ranked by relevance. ```js import Fuse from 'fuse.js' const books = [ { title: "Old Man's War", author: 'John Scalzi' }, { title: 'The Lock Artist', author: 'Steve Hamilton' } ] const fuse = new Fuse(books, { keys: ['title', 'author'] }) const results = fuse.search('jon') // [{ item: { title: "Old Man's War", author: "John Scalzi" }, refIndex: 0 }] ``` -------------------------------- ### Token Search Example Source: https://github.com/krisk/fuse/blob/main/README.md Demonstrates how to use token search for multi-word fuzzy matching with relevance ranking. Enable with `useTokenSearch: true`. ```javascript const fuse = new Fuse(docs, { useTokenSearch: true, keys: ['title', 'author', 'description'] }) fuse.search('javascrpt paterns') // → [{ item: { title: 'JavaScript Patterns', ... } }] ``` -------------------------------- ### Install Dependencies Source: https://github.com/krisk/fuse/blob/main/DEVELOPERS.md Installs the necessary project dependencies using npm. Ensure Node.js version 22.18 or higher is used. ```shell npm install ``` -------------------------------- ### Fuse.js Fuzzy Search Example Source: https://github.com/krisk/fuse/blob/main/docs/articles/vs-semantic-search.md Demonstrates how to initialize Fuse.js with a list of products and perform a typo-tolerant search. This code runs entirely in the browser. ```javascript import Fuse from 'fuse.js' const products = [ { name: 'MacBook Pro 16"', sku: 'MBP16', category: 'Laptops' }, { name: 'Magic Keyboard', sku: 'MK', category: 'Accessories' }, { name: 'Mac Mini M4', sku: 'MM4', category: 'Desktops' }, // ... hundreds or thousands of items ] const fuse = new Fuse(products, { keys: ['name', 'sku', 'category'], threshold: 0.4 }) // Typo-tolerant, instant, runs in the browser fuse.search('mackbook') // [{ item: { name: 'MacBook Pro 16"', ... }, ... }] ``` -------------------------------- ### Install Fuse.js with pnpm Source: https://github.com/krisk/fuse/blob/main/docs/getting-started.md Install Fuse.js using pnpm. pnpm is a fast, disk-space-efficient package manager. ```sh pnpm add fuse.js ``` -------------------------------- ### Install Fuse.js using npm Source: https://github.com/krisk/fuse/blob/main/docs/index.md Install Fuse.js using npm for use in your Node.js or browser projects. This is the recommended way to add the library to your project. ```bash npm install fuse.js ``` -------------------------------- ### Bitap Algorithm: Scanning Text Example Source: https://github.com/krisk/fuse/blob/main/docs/articles/how-fuzzy-search-works.md Demonstrates the step-by-step process of the Bitap algorithm scanning the text 'xtest' for the pattern 'test'. It shows how the state vector 'R' updates with each character read. ```javascript t e s t Start: R = 0 0 0 0 Read 'x': R = 0 0 0 0 ← 'x' isn't in the pattern, seed killed Read 't': R = 1 0 0 0 ← 't' matches position 0, partial match starts Read 'e': R = 0 1 0 0 ← 'e' matches position 1, match continues Read 's': R = 0 0 1 0 ← 's' matches position 2, still going Read 't': R = 1 0 0 1 ← 't' matches position 3 → full match! (also starts a new match at position 0) ``` -------------------------------- ### Install Fuse.js with yarn Source: https://github.com/krisk/fuse/blob/main/docs/getting-started.md Install Fuse.js using yarn. yarn is another popular package manager for JavaScript. ```sh yarn add fuse.js ``` -------------------------------- ### Extended Search Examples Source: https://github.com/krisk/fuse/blob/main/docs/extended-search.md Demonstrates various extended search queries on a list of books, including prefix, inverse, and suffix matching, combined with AND and OR logic. ```javascript const books = [ { title: "Old Man's War", author: 'John Scalzi' }, { title: 'The Lock Artist', author: 'Steve Hamilton' }, { title: 'Artist for Life', author: 'Michelangelo' } ] const fuse = new Fuse(books, { useExtendedSearch: true, keys: ['title'] }) // Starts with "Old" AND fuzzy match "war" fuse.search('^Old war') // Does NOT include "Artist" AND starts with "Old" fuse.search('!Artist ^Old') // Ends with "Artist" OR includes "War" fuse.search("Artist$ | 'War") ``` -------------------------------- ### Quick Start FuseWorker Initialization and Search Source: https://github.com/krisk/fuse/blob/main/docs/web-workers.md Initialize FuseWorker with documents and options, perform a search, and then terminate the workers. The search method returns a Promise. ```javascript import { FuseWorker } from 'fuse.js/worker' const fuse = new FuseWorker(docs, { keys: ['title', 'author', 'description'], threshold: 0.4, includeScore: true }) const results = await fuse.search('javascript') // Clean up when done fuse.terminate() ``` -------------------------------- ### Basic Fuzzy Search Example Source: https://github.com/krisk/fuse/blob/main/docs/fuzzy-search.md Initialize Fuse.js with a list of items and search for a pattern. The `includeScore` option returns a fuzziness score for each match. ```javascript const fuse = new Fuse(['apple', 'banana', 'orange'], { includeScore: true }) fuse.search('aple') // [{ item: 'apple', refIndex: 0, score: 0.25 }] ``` -------------------------------- ### Example Usage of FuzzySearch Component Source: https://github.com/krisk/fuse/blob/main/docs/articles/using-fuse-with-react.md Demonstrates how to use the `FuzzySearch` component by providing the data items, the keys to search within, a unique item key for React's list rendering, and an optional placeholder. ```jsx ``` -------------------------------- ### Fuzzy Search Example Source: https://github.com/krisk/fuse/blob/main/README.md Illustrates the core fuzzy search functionality of Fuse.js, which handles typos and partial matches using the Bitap algorithm. ```javascript fuse.search('javscript') // → [{ item: { title: 'JavaScript: The Good Parts', author: 'Douglas Crockford' } }] ``` -------------------------------- ### Fuzzy Search Example: 'test' in 'tset' Source: https://github.com/krisk/fuse/blob/main/docs/articles/how-fuzzy-search-works.md Illustrates how the Bitap algorithm handles a transposition ('tset' vs 'test') by using multiple error levels (R0, R1, R2). Each level accounts for an additional mismatch. ```text t e s t R0 (0 errors): 1 0 0 0 ← 't' matches, but 's' ≠ 'e' — exact match dies R1 (1 error): 1 1 0 0 ← the mismatch continues here as 1 error R2 (2 errors): 1 1 1 1 ← another mismatch, 2 errors — still matches! ``` -------------------------------- ### Combine Extended Search with Logical Queries Source: https://github.com/krisk/fuse/blob/main/docs/extended-search.md Integrate extended search operators within Fuse.js logical queries for complex filtering. This example searches for books where the title starts with 'Old' AND the author includes 'Scalzi'. ```javascript fuse.search({ $and: [ { title: '^Old' }, // title starts with "Old" { author: "'Scalzi" } // author includes "Scalzi" ] }) ``` -------------------------------- ### Combine Search Operators with AND/OR Source: https://github.com/krisk/fuse/blob/main/docs/extended-search.md Use whitespace for AND logic (all terms must match) and the pipe symbol (|) for OR logic (any group must match) to combine search operators. This example searches for items that include 'Man' AND 'Old', OR end with 'Artist'. ```javascript // Items that include "Man" AND "Old", OR end with "Artist" fuse.search("'Man 'Old | Artist$") ``` -------------------------------- ### Highlight Search Matches in React Source: https://github.com/krisk/fuse/blob/main/docs/articles/using-fuse-with-react.md Enable `includeMatches` in Fuse.js to get character-level match positions. Use these indices to wrap matched text in `` tags for visual highlighting. ```jsx import { useMemo, useState } from 'react' import Fuse from 'fuse.js' // Splits text into plain strings and elements based on match regions function highlightMatches(text, regions = []) { if (!regions.length) return text const chunks = [] let lastIndex = 0 // Fuse.js returns sorted, non-overlapping [start, end] pairs for (const [start, end] of regions) { // Add any unmatched text before this region if (start > lastIndex) { chunks.push(text.slice(lastIndex, start)) } // Wrap the matched range in a tag chunks.push({text.slice(start, end + 1)}) lastIndex = end + 1 } // Add any remaining text after the last match if (lastIndex < text.length) { chunks.push(text.slice(lastIndex)) } return chunks } function BookSearch({ books }) { const [query, setQuery] = useState('') const fuse = useMemo(() => { return new Fuse(books, { keys: ['title', 'author'], includeMatches: true, // return character-level match positions threshold: 0.4, }) }, [books]) const results = query ? fuse.search(query) : [] return (
setQuery(e.target.value)} />
    {results.map(({ item, matches }) => { // Find match data for each field we want to highlight const titleMatch = matches?.find((m) => m.key === 'title') const authorMatch = matches?.find((m) => m.key === 'author') return (
  • {highlightMatches(item.title, titleMatch?.indices)} — {highlightMatches(item.author, authorMatch?.indices)}
  • ) })}
) } ``` ```css mark { background-color: #fef08a; padding: 0; } ``` -------------------------------- ### Initialize Fuse Cloud Client and Search Source: https://github.com/krisk/fuse/blob/main/docs/cloud.md Instantiate the FuseCloud client with your public key and index name, then perform a search query. The results are returned in the same format as Fuse.js. ```javascript import { FuseCloud } from "@fusejs/cloud" const client = new FuseCloud({ publicKey: "pk_abc123", index: "products" }) const { results } = await client.search("iphone") // → [{ id: "1", score: 0.02, item: { title: "iPhone 16 Pro", ... } }] ``` -------------------------------- ### Nested $and and $or Query Source: https://github.com/krisk/fuse/blob/main/docs/logical-search.md Nest $and and $or operators arbitrarily to create complex query structures. This example combines an $and with a nested $or. ```javascript const result = fuse.search({ $and: [ { title: 'old war' }, { $or: [ { title: '^lock' }, { title: '!arts' } ] } ] }) ``` -------------------------------- ### Basic Fuse.js initialization and search Source: https://github.com/krisk/fuse/blob/main/docs/articles/vs-semantic-search.md Initialize Fuse.js with your data and search configuration, then perform a search. Adjust the 'threshold' option to control match sensitivity. ```javascript import Fuse from 'fuse.js' const fuse = new Fuse(yourData, { keys: ['name', 'description'], threshold: 0.4 }) const results = fuse.search('query') ``` -------------------------------- ### Import Fuse.js Basic Build Source: https://github.com/krisk/fuse/blob/main/docs/getting-started.md Import the basic build of Fuse.js, which only includes fuzzy search. Other features can be added at runtime. ```js // Basic build import Fuse from 'fuse.js/basic' ``` -------------------------------- ### Import Fuse.js Full Build Source: https://github.com/krisk/fuse/blob/main/docs/getting-started.md Import the default, full build of Fuse.js. This build includes all features. ```js // Full build (default) import Fuse from 'fuse.js' ``` -------------------------------- ### Bitap Algorithm State Initialization Source: https://github.com/krisk/fuse/blob/main/docs/articles/how-fuzzy-search-works.md Shows the initial state vector 'R' for the Bitap algorithm before processing any text. All bits are set to 0, indicating no matches found yet. ```javascript t e s t R = 0 0 0 0 ``` -------------------------------- ### Import Minified Fuse.js Builds Source: https://github.com/krisk/fuse/blob/main/docs/getting-started.md Import minified versions of Fuse.js builds for reduced file size. Use 'min' for the full build and 'min-basic' for the basic build. ```js // Minified variants import Fuse from 'fuse.js/min' import Fuse from 'fuse.js/min-basic' ``` -------------------------------- ### Run tests before pull request Source: https://github.com/krisk/fuse/blob/main/CONTRIBUTING.md Before creating a pull request, package and run all tests to ensure everything is working correctly. ```shell npm run test ``` -------------------------------- ### Project Structure Overview Source: https://github.com/krisk/fuse/blob/main/DEVELOPERS.md Illustrates the directory layout of the Fuse.js project, detailing the location of source code, tests, benchmarks, build configurations, and output. ```tree src/ core/ — Fuse class, config, scoring, query parser, formatting search/ — Bitap algorithm + extended search (operators, matchers) tools/ — FuseIndex, KeyStore, MaxHeap, field-length norm helpers/ — Utility functions (type guards, get, diacritics) types.ts — Shared type definitions entry.ts — Entry point with static methods and type exports test/ — Tests and fixtures bench/ — Benchmarks (search, index creation, extended, tokens, workers) tsdown.config.ts — Build config (all dist targets + types) scripts/ — Release + docs helpers (bump-docs, deploy-docs, release) dist/ — Built output (CJS, ESM, .d.ts) ``` -------------------------------- ### Dataset Generation Utility Source: https://github.com/krisk/fuse/blob/main/bench/parallel-browser/index.html Provides utility functions to generate a dataset of objects with names, emails, companies, and descriptions for benchmarking. Uses random selection from predefined arrays. ```javascript const firstNames = [ 'John', 'Jane', 'Alice', 'Bob', 'Charlie', 'Diana', 'Eve', 'Frank', 'Grace', 'Hank', 'Ivy', 'Jack', 'Karen', 'Leo', 'Mona', 'Nick', 'Olivia', 'Paul', 'Quinn', 'Rita', 'Sam', 'Tina', 'Uma', 'Victor' ] const lastNames = [ 'Smith', 'Johnson', 'Williams', 'Brown', 'Jones', 'Garcia', 'Miller', 'Davis', 'Rodriguez', 'Martinez', 'Anderson', 'Taylor', 'Thomas', 'Moore', 'Jackson', 'Martin', 'Lee', 'Perez', 'Thompson', 'White' ] const companies = [ 'Acme Corp', 'Globex Inc', 'Initech', 'Umbrella Co', 'Stark Industries', 'Wayne Enterprises', 'XYZ Corp', 'Quantum Labs', 'Nova Systems', 'Apex Digital' ] const domains = [ 'gmail.com', 'yahoo.com', 'outlook.com', 'company.com', 'work.org' ] const words = [ 'engineering', 'marketing', 'sales', 'design', 'research', 'quantum', 'neural', 'cloud', 'data', 'analytics', 'platform', 'mobile', 'security', 'infrastructure', 'development', 'operations', 'strategy', 'innovation', 'optimization', 'integration', 'automation', 'visualization', 'banana' ] function pick(arr) { return arr[Math.floor(Math.random() * arr.length)] } function generateDataset(size) { const docs = [] for (let i = 0; i < size; i++) { const first = pick(firstNames), last = pick(lastNames) const descLen = 5 + Math.floor(Math.random() * 10) docs.push({ id: i, name: `${first} ${last}`, email: `${first.toLowerCase()}.${last.toLowerCase()}@${pick(domains)}`, company: pick(companies), description: Array.from({ length: descLen }, () => pick(words)).join(' ') }) } return docs } ``` -------------------------------- ### Token Search: 'any' vs 'all' Matching Modes Source: https://github.com/krisk/fuse/blob/main/docs/token-search.md Demonstrates the difference between 'any' (OR) and 'all' (AND) token matching modes in Fuse.js. Use 'any' for ranked search and 'all' for filtering. ```javascript const list = ['red shirt', 'red hat', 'blue shirt'] new Fuse(list, { useTokenSearch: true }) .search('red shirt') .map((r) => r.item) // 'any' (default): ['red shirt', 'red hat', 'blue shirt'] new Fuse(list, { useTokenSearch: true, tokenMatch: 'all' }) .search('red shirt') .map((r) => r.item) // 'all': ['red shirt'] ``` -------------------------------- ### Run Benchmark Function (JavaScript) Source: https://github.com/krisk/fuse/blob/main/bench/parallel-browser/index.html This function orchestrates the benchmark process, including dataset generation, single-thread execution, parallel execution with varying worker counts, and result display. It updates the UI to show progress and final results. ```javascript y') const correctnessEl = document.getElementById('correctness') btn.disabled = true resultsTable.style.display = 'none' resultsBody.innerHTML = '' correctnessEl.textContent = '' const datasetSize = parseInt(document.getElementById('datasetSize').value) const benchRuns = parseInt(document.getElementById('benchRuns').value) status.textContent = `Generating ${datasetSize.toLocaleString()} documents... ` await new Promise(r => setTimeout(r, 50)) const docs = generateDataset(datasetSize) animateBall() // Single thread status.textContent = 'Running: single thread (watch the ball stutter)... ' await new Promise(r => setTimeout(r, 50)) const single = await bench('Fuse (single thread)', () => searchSingleThread(docs, QUERIES), benchRuns) // FuseWorker with different worker counts const parallel = [] for (const n of WORKER_COUNTS) { status.textContent = `Running: FuseWorker (${n} workers)... ` await new Promise(r => setTimeout(r, 50)) const result = await bench( `FuseWorker (${n}) `, () => searchWithFuseWorker(docs, QUERIES, n), benchRuns ) parallel.push(result) } animating = false // Verify correctness const singleResults = searchSingleThread(docs, QUERIES) const parallelResults = await searchWithFuseWorker(docs, QUERIES, 4) let correct = true for (const q of QUERIES) { if (singleResults[q].length !== parallelResults[q].length) correct = false } // Display results const allResults = [single, ...parallel] const maxAvg = single.avg resultsTable.style.display = '' for (const r of allResults) { const speedup = single.avg / r.avg const barWidth = Math.round((r.avg / maxAvg) * 200) const row = document.createElement('tr') row.innerHTML = ` ${r.label} ${r.avg.toFixed(1)} ${r.min.toFixed(1)} ${r.max.toFixed(1)} ${speedup.toFixed(2)}x (
{results[index].item.title}
) return ( {Row} ) } ``` -------------------------------- ### Bitmask Creation for Pattern Alphabet Source: https://github.com/krisk/fuse/blob/main/docs/articles/how-fuzzy-search-works.md Illustrates the creation of bitmasks for each character in a pattern, used in the Bitap algorithm. This is part of the `createPatternAlphabet()` function in Fuse.js. ```javascript t e s t mask[t] 1 0 0 1 mask[e] 0 1 0 0 mask[s] 0 0 1 0 ``` -------------------------------- ### Dynamic Collection Management Source: https://github.com/krisk/fuse/blob/main/README.md Add new documents to a live index using `fuse.add()` or remove existing documents using `fuse.remove()` without needing to rebuild the entire index. ```javascript fuse.add({ title: 'New Book', author: 'New Author' }) fuse.remove((doc) => doc.title === 'Old Book') ``` -------------------------------- ### Import Fuse.js in Deno Source: https://github.com/krisk/fuse/blob/main/docs/getting-started.md Import Fuse.js in Deno, a secure runtime for JavaScript and TypeScript. Ensure to use the correct Deno types and path. ```typescript // @deno-types="https://deno.land/x/fuse@v7.4.2/dist/fuse.d.ts" import Fuse from 'https://deno.land/x/fuse@v7.4.2/dist/fuse.min.mjs' ``` -------------------------------- ### Use Extended Search with Basic Build Source: https://github.com/krisk/fuse/blob/main/docs/extended-search.md To use extended search with the basic build of Fuse.js, import `ExtendedSearch` and register it using `Fuse.use()`. This is necessary if you are not using the full build. ```javascript import Fuse from 'fuse.js/basic' import { ExtendedSearch } from 'fuse.js' Fuse.use(ExtendedSearch) ``` -------------------------------- ### Basic $and Query Source: https://github.com/krisk/fuse/blob/main/docs/logical-search.md Use the $and operator to return documents that match all specified clauses. It supports short-circuit evaluation. ```javascript const result = fuse.search({ $and: [{ author: 'abc' }, { title: 'xyz' }] }) ``` -------------------------------- ### Match Highlighting with includeMatches Source: https://github.com/krisk/fuse/blob/main/README.md Enable character-level match indices for highlighting search results. Configure Fuse.js with `includeMatches: true` and specify the keys to search. ```javascript const fuse = new Fuse(list, { includeMatches: true, keys: ['title'] }) const result = fuse.search('javscript') // result[0].matches[0].indices → [[0, 9]] ``` -------------------------------- ### Pre-build Fuse.js Index Source: https://github.com/krisk/fuse/blob/main/docs/performance.md Pre-build the index for large datasets to improve performance during initial page load. Pass the created index to the Fuse constructor. ```javascript const index = Fuse.createIndex(keys, list) const fuse = new Fuse(list, options, index) ``` -------------------------------- ### search(query, options?) Source: https://github.com/krisk/fuse/blob/main/docs/web-workers.md Performs a search query across all workers. This method is asynchronous and returns a Promise that resolves with the search results. ```APIDOC ## `search(query, options?)` ```js const results = await fuse.search('query') const limited = await fuse.search('query', { limit: 10 }) ``` Returns `Promise`. Supports the same query types as `Fuse`: strings, and expression objects (logical search). ``` -------------------------------- ### Import Fuse.js and FuseWorker Source: https://github.com/krisk/fuse/blob/main/bench/parallel-browser/index.html Imports the necessary Fuse.js and FuseWorker modules. Ensure the paths are correct for your project structure. ```javascript import Fuse from '../../dist/fuse.min.mjs' import { FuseWorker } from '../../dist/fuse-worker.mjs' ``` -------------------------------- ### Basic $or Query Source: https://github.com/krisk/fuse/blob/main/docs/logical-search.md Use the $or operator to return documents that match any of the specified clauses. It supports short-circuit evaluation. ```javascript const result = fuse.search({ $or: [{ author: 'abc' }, { author: 'def' }] }) ``` -------------------------------- ### Benchmark Fuse.js Performance Source: https://github.com/krisk/fuse/blob/main/docs/performance.md Measure Fuse.js indexing and search performance with your own data. Configure list size, keys, query, and options to match your use case. Run the script in Node.js or a browser console. ```javascript import Fuse from 'fuse.js' // -- Configure to match your use case -- const LIST_SIZE = 10_000 const KEYS = ['title', 'description', 'category', 'tags'] const QUERY = 'javascript' const OPTIONS = { keys: KEYS, threshold: 0.4 } const SEARCH_RUNS = 100 // -- Generate sample data -- const words = ['alpha', 'bravo', 'charlie', 'delta', 'echo', 'foxtrot', 'golf', 'hotel', 'india', 'juliet', 'kilo', 'lima', 'mike', 'november', 'oscar', 'papa', 'quebec', 'romeo', 'sierra', 'tango', 'uniform', 'victor', 'whiskey', 'xray', 'yankee', 'zulu', 'javascript', 'typescript', 'python', 'rust', 'golang', 'swift', 'kotlin', 'scala', 'elixir'] function randomSentence(len) { return Array.from({ length: len }, () => words[Math.floor(Math.random() * words.length)] ).join(' ') } const list = Array.from({ length: LIST_SIZE }, () => ({ title: randomSentence(4), description: randomSentence(12), category: randomSentence(2), tags: randomSentence(6) })) // -- Benchmark indexing -- const indexStart = performance.now() const fuse = new Fuse(list, OPTIONS) const indexTime = performance.now() - indexStart // -- Benchmark search (average over multiple runs) -- const searchStart = performance.now() for (let i = 0; i < SEARCH_RUNS; i++) { fuse.search(QUERY) } const searchTime = (performance.now() - searchStart) / SEARCH_RUNS // -- Results -- console.log(`List size: ${LIST_SIZE.toLocaleString()} items`) console.log(`Keys: ${KEYS.join(', ')}`) console.log(`Index time: ${indexTime.toFixed(2)}ms`) console.log(`Search time: ${searchTime.toFixed(2)}ms (avg over ${SEARCH_RUNS} runs)`) console.log(`Results: ${fuse.search(QUERY).length} matches`) ``` -------------------------------- ### Register ExtendedSearch with Basic Build Source: https://github.com/krisk/fuse/blob/main/docs/getting-started.md Register the ExtendedSearch plugin with the basic build of Fuse.js if you need its functionality. This must be done at runtime. ```js import Fuse from 'fuse.js/basic' import { ExtendedSearch } from 'fuse.js' Fuse.use(ExtendedSearch) ``` -------------------------------- ### Documentation chatbot search layers Source: https://github.com/krisk/fuse/blob/main/docs/articles/vs-semantic-search.md Implement a hybrid search strategy using Fuse.js for instant, typo-tolerant search-as-you-type functionality and semantic search for understanding natural language questions. ```javascript import Fuse from 'fuse.js' // Layer 1: Instant search-as-you-type for known pages const fuse = new Fuse(docs, { keys: ['title', 'headings', 'slug'], threshold: 0.3 }) function handleSearchInput(query) { // Fast fuzzy search — instant results as the user types return fuse.search(query).slice(0, 5) } // Layer 2: Semantic search when the user asks a question async function handleQuestion(question) { const embedding = await embed(question) const chunks = await vectorDB.query({ vector: embedding, topK: 10 }) return await llm.answer(question, chunks) } ``` -------------------------------- ### Push branch to GitHub Source: https://github.com/krisk/fuse/blob/main/CONTRIBUTING.md Push your feature branch to GitHub to make it available for a pull request. ```shell git push origin my-fix-branch ``` -------------------------------- ### Enable Token Search Source: https://github.com/krisk/fuse/blob/main/docs/token-search.md To enable token search, set the `useTokenSearch` option to `true` in the Fuse.js constructor. This allows multi-word queries to be split and matched independently. ```javascript const fuse = new Fuse(docs, { useTokenSearch: true, keys: ['title', 'author', 'description'] }) fuse.search('javascrpt paterns') // → [{ item: { title: 'JavaScript Patterns', ... }, score: 0.12 }] ``` -------------------------------- ### Import Fuse.js with CommonJS Source: https://github.com/krisk/fuse/blob/main/docs/getting-started.md Import Fuse.js using CommonJS syntax. This is typically used in Node.js environments. ```js const Fuse = require('fuse.js') ``` -------------------------------- ### Import Fuse.js with ES Modules Source: https://github.com/krisk/fuse/blob/main/docs/getting-started.md Import Fuse.js using ES Module syntax. This is standard for modern JavaScript environments. ```js import Fuse from 'fuse.js' ``` -------------------------------- ### Semantic Search Pseudocode Source: https://github.com/krisk/fuse/blob/main/docs/articles/vs-semantic-search.md Illustrates the conceptual steps for semantic search using an embedding model and a vector database. This is pseudocode and requires external services. ```javascript // Pseudocode — requires an embedding model + vector database const embedding = await openai.embeddings.create({ model: 'text-embedding-3-small', input: 'lightweight search library' }) const results = await vectorDB.query({ vector: embedding.data[0].embedding, topK: 5 }) ``` -------------------------------- ### Basic Fuse.js Search Component in React Source: https://github.com/krisk/fuse/blob/main/docs/articles/using-fuse-with-react.md Implement a basic search component in React using Fuse.js. It filters a list of books based on user input, with results displayed in a list. Use `useMemo` to ensure the Fuse instance is created only once. ```jsx import { useMemo, useState } from 'react' import Fuse from 'fuse.js' const books = [ { title: 'The Great Gatsby', author: 'F. Scott Fitzgerald' }, { title: 'To Kill a Mockingbird', author: 'Harper Lee' }, { title: 'One Hundred Years of Solitude', author: 'Gabriel Garcia Marquez' }, { title: 'The Catcher in the Rye', author: 'J.D. Salinger' }, { title: 'Brave New World', author: 'Aldous Huxley' }, ] function BookSearch() { const [query, setQuery] = useState('') // Create the Fuse instance once — the index is built at construction time const fuse = useMemo(() => { return new Fuse(books, { keys: ['title', 'author'], // fields to search threshold: 0.4, // 0 = exact, 1 = match anything }) }, []) const results = query ? fuse.search(query) : [] // Show search results when there's a query, full list otherwise const displayItems = results.length > 0 ? results.map(({ item }) => item) : books return (
setQuery(e.target.value)} />
    {displayItems.map((book) => (
  • {book.title} — {book.author}
  • ))}
) } ``` -------------------------------- ### Event Listener for Benchmark Button (JavaScript) Source: https://github.com/krisk/fuse/blob/main/bench/parallel-browser/index.html Attaches a click event listener to the 'runBtn' element to trigger the benchmark execution when clicked. ```javascript document.getElementById('runBtn').addEventListener('click', runBenchmark) ``` -------------------------------- ### Memoize Fuse Index for Performance Source: https://github.com/krisk/fuse/blob/main/docs/articles/using-fuse-with-react.md Pre-build and cache the Fuse index using `useMemo` to avoid rebuilding it on every render, which is beneficial for large datasets and frequent data changes. ```jsx import { useMemo } from 'react' import Fuse from 'fuse.js' function useSearch(items, keys, query) { const fuse = useMemo(() => { // Pre-build the index so Fuse doesn't rebuild it on every new instance const index = Fuse.createIndex(keys, items) // pass pre-built index return new Fuse(items, { keys, threshold: 0.4 }, index) }, [items, keys]) return query ? fuse.search(query) : [] } ``` -------------------------------- ### Enable Extended Search Source: https://github.com/krisk/fuse/blob/main/docs/extended-search.md Initialize Fuse with the `useExtendedSearch: true` option to enable extended search operators. Ensure the keys you want to search are specified. ```javascript const fuse = new Fuse(list, { useExtendedSearch: true, keys: ['title', 'author'] }) ``` -------------------------------- ### Extended Search Operators Source: https://github.com/krisk/fuse/blob/main/README.md Demonstrates the use of extended search operators for precise control, including exact match (=), prefix (^), and suffix (!). Enable with `useExtendedSearch: true`. ```javascript 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 ``` -------------------------------- ### Include Fuse.js via CDN Source: https://github.com/krisk/fuse/blob/main/README.md Includes the Fuse.js library directly in an HTML file using a CDN link. ```html ``` -------------------------------- ### FuseWorker Constructor Source: https://github.com/krisk/fuse/blob/main/docs/web-workers.md Initializes a new FuseWorker instance. It takes the dataset, Fuse.js options, and optional worker-specific options. ```APIDOC ## Constructor ```js const fuse = new FuseWorker(docs, options?, workerOptions?) ``` - **`docs`** — Array of documents to search (same as `Fuse`) - **`options`** — Fuse.js options (same as `Fuse`: `keys`, `threshold`, `includeScore`, etc.) - **`workerOptions`** — Worker-specific options: | Option | Type | Default | Description | |---|---|---|---| | `numWorkers` | `number` | `navigator.hardwareConcurrency` (max 8) | Number of parallel workers | | `workerUrl` | `string \| URL` | Auto-resolved | Custom path to the worker script | ``` -------------------------------- ### Create a new git branch Source: https://github.com/krisk/fuse/blob/main/CONTRIBUTING.md Before submitting a pull request, create a new git branch for your changes. This helps keep your work isolated. ```shell git checkout -b my-fix-branch main ``` -------------------------------- ### Commit changes Source: https://github.com/krisk/fuse/blob/main/CONTRIBUTING.md Commit your changes using a descriptive message that follows the project's commit message conventions. This is required for automated release notes. ```shell git commit -a ``` -------------------------------- ### Amend commits and force push Source: https://github.com/krisk/fuse/blob/main/CONTRIBUTING.md If changes are suggested, you can amend initial commits and force push them to your branch. This is often easier than creating separate commits for iterations. ```shell git rebase main -i git push origin my-fix-branch -f ``` -------------------------------- ### Benchmark Runner Function Source: https://github.com/krisk/fuse/blob/main/bench/parallel-browser/index.html A generic function to run a benchmark for a given task. It includes a warmup phase and measures the average, minimum, and maximum execution times over a specified number of runs. ```javascript async function bench(label, fn, runs) { for (let i = 0; i < WARMUP_RUNS; i++) await fn() const times = [] for (let i = 0; i < runs; i++) { const start = performance.now() await fn() times.push(performance.now() - start) } const avg = times.reduce((a, b) => a + b, 0) / times.length return { label, avg, min: Math.min(...times), max: Math.max(...times) } } ``` -------------------------------- ### add(doc) Source: https://github.com/krisk/fuse/blob/main/docs/web-workers.md Adds a single document to the dataset. The document is added to one of the worker shards using a round-robin distribution. ```APIDOC ## `add(doc)` ```js await fuse.add({ title: 'New Item', author: 'Jane' }) ``` Adds a document to one of the worker shards (round-robin distribution). ``` -------------------------------- ### Web Worker Search Source: https://github.com/krisk/fuse/blob/main/README.md Shows how to use Fuse.js with Web Workers for searching large datasets without freezing the UI. Search is performed asynchronously. ```javascript import { FuseWorker } from 'fuse.js/worker' const fuse = new FuseWorker(docs, { keys: ['title', 'author', 'description'] }) const results = await fuse.search('query') fuse.terminate() ``` -------------------------------- ### Single-Thread Fuse Search Source: https://github.com/krisk/fuse/blob/main/bench/parallel-browser/index.html Performs searches using Fuse.js in a single-thread environment. Initializes Fuse with provided documents and options, then iterates through queries. ```javascript function searchSingleThread(docs, queries) { const fuse = new Fuse(docs, FUSE_OPTIONS) const results = {} for (const q of queries) results[q] = fuse.search(q) return results } ``` -------------------------------- ### Token Search 'all' Across Fields Source: https://github.com/krisk/fuse/blob/main/docs/token-search.md Illustrates how 'tokenMatch: all' evaluates across all specified fields and array elements within a record. Ensures all query words appear somewhere in the record. ```javascript const products = [ { title: 'Red', description: 'cotton shirt' }, { title: 'Red dress', description: 'silk' } ] new Fuse(products, { useTokenSearch: true, tokenMatch: 'all', keys: ['title', 'description'] }) .search('red shirt') .map((r) => r.item) // → [{ title: 'Red', description: 'cotton shirt' }] ``` -------------------------------- ### Include Fuse.js via CDN as an ES module Source: https://github.com/krisk/fuse/blob/main/docs/getting-started.md Include Fuse.js as an ES module from a CDN. This allows for dynamic imports in modern browsers. ```html ``` -------------------------------- ### Simple client-side search with Fuse.js Source: https://github.com/krisk/fuse/blob/main/docs/articles/vs-semantic-search.md Use Fuse.js for fast, client-side searching of small to medium datasets. This is ideal for searching by name, title, or other known terms. ```javascript // Simple: search 200 items in the browser in <1ms const fuse = new Fuse(items, { keys: ['name', 'description'] }) const results = fuse.search(userInput) ``` -------------------------------- ### Providing a Custom Worker URL Source: https://github.com/krisk/fuse/blob/main/docs/web-workers.md If automatic resolution fails, you can manually specify the path to the `fuse.worker.mjs` file. This is useful when the worker script is served from a static directory. ```javascript const fuse = new FuseWorker(docs, options, { workerUrl: '/static/fuse.worker.mjs' }) ``` -------------------------------- ### Custom Tokenizer with Function (Intl.Segmenter) Source: https://github.com/krisk/fuse/blob/main/docs/token-search.md Implements a custom tokenizer using a function with Intl.Segmenter for locale-aware word segmentation, suitable for CJK and other scripts without whitespace separation. The function must return string[]. ```javascript const segmenter = new Intl.Segmenter('zh', { granularity: 'word' }) const fuse = new Fuse(docs, { useTokenSearch: true, keys: ['text'], tokenize: (text) => Array.from(segmenter.segment(text), (s) => s.isWordLike ? s.segment : null) .filter(Boolean) }) ``` -------------------------------- ### setCollection(docs) Source: https://github.com/krisk/fuse/blob/main/docs/web-workers.md Replaces the entire dataset with a new array of documents. This operation redistributes the data across all workers and rebuilds their indexes. ```APIDOC ## `setCollection(docs)` ```js await fuse.setCollection(newDocs) ``` Replaces the entire dataset. Redistributes across workers and rebuilds indexes. Use this instead of `remove()` — filter your array, then call `setCollection`. ``` -------------------------------- ### Dotted Keys with $path and $val Source: https://github.com/krisk/fuse/blob/main/docs/logical-search.md Handle data with keys containing literal dots by using the $path and $val operators within logical expressions. This requires specifying the key path as an array. ```javascript const books = [ { title: "Old Man's War", author: { 'first.name': 'John', 'last.name': 'Scalzi' } } ] const fuse = new Fuse(books, { keys: ['title', ['author', 'first.name'], ['author', 'last.name']] }) const result = fuse.search({ $and: [ { $path: ['author', 'first.name'], $val: 'jon' }, { $path: ['author', 'last.name'], $val: 'scazi' } ] }) ``` -------------------------------- ### Over-engineered API call for simple search Source: https://github.com/krisk/fuse/blob/main/docs/articles/vs-semantic-search.md Avoid calling an external API for searching small datasets. This pattern is inefficient for tasks that can be handled client-side. ```javascript // Over-engineered: calling an API to search 200 items const response = await fetch('/api/search', { method: 'POST', body: JSON.stringify({ query: userInput }) }) // Server: embeds query → queries Pinecone → returns results // Total time: 300ms, cost: ~$0.001 per query ``` -------------------------------- ### Update local main with upstream changes Source: https://github.com/krisk/fuse/blob/main/CONTRIBUTING.md After cleaning up your local branches, update your local main branch with the latest changes from the upstream repository. ```shell git pull --ff upstream main ``` -------------------------------- ### Complete Fuzzy Search Component in React Source: https://github.com/krisk/fuse/blob/main/docs/articles/using-fuse-with-react.md A comprehensive React component that combines debouncing, Fuse.js searching with memoization, and highlighting of matched terms. It includes a basic input and a list to display results. ```jsx import { useEffect, useMemo, useState } from 'react' import Fuse from 'fuse.js' function useDebounce(value, delay) { const [debounced, setDebounced] = useState(value) useEffect(() => { const timer = setTimeout(() => setDebounced(value), delay) return () => clearTimeout(timer) }, [value, delay]) return debounced } function highlightMatches(text, regions = []) { if (!regions.length) return text const chunks = [] let lastIndex = 0 for (const [start, end] of regions) { if (start > lastIndex) chunks.push(text.slice(lastIndex, start)) chunks.push({text.slice(start, end + 1)}) lastIndex = end + 1 } if (lastIndex < text.length) chunks.push(text.slice(lastIndex)) return chunks } function FuzzySearch({ items, keys, itemKey, placeholder = 'Search...' }) { const [query, setQuery] = useState('') const debouncedQuery = useDebounce(query, 200) // Recreate Fuse only when items or keys change const fuse = useMemo( () => new Fuse(items, { keys, includeMatches: true, threshold: 0.4 }), [items, keys] ) // Cap results to keep rendering fast const results = debouncedQuery ? fuse.search(debouncedQuery, { limit: 50 }) : [] return (
setQuery(e.target.value)} />
    {results.length > 0 ? results.map(({ item, matches }) => (
  • {keys.map((key) => { const match = matches?.find((m) => m.key === key) return ( {highlightMatches(item[key], match?.indices)}{' '} ) })}
  • )) : items.slice(0, 50).map((item) => (
  • {keys.map((key) => ( {item[key]} ))}
  • ))}
) } ``` -------------------------------- ### Token Search with Multiple Words Source: https://github.com/krisk/fuse/blob/main/README.md Shows token search matching multiple words with typos, demonstrating its ability to find relevant results even with misspellings and word order variations. ```javascript const fuse = new Fuse(docs, { useTokenSearch: true, keys: ['title', 'body'] }) fuse.search('express midleware rout') // Finds "Express Middleware" and "Express Routing Guide" despite typos ```