Edgevec
High-performance vector search for Browser, Node, and Edge
Install / Use
/learn @matte1782/EdgevecREADME
EdgeVec
The first WASM-native vector database. Dense + sparse vectors, hybrid search, binary quantization, metadata filtering — all in the browser.
EdgeVec is an embedded vector database built in Rust with first-class WebAssembly support. It brings server-grade vector database features to the browser: HNSW + FlatIndex, sparse vectors with BM25, hybrid search (RRF fusion), 32x memory reduction via binary quantization, metadata filtering, soft delete, persistence, and sub-millisecond search.
Why EdgeVec?
| Feature | EdgeVec | hnswlib-wasm | Pinecone | |:--------|:-------:|:------------:|:--------:| | Vector Search | Yes | Yes | Yes | | Binary Quantization | Yes (32x) | No | No | | Metadata Filtering | Yes | No | Yes | | Sparse Vectors | Yes | No | Yes | | Hybrid Search (RRF) | Yes | No | Yes | | FlatIndex (exact) | Yes | No | Limited | | BinaryFlatIndex | Yes | No | No | | SQL-like Queries | Yes | No | Yes | | Memory Pressure API | Yes | No | No | | Soft Delete | Yes | No | Yes | | Persistence | Yes | No | Yes | | Browser-native | Yes | Yes | No | | No server required | Yes | Yes | No | | Offline capable | Yes | Yes | No |
EdgeVec is the only WASM vector database with binary quantization, sparse vectors, hybrid search, BinaryFlatIndex, and filtered search.
Try It Now
Build filters visually, see live results, copy-paste ready code:
Filter Playground - Interactive filter builder with live sandbox
- Visual filter construction
- 10 ready-to-use examples
- Live WASM execution
- Copy-paste code snippets (JS/TS/React)
Quick Start
npm install edgevec
import init, { EdgeVec } from 'edgevec';
await init();
// Create index (768D for embeddings like OpenAI, Cohere)
const db = new EdgeVec({ dimensions: 768 });
// Insert vectors with metadata (v0.6.0)
const vector = new Float32Array(768).map(() => Math.random());
const id = db.insertWithMetadata(vector, {
category: "books",
price: 29.99,
inStock: true
});
// Search with filter expression (v0.6.0)
const query = new Float32Array(768).map(() => Math.random());
const results = db.searchWithFilter(query, 'category = "books" AND price < 50', 10);
// Fast BQ search with rescoring — 32x less memory, 95% recall (v0.6.0)
const fastResults = db.searchBQ(query, 10);
// Monitor memory pressure (v0.6.0)
const pressure = db.getMemoryPressure();
if (pressure.level === 'warning') {
db.compact(); // Free deleted vectors
}
Interactive Demos
Try EdgeVec directly in your browser:
| Demo | Description | |:-----|:------------| | Entity-RAG Demo | Entity-enhanced search on 1000 SQuAD paragraphs, boost ON/OFF toggle (NEW!) | | Filter Playground v0.7.0 | Visual filter builder with live sandbox | | v0.6.0 Cyberpunk Demo | BQ vs F32 comparison, metadata filtering, memory pressure | | Demo Hub | All demos in one place |
Run locally:
| Demo | Path |
|:-----|:-----|
| SIMD Benchmark | wasm/examples/simd_benchmark.html |
| Benchmark Dashboard | wasm/examples/benchmark-dashboard.html |
| Soft Delete Demo | wasm/examples/soft_delete.html |
| Main Demo | wasm/examples/index.html |
# Run demos locally
git clone https://github.com/matte1782/edgevec.git
cd edgevec
python -m http.server 8080
# Open http://localhost:8080/wasm/examples/index.html
Entity-Enhanced RAG
EdgeVec supports metadata boosting for entity-enhanced retrieval — improve search relevance by incorporating entity signals (ORG, PERSON, GPE) extracted via NER, without building a knowledge graph.
use edgevec::filter::{MetadataBoost, FilteredSearcher, FilterStrategy};
use edgevec::metadata::MetadataValue;
let boosts = vec![
MetadataBoost::new("entity_type".to_string(), MetadataValue::String("ORG".to_string()), 0.3)?,
];
let results = searcher.search_boosted(&query, 10, &boosts, None, FilterStrategy::Auto)?;
Boosts are soft signals that rerank results by reducing distance for matches. Combine with FilterExpression for hard constraints + soft boosting in a single query.
Try the in-browser demo — 1,000 SQuAD paragraphs, entity boost ON/OFF toggle, zero API calls.
Read more: Entity-Enhanced RAG in 300KB
Performance
EdgeVec v0.9.0 uses SIMD instructions for 2x+ faster vector operations on modern browsers.
Distance Calculation (Native Benchmark)
| Dimension | Dot Product | L2 Distance | Throughput | |:----------|:------------|:------------|:-----------| | 128 | 55 ns | 66 ns | 2.3 Gelem/s | | 384 | 188 ns | 184 ns | 2.1 Gelem/s | | 768 | 374 ns | 358 ns | 2.1 Gelem/s | | 1536 | 761 ns | 693 ns | 2.1 Gelem/s |
Search Latency (768D vectors, k=10)
| Scale | EdgeVec | Target | Status | |:------|:--------|:-------|:-------| | 1k vectors | 380 us | <1 ms | 2.6x under | | 10k vectors | 938 us | <1 ms | PASS |
Hamming Distance (Binary Quantization)
| Operation | Time | Throughput | |:----------|:-----|:-----------| | 768-bit pair | 4.5 ns | 40 GiB/s | | Batch 10k | 79 us | 127 Melem/s |
Browser Support
| Browser | SIMD | Performance | |:--------|:-----|:------------| | Chrome 91+ | YES | Full speed | | Firefox 89+ | YES | Full speed | | Safari 16.4+ | YES | Full speed (macOS) | | Edge 91+ | YES | Full speed | | iOS Safari | NO | Scalar fallback |
Note: iOS Safari doesn't support WASM SIMD. EdgeVec automatically uses scalar fallback, which is ~2x slower but still functional.
Bundle Size
| Package | Size (gzip) | Notes | |:--------|:------------|:------| | edgevec | 217 KB | SIMD enabled (541 KB uncompressed) |
Database Features
Binary Quantization (v0.6.0)
32x memory reduction with minimal recall loss:
// BQ is auto-enabled for dimensions divisible by 8
const db = new EdgeVec({ dimensions: 768 });
// Raw BQ search (~85% recall, ~5x faster)
const bqResults = db.searchBQ(query, 10);
// BQ + rescore (~95% recall, ~3x faster)
const rescoredResults = db.searchBQRescored(query, 10, 5);
| Mode | Memory (100k × 768D) | Speed | Recall@10 | |:-----|:---------------------|:------|:----------| | F32 (baseline) | ~300 MB | 1x | 100% | | BQ raw | ~10 MB | 5x | ~85% | | BQ + rescore(5) | ~10 MB | 3x | ~95% |
Metadata Filtering (v0.6.0)
Insert vectors with metadata, search with SQL-like filter expressions:
// Insert with metadata
db.insertWithMetadata(vector, {
category: "electronics",
price: 299.99,
tags: ["featured", "sale"]
});
// Search with filter
db.searchWithFilter(query, 'category = "electronics" AND price < 500', 10);
db.searchWithFilter(query, 'tags ANY ["featured"]', 10); // Array membership
// Complex expressions
db.searchWithFilter(query,
'(category = "electronics" OR category = "books") AND price < 100',
10
);
Operators: =, !=, >, <, >=, <=, AND, OR, NOT, ANY
Filter syntax documentation ->
Memory Pressure API (v0.6.0)
Monitor and control WASM heap usage:
const pressure = db.getMemoryPressure();
// { level: 'normal', usedBytes: 52428800, totalBytes: 268435456, usagePercent: 19.5 }
if (pressure.level === 'warning') {
db.compact(); // Free deleted vectors
}
if (!db.canInsert()) {
console.warn('Memory critical, inserts blocked');
}
Soft Delete & Compaction
// O(1) soft delete
db.softDelete(id);
// Check status
console.log('Live:', db.liveCount());
console.log('Deleted:', db.deletedCount());
// Reclaim space when needed
if (db.needsCompaction()) {
const result = db.compact();
console.log(`Removed ${result.tombstones_removed} tombstones`);
}
Persistence
// Save to IndexedDB (browser) or filesystem
await db.save("my-vector-db");
// Load existing database
const db = await EdgeVec.load("my-vector-db");
Scalar Quantization
const config = new EdgeVecConfig(768);
config.quantized = true; // Enable SQ8 quantization
// 3.6x memory reduction: 3.03 GB -> 832 MB at 1M vectors
FlatIndex (v0.9.0)
Brute-force exact nearest neighbor search for small datasets. No graph overhead, 100% recall guarantee.
use edgevec::{FlatIndex, FlatIndexConfig, DistanceMetric};
let config = FlatIndexConfig::new(768)
.with_metric(DistanceMetric::Cosine)
.with_capacity(10_000);
let mut index = FlatIndex::new(config);
// Insert vectors
let id = index.insert(&embedding)?;
// Exact search (100% recall)
let results = index.search(&query, 10)?;
// Persistence via snapshot
let snapshot = index.to_snapshot()?;
let restored = FlatIndex::from_snapshot(&snapshot)?;
When to use FlatIndex: Datasets under ~50K vectors where exact recall matters more than speed.
Sparse Vectors (v0.9.0)
CSR-format sparse vector storage with inverted index for fast keyword-style retrieval.
use edgevec::SparseVector;
use edgevec::sparse::{SparseStorage, SparseSearcher};
//
