Fuse README

The project's README from github.com/krisk/Fuse. As one markdown file: README.md.

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.

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.

Web Workers

Search large datasets without freezing the UI. FuseWorker splits your data across multiple Web Workers and searches in parallel — ~5x faster on 100K documents.

import { FuseWorker } from 'fuse.js/worker'

const fuse = new FuseWorker(docs, {
  keys: ['title', 'author', 'description']
})

const results = await fuse.search('query')
fuse.terminate()

Same options and results as Fuse — just async. Function-valued options (sortFn, getFn, keys[].getFn) aren't supported because functions can't be transferred to a worker; everything else carries over. See the Web Workers docs for the interactive demo and full API.

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

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 }
  ]
})

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

Object Query Syntax

Prefer a structured, self-documenting alternative to the magic characters? Express the same operators as an object. Unlike the string form, this needs no useExtendedSearch flag (the operators are unambiguous), autocompletes in TypeScript, and needs no quoting or escaping.

const fuse = new Fuse(list, { keys: ['title', 'author'] })

fuse.search({ title: { $startsWith: 'old' }, author: { $eq: 'Kay' } })

Each operator maps to a string equivalent:

Object String Matches when the field
$fuzzy term fuzzy-matches (typo tolerant)
$eq =term equals the value
$contains 'term contains the value
$startsWith ^term starts with the value
$endsWith term$ ends with the value

Negate with $not, which wraps exactly one of $contains, $startsWith, or $endsWith:

fuse.search({ title: { $not: { $contains: 'draft' } } }) // === '!draft'
fuse.search({ title: { $not: { $startsWith: 'old' } } }) // === '!^old'
fuse.search({ title: { $not: { $endsWith: '.go' } } }) // === '!.go$'

Multiple operators on one field are AND-ed; use field-local $and / $or for more, and compose across fields with logical search:

// starts with "old" AND does not contain "draft"
fuse.search({ title: { $startsWith: 'old', $not: { $contains: 'draft' } } })

// title starts with "old" OR ends with "war"
fuse.search({ title: { $or: [{ $startsWith: 'old' }, { $endsWith: 'war' }] } })

Object queries return identical results to the equivalent string query, and validate strictly: unknown operators, empty or non-string values, and illegal nesting throw instead of silently degrading to a fuzzy search. Available in the full build. See the Extended Search docs for the full grammar.

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

Available in the full build. See the Token Search docs for details and performance benchmarks.

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]] }

Fuse.match() does not support useTokenSearch — token search requires corpus-level statistics (df, fieldCount) that a one-off string comparison can't provide. Passing useTokenSearch: true throws an explicit error. Use new Fuse(docs, { useTokenSearch: true }).search(query) for token-search behavior.

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:

Build Includes Min + gzip
Full Fuzzy + Extended + Logical + Token search ~8.6 kB
Basic Fuzzy search only ~6.8 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.

Official ports

Supporting Fuse.js

Develop

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

Contribute

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

Fuse (krisk/Fuse)

Searching Database…

20.5K ·GitHub
这是什么?Fuse.js 是一个轻量级、零依赖的 JavaScript 和 TypeScript 模糊搜索库。它既能在浏览器里运行,也能在 Node 上运行,专为在客户端搜索中小型数据集而设计,不需要专门搭建一个搜索后端。
所以它是一个打包进我自己代码里的库,而不是托管服务,对吧?对——它是一个引入到你自己的 JavaScript 项目里的库,没有任何服务器组件。你把数据在内存中建好索引,然后在代码运行的任何地方调用 .search(),浏览器或服务器都行。
怎么把它加到我的项目里?从 npm 安装(npm install fuse.js),或者直接通过 CDN 引入,然后用 new Fuse(docs, options) 包装你的数据,再调用 .search(query) 就可以了。
它会依赖其他包吗?需要什么特殊环境吗?不用——它没有任何运行时依赖。现代浏览器都能用,在服务器上 Node.js 10 或更高版本就足够了。
数据集多大就不适合用它了?它面向的是没有专门搜索后端的中小型客户端数据集。如果数据量很大——大约 10 万条文档——请改用 FuseWorker 并行搜索,别在主线程上跑。
什么是 Token Search?这是一个可选模式(useTokenSearch: true),用于多词查询:每个词独立进行模糊匹配,结果按 BM25 风格的 IDF 权重排序,所以生僻词权重更高,词序也不影响结果。输入 'javascrpt paterns',照样能找到 'JavaScript Patterns'。
它能做精确筛选,而不只是模糊匹配吗?可以——扩展搜索提供了精确匹配(=)和前缀(^)等操作符,还能和 $and/$or 组合使用。另外还有一种对象查询语法($eq、$startsWith、$not),不需要任何开关,遇到无效输入会直接报错,而不是悄悄降级成模糊搜索。
我能在不重建索引的情况下添加或删除文档吗?可以——动态集合让你直接在一个已建好的索引里添加和删除文档,无需重建。
有 Swift 或 iOS 应用的版本吗?有——fuse-swift 是官方移植版,支持 iOS、macOS、tvOS、watchOS、visionOS 和 Linux,搜索结果逐字节一致,并提供地道的 Swift API。当前版本是 2.0.0-rc.1。
Creator
krisk
Size
11.1 MB
Stars
20.5K
Age
14y
Commits · 90 Days