Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@nozbe/microfuzz

Package Overview
Dependencies
Maintainers
6
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@nozbe/microfuzz

A tiny, simple, fast fuzzy search library

  • 0.1.5
  • next
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
8.6K
increased by15.03%
Maintainers
6
Weekly downloads
 
Created
Source

microfuzz in action in Nozbe

microfuzz

A tiny, simple, fast JS fuzzy search library

✨ Easily add power user-friendly search, autocomplete, jump to, command palette to your app.

MIT License npm

microfuzz
🤓Fuzzy search. Power users love it
🗜️Tiny. 2KB gzipped
Simple. Only a few options, reasonable defaults
⚡️Fast. Filter thousands of items in milliseconds
🧰Framework-agnostic. Plain JS, no dependencies
⚛️React/React Native helpers (optional) included
⚠️Static typing with Flow or TypeScript

microfuzz pitch

General idea of how microfuzz works:

  • Case-insensitive and diacritics-insensitive search
  • Works with Latin script, Cyrillic, rudimentary CJK support
  • Limited fuzzing: matches query letters in order, but they don't have to be consecutive (but transposition and missing characters are not allowed)
  • Some very poor fuzzy matches are rejected by default (see Fuzzy search strategies)
  • Additionally, matches query words in any order
  • NOT full-text search. Stemming, soundex, levenstein, autocorrect are not included
  • Sorts by how well text matches the query with simple heuristics (for equal fuzzy score, input order is preserved, so you can pre-sort array if you want).
  • Returns ranges of matching characters for pretty highlighting
  • In-memory search, no indexing

microfuzz is not a one-size-fits-all solution (see Alternatives to consider).

Using microfuzz (plain JS)

import createFuzzySearch from '@nozbe/microfuzz'

const list = [/* an array of strings to fuzzy search */]
const fuzzySearch = createFuzzySearch(list)

// Run this whenever search term changes
// Only matching items will be returned, sorted by how well they match `queryText`
const results = fuzzySearch(queryText)

This is split into two steps for performance (createFuzzySearch pre-processes list, and you can cache/memoize function returned by it).

If list is an array of objects:

const fuzzySearch = createFuzzySearch(list, {
  // search by `name` property
  key: 'name',
  // search by `description.text` property
  getText: (item) => [item.description.text]
  // search by multiple properties:
  getText: (item) => [item.name, item.description.text]
})

Using microfuzz in React

If you use React or React Native, you can use these optional helpers for convenience:

import { useFuzzySearchList, Highlight } from '@nozbe/microfuzz/react'

// `useFuzzySearchList` simply wraps `createFuzzySearch` with memoization built in
// NOTE: For best performance, `getText` and `mapResultItem` should be memoized by user
const filteredList = useFuzzySearchList({
  list,
  // If `queryText` is blank, `list` is returned in whole
  queryText,
  // optional `getText` or `key`, same as with `createFuzzySearch`
  getText: (item) => [item.name],
  // arbitrary mapping function, takes `FuzzyResult<T>` as input
  mapResultItem: ({ item, score, matches: [highlightRanges] }) => ({ item, highlightRanges })
})

// Render `filteredList`'s labels with matching characters highlighted
filteredList.map(({ item, highlightRanges }) => (
  <Item key={item.key}>
    <Label><Highlight text={item.name} ranges={highlightRanges} /></Label>
  </Item>
))

Fuzzy search strategies

You can optionally pass { strategy: } parameter to createFuzzySearch / useFuzzySearchList:

  • 'off' - no fuzzy search, only matches if item contains query (or contains query words in any order)
  • 'smart' - (default) matches letters in order, but poor quality matches are ignored
  • 'aggressive' - matches letters in order with no restrictions (classic fuzzy search)

Alternatives to consider

I wrote microfuzz simply because I didn't quite like how other fuzzy search libraries I found worked, for my use case. Your mileage may vary.

It's not the tiniest, the simplest, or the fastest implementation you can find. But it's tiny, simple, and fast enough, while providing fuzzy search heuristics and sorting that I found to work reasonably well in Nozbe, a project management app, where it's used to filter down or autocomplete lists of short labels — names of projects, sections, tasks, user names, etc.

By "fast" I mean that on my computer, with a list of ~4500 labels, the first search (one-letter search query) takes ~7ms, while subsequent searches take less than 1.5ms — all in-memory, without indexing. More than fast enough to search on every keystroke without any lag.

If you have much larger lists to fuzzy-search, you may find the performance unsatisfactory — consider implementations with simpler heuristics or indexing. For very long strings (notes, comments), fuzzy-searching may not be the right strategy — consider Full-Text Search (with indexing) instead.

Feel free to contribute improvements to sorting heuristics or alternative search strategies (provided that the "fast, simple, tiny" criteria don't suffer too much).

Alternatives:

  • Fuse.js - popular implementation with many more options, including extended search and indexing. However, while its scoring (sorting) is much more sophisticated in theory, I found it unsatisfactory in practice.
  • fuzzysort - optimized for fuzzy searching lists of file names/file paths, but I don't like its scoring for natural language labels
  • MiniSearch
  • fuzzy
  • fuzzy-search - an even simpler implementation than microfuzz
  • fuzzysearch - tiniest implementation of the list

Author and license

microfuzz was created by @Nozbe.

microfuzz's main author and maintainer is Radek Pietruszewski (websitetwitterengineering posters)

See all contributors.

microfuzz is available under the MIT license. See the LICENSE file for more info.

Keywords

FAQs

Package last updated on 18 Jul 2023

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc