matte1782
edgevec
Rust

High-performance vector search for Browser, Node, and Edge

Last updated Aug 3, 2026
96
Stars
6
Forks
2
Issues
0
Stars/day
Attention Score
30
Language breakdown
Rust 69.5%
HTML 12.1%
JavaScript 8.8%
TypeScript 6.3%
CSS 2.0%
Python 1.0%
โ–ธ Files click to expand
README

EdgeVec

CI Crates.io npm License

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.

,ignore
use edgevec::filter::{MetadataBoost, FilteredSearcher, FilterStrategy};
use edgevec::metadata::MetadataValue;

let boosts = vec![ MetadataBoost::new("entitytype".tostring(), 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) |

Full benchmark report ->


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.

,ignore
use edgevec::{FlatIndex, FlatIndexConfig, DistanceMetric};

let config = FlatIndexConfig::new(768) .with_metric(DistanceMetric::Cosine) .withcapacity(10000); 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.

,ignore
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.

,ignore
use edgevec::hybrid::{HybridSearcher, HybridSearchConfig, FusionMethod};

// Set up: HNSW index + sparse storage already populated let searcher = HybridSearcher::new(&hnswindex, &densestorage, &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(&densequery, &sparsequery, &config)?; for r in &results { println!("ID: {}, score: {:.4}, denserank: {:?}, sparserank: {:?}", r.id, r.score, r.denserank, r.sparserank); }

BinaryFlatIndex (v0.9.0)

Native binary vector storage with Hamming distance search. 32x memory reduction, sub-microsecond inserts.

,ignore
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

| Document | Description | |:---------|:------------| | Tutorial | Getting started guide | | Filter Syntax | Complete filter expression reference | | Database Operations | CRUD operations guide | | FlatIndex API | FlatIndex reference | | Sparse Vectors | Sparse vector storage and search | | Hybrid Search | Dense + sparse fusion guide | | BinaryFlatIndex | Binary vector index reference | | Performance Tuning | HNSW parameter optimization | | Migration Guide | Migrating from hnswlib, FAISS, Pinecone | | Comparison | When to use EdgeVec vs alternatives |


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.

Built with Rust + WebAssembly

GitHub | npm | crates.io | Demos

๐Ÿ”— More in this category

ยฉ 2026 GitRepoTrend ยท matte1782/edgevec ยท Updated daily from GitHub