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

rerankers

v0.1.0

Published

Browser-compatible reranking library powered by Transformers.js and open Hugging Face models.

Readme

Run local reranking models directly in your JavaScript/TypeScript application.

Why rerankers?

In RAG and other retrieval workflows, returning accurate results is a trade off between search capabilities and speed. Embedding models and vector indexes are good at returning semantically similar results fast. Cross-encoding rerankers are much more accurate, but slower, because they compare the query with each document at ranking time.

This library uses @huggingface/transformers to make it easy to rerank documents against queries using local models.

Demo

You can see this library in action in a live reranking demo.

How it works

Install

Install the library from npm.

npm install rerankers

Using the library

This package uses @huggingface/transformers. Models are downloaded on first use and cached by Transformers.js.

import { Reranker } from "rerankers";

const query = "How can I reduce the initial load time of a JavaScript web application?";

const documents = [
  {
    id: "doc-1",
    text: "Code splitting lets a JavaScript application load only the code needed for the current page. Dynamic imports and route-based chunks can significantly reduce the initial bundle size.",
  },
  {
    id: "doc-2",
    text: "JavaScript is a programming language commonly used to add interactive behaviour to websites and build server-side applications with Node.js.",
  },
  {
    id: "doc-3",
    text: "Compressing images, serving modern formats such as WebP or AVIF, and lazy-loading below-the-fold media can improve page load performance.",
  },
  {
    id: "doc-4",
    text: "Tree shaking removes unused exports from a production bundle. It works best with ES modules and can reduce the amount of JavaScript downloaded during the initial page load.",
  },
  {
    id: "doc-5",
    text: "A service worker can cache application assets after the first visit, making repeat visits faster and allowing some functionality to work offline.",
  },
];

const reranker = await Reranker.create({ model: "mixedbread-ai/mxbai-rerank-base-v1" });
const results = await reranker.rank(query, documents, { topK: 3 });

console.log(results);
// => [
//   {
//     document: {
//       id: "doc-1",
//       text: "Code splitting lets a JavaScript application load only the code needed for the current page. Dynamic imports and route-based chunks can significantly reduce the initial bundle size."
//     },
//     index: 0,
//     score: 0.9616439938545227
//   },
//   {
//     document: {
//       id: "doc-4",
//       text: "Tree shaking removes unused exports from a production bundle. It works best with ES modules and can reduce the amount of JavaScript downloaded during the initial page load."
//     },
//     index: 3,
//     score: 0.9472419619560242
//   },
//   {
//     document: {
//       id: "doc-5",
//       text: "A service worker can cache application assets after the first visit, making repeat visits faster and allowing some functionality to work offline."
//     },
//     index: 4,
//     score: 0.4266827702522278
//   }
// ]

Model config

You can just pass a Hugging Face model ID and default options will be used to load the model. Specifically, the dtype will be set to auto.

const reranker = await Reranker.create({
  model: "mixedbread-ai/mxbai-rerank-large-v1",
});

If you want to pass more options, such as a specific dtype or device, you can pass a transformerOptions property like this:

const reranker = await Reranker.create({
  model: "mixedbread-ai/mxbai-rerank-large-v1",
  transformerOptions: {
    device: "wasm",
    dtype: "q8",
  },
});

For more on dtypes or device options check the Transformers.js documentation.

Models

These models have been tested and work with rerankers. Other reranking models with ONNX weights should also work.

| Model | Parameters | Languages | Context | | --------------------------------------------------------------------------------------------------------- | ---------: | ------------------- | ------: | | Xenova/ms-marco-TinyBERT-L-2-v2 | 4.4M | English | 512 | | Xenova/ms-marco-MiniLM-L-2-v2 | 15.6M | English | 512 | | Xenova/ms-marco-MiniLM-L-4-v2 | 19.2M | English | 512 | | Xenova/ms-marco-MiniLM-L-6-v2 | 22.7M | English | 512 | | Xenova/ms-marco-MiniLM-L-12-v2 | 33.4M | English | 512 | | jinaai/jina-reranker-v1-tiny-en | 33.0M | English | 8,192 | | jinaai/jina-reranker-v1-turbo-en | 37.8M | English | 8,192 | | mixedbread-ai/mxbai-rerank-xsmall-v1 | 70.8M | English | 512 | | mixedbread-ai/mxbai-rerank-base-v1 | 184M | English | 512 | | Xenova/bge-reranker-base | ~278M | Chinese and English | 512 | | mixedbread-ai/mxbai-rerank-large-v1 | 435M | English | 512 | | Xenova/bge-reranker-large | ~560M | Chinese and English | 512 | | onnx-community/bge-reranker-v2-m3-ONNX | 568M | Multilingual | 8,192 |

