Ruvector WASM
High-performance vector database running entirely in your browser via WebAssembly.
Bring sub-millisecond vector search to the edge with offline-first capabilities. Perfect for AI applications, semantic search, and recommendation engines that run completely client-side. Built by rUv with Rust and WebAssembly.
π Why Ruvector WASM?
In the age of privacy-first, offline-capable web applications, running AI workloads entirely in the browser is no longer optionalβit's essential.
Ruvector WASM brings enterprise-grade vector search to the browser:
- β‘ Blazing Fast: <1ms query latency with HNSW indexing and SIMD acceleration
- π Privacy First: All data stays in the browserβzero server round-trips
- π΄ Offline Capable: Full functionality without internet via IndexedDB persistence
- π Edge Computing: Deploy to CDNs for ultra-low latency globally
- πΎ Persistent Storage: IndexedDB integration with automatic synchronization
- π§΅ Multi-threaded: Web Workers support for parallel processing
- π¦ Compact: <400KB gzipped with optimizations
- π― Zero Dependencies: Pure Rust compiled to WebAssembly
π Features
Core Capabilities
- Complete VectorDB API: Insert, search, delete, batch operations with familiar patterns
- HNSW Indexing: Hierarchical Navigable Small World for fast approximate nearest neighbor search
- Multiple Distance Metrics: Euclidean, Cosine, Dot Product, Manhattan
- SIMD Acceleration: 2-4x speedup on supported hardware with automatic detection
- Memory Efficient: Optimized memory layouts and zero-copy operations
- Type-Safe: Full TypeScript definitions included
Browser-Specific Features
- IndexedDB Persistence: Save/load database state with progressive loading
- Web Workers Integration: Parallel operations across multiple threads
- Worker Pool Management: Automatic load balancing across 4-8 workers
- Zero-Copy Transfers: Transferable objects for efficient data passing
- Browser Console Debugging: Enhanced error messages and stack traces
- Progressive Web Apps: Perfect for PWA offline scenarios
Performance Optimizations
- Batch Operations: Efficient bulk insert/search for large datasets
- LRU Caching: 1000-entry hot vector cache for frequently accessed data
- Lazy Loading: Progressive data loading with callbacks
- Compressed Storage: Optimized serialization for IndexedDB
- WASM Streaming: Compile WASM modules while downloading
π¦ Installation
NPM
Yarn
CDN (for quick prototyping)
β‘ Quick Start
Basic Usage
import init from '@ruvector/wasm';
// 1. Initialize WASM module (one-time setup)
await ;
// 2. Create database with 384-dimensional vectors
const db = ;
// 3. Insert vectors with metadata
const embedding = .;
const id = db.;
// 4. Search for similar vectors
const query = .;
const results = db.; // top 10 results
// 5. Process results
results.;
React Integration
import { useEffect, useState } from 'react';
import init, { VectorDB } from '@ruvector/wasm';
function SemanticSearch() {
const [db, setDb] = useState<VectorDB | null>(null);
const [results, setResults] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
// Initialize WASM and create database
init().then(() => {
const vectorDB = new VectorDB(384, 'cosine', true);
setDb(vectorDB);
setLoading(false);
});
}, []);
const handleSearch = async (queryEmbedding: Float32Array) => {
if (!db) return;
const searchResults = db.search(queryEmbedding, 10);
setResults(searchResults);
};
if (loading) return <div>Loading vector database...</div>;
return (
<div>
<h1>Semantic Search</h1>
{/* Your search UI */}
</div>
);
}
Vue.js Integration
<template>
<div>
<h1>Vector Search</h1>
<div v-if="!dbReady">Initializing...</div>
<div v-else>
<button @click="search">Search</button>
<ul>
<li v-for="result in results" :key="result.id">
{{ result.id }}: {{ result.score }}
</li>
</ul>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import init, { VectorDB } from '@ruvector/wasm';
const db = ref(null);
const dbReady = ref(false);
const results = ref([]);
onMounted(async () => {
await init();
db.value = new VectorDB(384, 'cosine', true);
dbReady.value = true;
});
const search = () => {
const query = new Float32Array(384).map(() => Math.random());
results.value = db.value.search(query, 10);
};
</script>
Svelte Integration
<script>
import { onMount } from 'svelte';
import init, { VectorDB } from '@ruvector/wasm';
let db = null;
let ready = false;
let results = [];
onMount(async () => {
await init();
db = new VectorDB(384, 'cosine', true);
ready = true;
});
function search() {
const query = new Float32Array(384).map(() => Math.random());
results = db.search(query, 10);
}
</script>
{#if !ready}
<p>Loading...</p>
{:else}
<button on:click={search}>Search</button>
{#each results as result}
<div>{result.id}: {result.score}</div>
{/each}
{/if}
π₯ Advanced Usage
Web Workers for Background Processing
Offload heavy vector operations to background threads for smooth UI performance:
// main.js
import from '@ruvector/wasm/worker-pool';
const pool = ;
// Initialize worker pool
await pool.;
// Batch insert in parallel (non-blocking)
const vectors = ;
const ids = await pool.;
// Parallel search across workers
const query = .;
const results = await pool.;
// Get pool statistics
const stats = pool.;
console.log;
console.log;
// Cleanup when done
pool.;
// worker.js - Web Worker implementation
;
const = wasm_bindgen;
let db = null;
self ;
IndexedDB Persistence - Offline First
Keep your vector database synchronized across sessions:
import from '@ruvector/wasm/indexeddb';
import init from '@ruvector/wasm';
await ;
// Create persistence layer
const persistence = ;
await persistence.;
// Create or restore VectorDB
const db = ;
// Load existing data from IndexedDB (with progress)
await persistence.;
// Insert new vectors and save to IndexedDB
const vector = .;
const id = db.;
await persistence.;
// Batch save for better performance
const entries = ; // Your vector entries
await persistence.;
// Get storage statistics
const stats = await persistence.;
console.log;
console.log;
console.log;
console.log;
// Clear old data
await persistence.;
Batch Operations for Performance
Process large datasets efficiently:
import init from '@ruvector/wasm';
await ;
const db = ;
// Batch insert (10x faster than individual inserts)
const entries = ;
const ids = db.;
console.log;
// Multiple parallel searches
const queries = Array.;
const allResults = queries.;
console.log;
Memory Management Best Practices
import init from '@ruvector/wasm';
await ;
// Reuse Float32Array buffers to reduce GC pressure
const buffer = ;
// Insert with reused buffer
// Check memory usage
const vectorCount = db.;
const isEmpty = db.;
const dimensions = db.;
console.log;
// Clean up when done
// JavaScript GC will handle WASM memory automatically
π Performance Benchmarks
Browser Performance (Chrome 120 on M1 MacBook Pro)
| Operation | Vectors | Dimensions | Standard | SIMD | Speedup |
|---|---|---|---|---|---|
| Insert (individual) | 10,000 | 384 | 3.2s | 1.1s | 2.9x |
| Insert (batch) | 10,000 | 384 | 1.2s | 0.4s | 3.0x |
| Search (k=10) | 100 queries | 384 | 0.5s | 0.2s | 2.5x |
| Search (k=100) | 100 queries | 384 | 1.8s | 0.7s | 2.6x |
| Delete | 1,000 | 384 | 0.2s | 0.1s | 2.0x |
Throughput Comparison
Operation Ruvector WASM Tensorflow.js ml5.js
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Insert (ops/sec) 25,000 5,000 1,200
Search (queries/sec) 500 80 20
Memory (10K vectors) ~50MB ~200MB ~150MB
Bundle Size (gzipped) 380KB 800KB 450KB
Offline Support β
Partial β
SIMD Acceleration β
β β
Real-World Application Performance
Semantic Search (10,000 documents, 384-dim embeddings)
- Cold start: ~800ms (WASM compile + data load)
- Warm query: <5ms (with HNSW index)
- IndexedDB load: ~2s (10,000 vectors)
- Memory footprint: ~60MB
Recommendation Engine (100,000 items, 128-dim embeddings)
- Initial load: ~8s from IndexedDB
- Query latency: <10ms (p50)
- Memory usage: ~180MB
- Bundle impact: +400KB gzipped
π Browser Compatibility
Support Matrix
| Browser | Version | WASM | SIMD | Workers | IndexedDB | Status |
|---|---|---|---|---|---|---|
| Chrome | 91+ | β | β | β | β | Full Support |
| Firefox | 89+ | β | β | β | β | Full Support |
| Safari | 16.4+ | β | Partial | β | β | Limited SIMD |
| Edge | 91+ | β | β | β | β | Full Support |
| Opera | 77+ | β | β | β | β | Full Support |
| Samsung Internet | 15+ | β | β | β | β | No SIMD |
SIMD Support Detection
import from '@ruvector/wasm';
if else
Polyfills and Fallbacks
// Check for required features
const hasWASM = typeof WebAssembly !== 'undefined';
const hasWorkers = typeof Worker !== 'undefined';
const hasIndexedDB = typeof indexedDB !== 'undefined';
if
if
if
π¦ Bundle Size
Production Build Sizes
Build Type Uncompressed Gzipped Brotli
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Standard WASM 1.2 MB 450 KB 380 KB
SIMD WASM 1.3 MB 480 KB 410 KB
JavaScript Glue 45 KB 12 KB 9 KB
TypeScript Definitions 8 KB 2 KB 1.5 KB
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Total (Standard) 1.25 MB 462 KB 390 KB
Total (SIMD) 1.35 MB 492 KB 420 KB
With Optimizations (wasm-opt)
Optimized Build Uncompressed Gzipped Brotli
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Standard WASM 900 KB 380 KB 320 KB
SIMD WASM 980 KB 410 KB 350 KB
Code Splitting Strategy
// Lazy load WASM module when needed
const ;
// Use in your application
button.;
π¨ Building from Source
Prerequisites
- Rust: 1.77 or higher
- wasm-pack: Latest version
- Node.js: 18.0 or higher
# Install wasm-pack
|
# Or via npm
Build Commands
# Clone repository
# Install dependencies
# Build for web (ES modules)
# Build with SIMD optimizations
# Build for Node.js
# Build for bundlers (webpack, rollup, etc.)
# Build all targets
# Run tests in browser
# Run tests in Node.js
# Check bundle size
# Optimize with wasm-opt (requires binaryen)
# Serve examples locally
Development Workflow
# Watch mode (requires custom setup)
# Run specific browser tests
# Profile WASM performance
# Generate documentation
Custom Build Configuration
# .cargo/config.toml
[]
= [
"-C", "opt-level=z",
"-C", "lto=fat",
"-C", "codegen-units=1"
]
π API Reference
VectorDB Class
class VectorDB {
constructor(
dimensions: number,
metric?: 'euclidean' | 'cosine' | 'dotproduct' | 'manhattan',
useHnsw?: boolean
);
// Insert operations
insert(vector: Float32Array, id?: string, metadata?: object): string;
insertBatch(entries: VectorEntry[]): string[];
// Search operations
search(query: Float32Array, k: number, filter?: object): SearchResult[];
// Retrieval operations
get(id: string): VectorEntry | null;
len(): number;
isEmpty(): boolean;
// Delete operations
delete(id: string): boolean;
// Persistence (IndexedDB)
saveToIndexedDB(): Promise<void>;
static loadFromIndexedDB(dbName: string): Promise<VectorDB>;
// Properties
readonly dimensions: number;
}
Types
interface VectorEntry {
id?: string;
vector: Float32Array;
metadata?: Record<string, any>;
}
interface SearchResult {
id: string;
score: number;
vector?: Float32Array;
metadata?: Record<string, any>;
}
Utility Functions
// Detect SIMD support
function detectSIMD(): boolean;
// Get version
function version(): string;
// Array conversion
function arrayToFloat32Array(arr: number[]): Float32Array;
// Benchmarking
function benchmark(name: string, iterations: number, dimensions: number): number;
See WASM API Documentation for complete reference.
π― Example Applications
Semantic Search Engine
// Semantic search with OpenAI embeddings
import init from '@ruvector/wasm';
import from 'openai';
await ;
const openai = ;
const db = ; // OpenAI ada-002 = 1536 dims
// Index documents
const documents = ;
// Search
const queryResponse = await openai.;
const queryEmbedding = ;
const results = db.;
results.;
Offline Recommendation Engine
// Product recommendations that work offline
import init from '@ruvector/wasm';
import from '@ruvector/wasm/indexeddb';
await ;
const db = ;
const persistence = ;
await persistence.;
// Load cached recommendations
await persistence.;
// Get recommendations based on user history
// Add new products (syncs to IndexedDB)
RAG (Retrieval-Augmented Generation)
// Browser-based RAG system
import init from '@ruvector/wasm';
await ;
const db = ; // BERT embeddings
// Index knowledge base
const knowledgeBase = ; // Your documents
// RAG query function
π Troubleshooting
Common Issues
1. WASM Module Not Loading
// Ensure correct MIME type
// Add to server config (nginx):
// types {
// application/wasm wasm;
// }
// Or use explicit fetch
const wasmUrl = ;
await ;
2. CORS Errors
// For local development
// package.json
3. Memory Issues
// Monitor memory usage
const stats = db.;
const estimatedMemory = stats * dimensions * 4; // bytes
if
// Use batch operations to reduce GC pressure
const BATCH_SIZE = 1000;
4. Web Worker Issues
// Ensure worker script URL is correct
const workerUrl = ;
const worker = ;
// Handle worker errors
worker ;
See WASM Troubleshooting Guide for more solutions.
π Links & Resources
Documentation
- Getting Started Guide - Complete setup and usage
- WASM API Reference - Full API documentation
- Performance Tuning - Optimization tips
- Main README - Project overview and features
Examples & Demos
- Vanilla JS Example - Basic implementation
- React Demo - React integration with hooks
- Live Demo - Try it in your browser
- CodeSandbox - Interactive playground
Community & Support
- GitHub: github.com/ruvnet/ruvector
- Discord: Join our community
- Twitter: @ruvnet
- Issues: Report bugs
π License
MIT License - see LICENSE for details.
Free to use for commercial and personal projects.
π Acknowledgments
- Built with wasm-pack and wasm-bindgen
- HNSW algorithm implementation from hnsw_rs
- SIMD optimizations powered by Rust's excellent WebAssembly support
- The WebAssembly community for making this possible
Built by rUv β’ Open Source on GitHub
Perfect for: PWAs β’ Offline-First Apps β’ Edge Computing β’ Privacy-First AI
Get Started β’ API Docs β’ Examples