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

bloomfilter

v1.1.2

Published

Fast bloom filter in JavaScript.

Readme

Bloom Filter

This JavaScript bloom filter implementation uses the non-cryptographic Fowler–Noll–Vo hash function for speed.

Usage

import { BloomFilter } from 'bloomfilter';

const bloom = new BloomFilter(
  32 * 256, // number of bits to allocate.
  16        // number of hash functions.
);

// Add some elements to the filter.
bloom.add("foo");
bloom.add("bar");

// Test if an item is in our filter.
// Returns true if an item is probably in the set,
// or false if an item is definitely not in the set.
bloom.test("foo");
bloom.test("bar");
bloom.test("blah");

// Serialisation.
const json = JSON.stringify(bloom);

// Deserialisation.
const loadedBloom = BloomFilter.fromJSON(json);

// Automatically pick {m, k} based on number of elements and target false
// positive error rate.
const autoBloom = BloomFilter.withTargetError(1_000_000, 1e-6);

Benchmark

npm run benchmark

To compare the working-tree implementation with the original JavaScript implementation at commit 3703d8a, run this from a Git checkout:

npm run benchmark:compare
npm run benchmark:compare -- --reverse

Both commands use the same runner and fill filters to their expected capacity. The comparison runs four ASCII-key workloads in separate processes and verifies matching filter contents and query results; --reverse reverses execution order.

Each operation warms up for at least 100 ms and three batches, followed by nine measurement samples of at least 5 ms each. Results show medians and ranges in microseconds per operation. Setup, input generation, module startup, and result verification are excluded. Garbage collection may occur during timed operations; it is forced only before warmup. These are local microbenchmarks, so small performance differences should be treated cautiously.

Implementation

Although the bloom filter requires k hash functions, we can simulate this using enhanced double hashing with a single 64-bit FNV-1a hash computation for performance. The 64-bit hash is split into two 32-bit halves to obtain the two independent hash functions required for enhanced double hashing.

Insertion and membership testing generate each location as it is used, avoiding an intermediate locations array and allowing unsuccessful lookups to stop early. The location recurrence uses conditional subtraction in place of remainder where possible. Hashing retains the original UTF-16 code-unit semantics and version-1 serialisation format.

Thanks to Will Fitzgerald for his help and inspiration with the hashing optimisation.