Documents

Documents can be strings or objects. Object documents are returned unchanged.

const results = await reranker.rank("red planet", [
  { id: "venus", text: "Venus is hot.", metadata: { source: "encyclopedia" } },
  { id: "mars", text: "Mars is called the Red Planet.", metadata: { source: "encyclopedia" } },
]);

Each result includes:

type RerankResult<TDocument> = {
  document: TDocument;
  index: number;
  score: number;
};

Releasing resources

A reranker keeps its model loaded so it can be reused across calls. Models can be large and occupy a significant amount of memory. When you no longer need it, call dispose() to release the model's inference sessions and regain the memory:

const reranker = await Reranker.create({
  model: "mixedbread-ai/mxbai-rerank-base-v1",
});

try {
  const results = await reranker.rank(query, documents);
} finally {
  await reranker.dispose();
}

Reranker also implements AsyncDisposable, so runtimes that support explicit resource management can dispose it automatically:

await using reranker = await Reranker.create({
  model: "mixedbread-ai/mxbai-rerank-base-v1",
});

const results = await reranker.rank(query, documents);

Disposal waits for active ranking calls to finish and is safe to call more than once. A disposed reranker cannot be used again, trying to do so will throw a RerankerDisposedError.

Ecosystem plugins

LangChain

Install LangChain core alongside this package:

npm install rerankers @langchain/core

Use the LocalReranker adapter from the rerankers/langchain subpath anywhere LangChain expects a document compressor.

import { LocalReranker } from "rerankers/langchain";
import { Document } from "@langchain/core/documents";

// Using the documents from the first example
const lcDocs = documents.map(
  (doc) =>
    new Document({
      pageContent: doc.text,
      metadata: { id: doc.id },
    }),
);

const reranker = new LocalReranker({
  model: "mixedbread-ai/mxbai-rerank-base-v1",
  topK: 5,
});

try {
  const documents = await reranker.compressDocuments(lcDocs, query);
} finally {
  await reranker.dispose();
}

Returned LangChain documents are the original document objects in reranked order. Each returned document receives metadata.relevanceScore.

You can pass transformerOptions in the same initializer object

const reranker = new LocalReranker({
  model: "mixedbread-ai/mxbai-rerank-base-v1",
  transformerOptions: {
    dtype: "q8",
    device: "gpu",
  },
  topK: 5,
});

For full lifecycle control, pass an already-created reranker:

import { Reranker } from "rerankers";

const coreReranker = await Reranker.create({ model: "mixedbread-ai/mxbai-rerank-base-v1" });
const reranker = new LocalReranker({ reranker: coreReranker, topK: 5 });

LocalReranker.dispose() delegates to its core reranker, including when the core reranker was injected. LocalReranker also supports await using through Symbol.asyncDispose.

Use rerank() when you want raw scores without mutating LangChain document metadata:

const results = await reranker.rerank(documents, "red planet", { topK: 5 });
// [{ index: 1, relevanceScore: 0.92 }, ...]

Vercel AI SDK

Install the AI SDK alongside this package, then use the rerankers/ai-sdk adapter anywhere AI SDK expects a reranking model.

npm install rerankers ai
import { rerank } from "ai";
import { rerankers } from "rerankers/ai-sdk";

await using model = rerankers.rerankingModel({
  model: "mixedbread-ai/mxbai-rerank-base-v1",
});

const { ranking, rerankedDocuments } = await rerank({
  model,
  query: "Which document mentions Mars?",
  documents: [
    "Venus has a thick atmosphere.",
    "Mars is called the Red Planet.",
    "Jupiter is the largest planet.",
  ],
  topN: 2,
});

The returned model owns its local reranker and supports both dispose() and Symbol.asyncDispose for releasing it.

AI SDK object documents are supported with a text extractor. If you do not provide one, the adapter uses a string text property when present and falls back to JSON.stringify(document).

const model = rerankers.rerankingModel(
  { model: "Xenova/bge-reranker-base" },
  {
    documentText: (document) => `${document.title}: ${document.body}`,
  },
);

Browser And Node

The package is ESM and keeps the runtime path compatible with browsers and Node.js. Use Transformers.js options such as device and dtype to tune runtime behavior.

License

MIT