Come for the speed,stay for the quality.

A zero-bs fork of Orama maintained by the original team.
Full-text, vector, and hybrid search in your browser, server, or edge - in less than 2kb.

Benchmarks

Quality vs speed

Macro-average BEIR nDCG@10 against Node.js throughput. Up and to the right is better; throughput uses a logarithmic scale.

0.00.10.20.30.40.5101001.0k10k100k1000kSearch quality · macro nDCG@10 →Throughput · ops/s →OramaOrama · 0.222 nDCG@10 · 32k ops/sZBSearch (BM25)ZBSearch (BM25) · 0.453 nDCG@10 · 73k ops/sZBSearch (QPS)ZBSearch (QPS) · 0.112 nDCG@10 · 48k ops/sZBSearch (PT15)ZBSearch (PT15) · 0.164 nDCG@10 · 74k ops/sFlexSearchFlexSearch · 0.168 nDCG@10 · 299k ops/sFuse.jsFuse.js · 0.066 nDCG@10 · 35 ops/sLunrLunr · 0.425 nDCG@10 · 10k ops/sMiniSearchMiniSearch · 0.305 nDCG@10 · 43k ops/s
ZBSearchOther enginesDashed line and rings mark the Pareto frontier: no other engine is both faster and better.Quality and throughput use different benchmark corpora; compare the tradeoff, not absolute latency.

API

As simple as it gets

Just create an instance, insert your data, and start searching. No server, no database, no hassle.

app.ts
import { create, insert, search } from 'zbsearch'

const db = create({
  schema: {
    title: 'string',
    embedding: 'vector[384]',
  },
})

await insert(db, {
  title: 'Noise cancelling headphones',
  embedding: [0.8271, 0.9274, 0.8371, 0,1723, 0.5291, ...],
})

const results = search(db, {
  term: 'best headphones',
  mode: 'hybrid',
})

Search box

Headless, so it looks like your site

@zbsearch/searchbox-react ships the behaviour - searching, grouping, keyboard nav, a11y. The look is a handful of CSS variables. Switch themes and type; the index is running in your browser.