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 (
)
}
```
```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 (
)
}
```
--------------------------------
### 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 (
)
}
```
--------------------------------
### 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
``` |