BrowserVec

In-browser WebGPU vector store with custom WGSL kernels — embeddings, similarity search, and persistence, all client-side, no server round-trip.

npm license
Try the demo Browse examples GitHub

01Status

M1–M5 complete, M6 mostly complete.  Flat brute-force + IVF approximate search, fp32/int8/int4/1-bit quantization (every combination), OPFS/IndexedDB persistence with optional AES-256-GCM encryption, an on-device text embedder, Worker-offloaded ingest, and a WASM-SIMD CPU fallback for devices without WebGPU. Cross-device tuning is the one open item.

See CHANGELOG.md for release history.

02Install

npm install browservec
import { BrowserVec } from 'browservec';

Requires a browser with WebGPU for the GPU-accelerated path; falls back to a WASM-SIMD/scalar CPU path (exact fp32 flat search) where WebGPU is unavailable.

03Quick start

npm install
npm run dev        # open the printed URL → demo/index.html (needs a WebGPU browser)

Or skip the local setup entirely — open the hosted demo. It builds a random corpus, runs a GPU top-k query, and checks recall against a CPU brute-force reference.

04Core API

import { BrowserVec } from 'browservec';

BrowserVec.isSupported(); // { webgpu, opfs, wasm }

const db = await BrowserVec.create({ dimension: 768, metric: 'cosine' });

await db.addBatch([
  { id: 'a', vector: vecA, metadata: { lang: 'en' } },
  { id: 'b', vector: vecB },
]);

const hits = await db.query(queryVec, { k: 5 });
// → [{ id, score, metadata? }, ...]  (higher score = closer)

db.get('a');     // → { id, vector, metadata? } | null
db.delete('a');  // tombstone by id → true/false (compacted on save)
await db.update({ id: 'a', vector: v2 }); // replace/upsert a vector
await db.compact();                       // physically drop tombstones (no reload)
db.stats();      // { count, deleted?, dimension, metric, device, lastQueryMs, persist? }
db.destroy();    // free GPU resources

Full method/type reference: docs/api-reference.md.

05Features

FeatureWhat it does
Deleting vectorsTombstone-based delete/update/compact — cheap deletes, GPU memory reclaimed on compact or reload.
PersistenceVersioned binary snapshots to OPFS (or IndexedDB), auto-load on create(), export/import as a Blob.
Encryption at restAES-256-GCM + PBKDF2 passphrase envelope for persisted/exported snapshots.
Quantization (TurboQuant)int8/int4/1-bit codes via randomized Hadamard rotation + exact fp32 re-rank — ~4×/8×/32× less memory.
Approximate search (IVF)GPU-assisted k-means clustering; queries scan only the nearest nprobe clusters.
Text retrieval / embedderaddText/queryText via a zero-dep hashing embedder or an optional transformers.js model.
Worker ingest offloadRotate+quantize and IVF k-means mean-updates run off the main thread so ingest doesn't freeze the UI.
Corpus chunkingCorpus spreads across multiple GPU buffers past the device's per-buffer limit — transparent, same results.
GPU top-kTop-k reduction runs on the GPU past 4k rows, so only a short candidate list is read back per query.
CPU fallbackExact WASM-SIMD flat scan when WebGPU is unavailable — bit-identical to the GPU path.

06Benchmarks

From the demo's M6 device report tool (fixed-seed 20k×384 corpus, recall@10 against an exact fp32 reference). Chrome 149 / macOS, Apple M-series (Metal-3).

Configrecall@10Query latency
flat fp321.0001.71 ms/q
flat int81.0001.52 ms/q
flat int41.0001.69 ms/q
flat 1-bit1.0002.45 ms/q
IVF fp321.0000.51 ms/q
IVF int81.0000.63 ms/q
IVF int41.0000.93 ms/q
IVF 1-bit1.0001.11 ms/q
CPU fallback (WASM-SIMD), 8k rows1.76 ms/q

Run the tool yourself in the demo or the interactive perf-benchmark example. Full matrix, takeaways, and methodology in the README.

07Explore

Live demo

Interactive M1–M6 benchmark runner — flat/IVF search, quantization, persistence, encryption, and the M6 device report tool, all in one page.

Examples gallery

26 runnable examples — real-world use cases (RAG chat, knowledge base, recommenders), core concepts, embeddings, persistence, and performance benchmarks.

08Docs & further reading