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:
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
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) |
Full benchmark report ->
Database Features
Binary Quantization (v0.6.0)
32x memory reduction with minimal recall loss:
const db = new EdgeVec({ dimensions: 768 });
const bqResults = db.searchBQ(query, 10);
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% |
Insert vectors with metadata, search with SQL-like filter expressions:
db.insertWithMetadata(vector, {
category: "electronics",
price: 299.99,
tags: ["featured", "sale"]
});
db.searchWithFilter(query, 'category = "electronics" AND price < 500', 10);
db.searchWithFilter(query, 'tags ANY ["featured"]', 10);
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();
if (pressure.level === 'warning') {
db.compact();
}
if (!db.canInsert()) {
console.warn('Memory critical, inserts blocked');
}
Soft Delete & Compaction
db.softDelete(id);
console.log('Live:', db.liveCount());
console.log('Deleted:', db.deletedCount());
if (db.needsCompaction()) {
const result = db.compact();
console.log(`Removed ${result.tombstones_removed} tombstones`);
}
Persistence
await db.save("my-vector-db");
const db = await EdgeVec.load("my-vector-db");
Scalar Quantization
const config = new EdgeVecConfig(768);
config.quantized = true;
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};
// Create a sparse vector (e.g., BM25 term weights)
let sv = SparseVector::new(
vec![10, 42, 999], // term indices
vec![0.8, 1.2, 0.3], // term weights
30_000, // vocabulary size
)?;
// Store and search
let mut storage = SparseStorage::new();
let id = storage.insert(&sv)?;
let searcher = SparseSearcher::new(&storage);
let results = searcher.search(&query_sv, 10);
Hybrid Search (v0.9.0)
Combine dense (HNSW) and sparse retrieval with Reciprocal Rank Fusion (RRF) or linear fusion.
use edgevec::hybrid::{HybridSearcher, HybridSearchConfig, FusionMethod};
// Set up: HNSW index + sparse storage already populated
let searcher = HybridSearcher::new(&hnsw_index, &dense_storage, &sparse_storage);
let config = HybridSearchConfig::new(
50, // dense_k: candidates from HNSW
50, // sparse_k: candidates from sparse
10, // final_k: results after fusion
FusionMethod::Rrf { k: 60 }, // RRF with k=60
);
let results = searcher.search(&dense_query, &sparse_query, &config)?;
for r in &results {
println!("ID: {}, score: {:.4}, dense_rank: {:?}, sparse_rank: {:?}",
r.id, r.score, r.dense_rank, r.sparse_rank);
}
BinaryFlatIndex (v0.9.0)
Native binary vector storage with Hamming distance search. 32x memory reduction, sub-microsecond inserts.
use edgevec::BinaryFlatIndex;
// 768-bit binary vectors (96 bytes each)
let mut index = BinaryFlatIndex::new(768)?;
// Insert packed binary vectors
let id = index.insert(&binary_vector)?;
// Hamming distance search
let results = index.search(&query, 10)?;
for r in &results {
println!("ID: {}, distance: {}", r.id, r.distance);
}
Use cases: Semantic caching, large-scale deduplication, insert-heavy workloads (~1us insert vs ~2ms for HNSW).
Rust Usage
use edgevec::{HnswConfig, HnswIndex, VectorStorage};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = HnswConfig::new(768);
let mut storage = VectorStorage::new(&config, None);
let mut index = HnswIndex::new(config, &storage)?;
// Insert
let vector = vec![0.1; 768];
let id = index.insert(&vector, &mut storage)?;
// Search
let query = vec![0.1; 768];
let results = index.search(&query, 10, &storage)?;
// Soft delete
index.soft_delete(id)?;
Ok(())
}
Documentation
Limitations
EdgeVec is designed for client-side vector search. It is NOT suitable for:
- Billion-scale datasets — Browser memory limits apply (~1GB practical limit)
- Multi-user concurrent access — Single-user, single-tab design
- Distributed deployments — Runs locally only
For these use cases, consider Pinecone, Qdrant, or Weaviate.
Version History
- v0.9.0 — Sparse vectors (CSR), hybrid search (RRF + linear fusion), FlatIndex, BinaryFlatIndex (PR #7 by @marlon-costa-dc)
- v0.8.0 — Vue 3 composables, functional filter API, SIMD Euclidean, tech debt reduction
- v0.7.0 — SIMD acceleration (2x+ speedup), First Community Contribution (@jsonMartin — 8.75x Hamming)
- v0.6.0 — Binary quantization (32x memory), metadata storage, memory pressure API
- v0.5.4 — iOS Safari compatibility fixes
- v0.5.3 — crates.io publishing fix (package size reduction)
- v0.5.2 — npm TypeScript compilation fix
- v0.5.0 — Metadata filtering with SQL-like syntax, Filter Playground demo
- v0.4.0 — Documentation sprint, benchmark dashboard, chaos testing
- v0.3.0 — Soft delete API, compaction, persistence format v3
- v0.2.0 — Scalar quantization (SQ8), SIMD optimization
- v0.1.0 — Initial release with HNSW indexing
Contributors
Thank you to everyone who has contributed to EdgeVec!
| Contributor |
Contribution |
| @jsonMartin |
SIMD Hamming distance (PR #4) — 8.75x speedup |
| @marlon-costa-dc |
BinaryFlatIndex + clippy quality fixes (PR #7, PR #8) |
License
Licensed under either of:
at your option.
评论