npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

nucleo-matcher-wasm

v0.4.0

Published

Fast fuzzy finder, powered by nucleo-matcher compiled to WebAssembly

Readme

nucleo-matcher-wasm

License Version CI

Fast fuzzy finder, powered by nucleo-matcher compiled to WebAssembly.

nucleo is a highly performant fuzzy matcher written in rust. It aims to fill the same use case as fzf and skim. Compared to fzf, nucleo has a significantly faster matching algorithm. It is used in the helix-editor and therefore has a large user base with lots of real world testing. The core matcher implementation is considered complete and is unlikely to see major changes

Installation

npm i nucleo-matcher-wasm

Usage

import { NucleoMatcher } from 'nucleo-matcher-wasm';

const items = [
    'src/components/Header.svelte',
    'src/utils/helpers.ts',
    'test/fixtures/data.json',
];

// Basic usage (defaults: case-insensitive, smart normalization)
const nucleo = new NucleoMatcher(items);

// With options (file path matching, smart case)
const nucleo = new NucleoMatcher(items, {
    matchPaths: true,
    caseMatching: 'smart',
});

API

matchPattern

Usage: matchPattern(pattern, options?)

Match with fzf-like syntax (^ prefix, $ postfix, ' substring, ! negation):

nucleo.matchPattern('header');
// → [['src/components/Header.svelte', 168]]

nucleo.matchPattern('^src comp');
// → [['src/components/Header.svelte', 168]]

matchLiteral

Usage:matchLiteral(pattern, kind?, options?)

Match literally (no special syntax parsing). kind: "fuzzy" (default), "substring", "prefix", "postfix", "exact":

nucleo.matchLiteral('^src', 'fuzzy');
// Treats ^ as a literal character

nucleo.matchLiteral('test/', 'prefix');
// → [['test/fixtures/data.json', ...]]

matchPatternIndices

Usage: matchPatternIndices(pattern, options?) / matchLiteralIndices(pattern, kind?, options?)

Same as above but also returns matched character indices (for highlighting):

nucleo.matchPatternIndices('header');
// → [['src/components/Header.svelte', 168, [15, 16, 17, 18, 19, 20]]]

setItems

Usage: setItems(items)

Replace the stored item list.

score

Usage: score(pattern, haystack, options?)

Score a single string without pre-loading items:

nucleo.score('hlp', 'helpers.ts');
// → 96

nucleo.score('xyz', 'helpers.ts');
// → undefined

Options

Options can be set in the constructor and the provided matching methods.

matchPaths

[!NOTE]

This option can only be set in the constructor (not per-call).

Values: boolean
Default: false

Treat / and \\ as word boundaries.

preferPrefix

[!NOTE]

This option can only be set in the constructor (not per-call).

Values: boolean
Default: false

Boost matches near the start of the haystack.

caseMatching

Values: "ignore" | "smart" | "respect"
Default: "ignore"

Case sensitivity mode.

normalization

Values: "smart" | "never"
Default: "smart"

Unicode normalization mode

maxResults

[!NOTE]

This option can only be set per-call (not in the constructor).

Values: number
Default: undefined

Cap the result set to the top N matches by score. Skips marshaling discarded results across the WebAssembly boundary, and uses a bounded heap internally rather than scoring + full-sorting all candidates.

nucleo.matchPattern('hdr', { maxResults: 50 });

Benchmarks

This repository contains a benchmark script, testing nucleo-matcher-wasm against some popular fuzzy finder libraries for NodeJS. Here's the gist of it on an Apple M2 Pro with 32GB of RAM:

======================================================================
Dataset: 100 items, 500 iterations per matcher
======================================================================

Averages across all patterns:
  nucleo (literal)        0.005 ms/iter
  nucleo (pattern)        0.007 ms/iter
  fuzzy-search            0.009 ms/iter
  fzy.js                  0.016 ms/iter
  fuzzaldrin-plus         0.017 ms/iter
  fzi                     0.024 ms/iter
  fuzzy                   0.030 ms/iter
  fuzzaldrin              0.031 ms/iter
  fzf                     0.045 ms/iter
  fuse.js                 0.174 ms/iter
  fast-fuzzy              0.514 ms/iter

======================================================================
Dataset: 1,000 items, 500 iterations per matcher
======================================================================

Averages across all patterns:
  nucleo (literal)        0.046 ms/iter
  nucleo (pattern)        0.047 ms/iter
  fuzzy-search            0.087 ms/iter
  fzy.js                  0.175 ms/iter
  fuzzaldrin-plus         0.187 ms/iter
  fzi                     0.265 ms/iter
  fuzzaldrin              0.296 ms/iter
  fuzzy                   0.307 ms/iter
  fzf                     0.430 ms/iter
  fast-fuzzy              0.535 ms/iter
  fuse.js                 1.743 ms/iter

======================================================================
Dataset: 10,000 items, 50 iterations per matcher
======================================================================

Averages across all patterns:
  nucleo (literal)        0.467 ms/iter
  nucleo (pattern)        0.489 ms/iter
  fuzzy-search            0.886 ms/iter
  fzy.js                  1.852 ms/iter
  fuzzaldrin-plus         1.972 ms/iter
  fzi                     2.770 ms/iter
  fuzzaldrin              2.994 ms/iter
  fuzzy                   3.210 ms/iter
  fast-fuzzy              4.120 ms/iter
  fzf                     4.262 ms/iter
  fuse.js                17.832 ms/iter

Try npm run bench to see how well the benchmark performs on your target environment.

Development

Prerequisites

Rust & Cargo

Install via rustup:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

wasm-pack

wasm-pack compiles the Rust crate to WebAssembly and generates JS/TS bindings.

cargo install wasm-pack

Node.js

Node.js ≥ 18 is required for running the playground scripts and publishing to npm.

Building

Build the WASM package targeting Node.js:

wasm-pack build --target nodejs --out-dir dist

License

This work is licensed under Mozilla Public License 2.0 .