How VelesDB WASM Integration Works for Browser-Based Applications
VelesDB delivers browser-based vector search through a wasm-bindgen compiled Rust core, wrapped by a TypeScript SDK that dynamically loads the module and exposes the VectorStore class for client-side CRUD and similarity search operations.
The cyberlife-coder/velesdb repository ships a dedicated WebAssembly build via the velesdb-wasm crate, enabling the core vector-store engine to run entirely within browsers or Node.js. This integration eliminates server dependencies by compiling the Rust search algorithms to WASM and exposing them through idiomatic JavaScript APIs.
Architecture of the WASM Integration
The system operates through three tightly-coupled layers that bridge Rust and JavaScript:
| Layer | Purpose | Key File |
|---|---|---|
| WASM Binary | Compiled Rust code exposing vector operations via wasm-bindgen |
crates/velesdb-wasm/src/lib.rs |
| JavaScript Glue | Dynamic module loading and VectorStore class re-export |
sdks/typescript/src/backends/wasm.ts |
| Demo & SDK | HTML examples and TypeScript wrappers for CDN distribution | examples/wasm-browser-demo/README.md |
Loading the WASM Module in the Browser
Browser applications load the compiled binary directly from npm CDNs. The entry point calls init(), which resolves the velesdb_wasm_bg.wasm file, allocates linear memory, and registers exported Rust functions as JavaScript methods.
In crates/velesdb-wasm/src/lib.rs, the #[wasm_bindgen(start)] attribute marks the init function as the module entry point. When invoked, it instantiates the WASM blob and prepares the runtime for VectorStore operations.
<script type="module">
// Pull the module from a CDN (unpkg or jsdelivr)
import init, { VectorStore } from
'https://unpkg.com/velesdb-wasm@latest/velesdb_wasm.js';
// Initialise the Wasm runtime
await init();
// Use the exported class
const store = new VectorStore(768, 'cosine');
</script>
The TypeScript SDK mirrors this flow in sdks/typescript/src/backends/wasm.ts by performing a dynamic import('@wiscale/velesdb-wasm') when a VelesDB instance is created with backend: 'wasm'.
The VectorStore Core Implementation
The Rust side defines the VectorStore struct (lines 97-129 of lib.rs) to store vectors in a contiguous Vec<f32> buffer for the default Full mode, while also supporting compressed SQ8 and Binary modes to reduce memory footprint.
Key methods exposed to JavaScript via #[wasm_bindgen] include:
| Method | Description |
|---|---|
new(dimension, metric) |
Creates an empty store with specified distance metric |
insert(id, vector) |
Adds a single vector using u64/BigInt IDs |
insert_batch(batch) |
Fast bulk insertion to minimize JS-to-WASM call overhead |
search(query, k) |
Returns the k nearest neighbours with IDs and scores |
search_with_filter(query, k, filter) |
Applies JSON payload filtering during the search |
text_search(query, k, field?) |
Substring search across payload fields |
save(db_name) / load(db_name) |
Persists to IndexedDB via persistence.rs (lines 77-95) |
export_to_bytes() / import_from_bytes() |
Serializes the store for manual storage in localStorage |
These methods are thin wrappers around internal Rust modules such as store_insert, store_search, and serialization within the impl VectorStore block.
TypeScript SDK Backend Integration
When an application initializes the SDK with backend: 'wasm', the WasmBackend class orchestrates the loading sequence (lines 57-61 of wasm.ts):
- Calls
WasmBackend.init()to trigger the dynamic import - Resolves the
@wiscale/velesdb-wasmnpm package - Executes the default export to run the
wasm-bindgengeneratedinit()function - Stores the module reference and initializes the backend flag
All subsequent operations (createCollection, insert, search) delegate to the VectorStore instance held in the collections map (see createCollection at lines 80-96). The SDK handles ID conversion between numeric Rust IDs and string JavaScript IDs while maintaining payload bookkeeping.
import { VelesDB } from '@wiscale/velesdb';
async function run() {
const db = new VelesDB({ backend: 'wasm' });
await db.init(); // loads the WASM module
await db.createCollection('docs', { dimension: 256 });
// Insert with payload
await db.insert('docs', {
id: 'doc-1',
vector: new Float32Array(256).map(() => Math.random()),
payload: { title: 'Hello', tags: ['demo'] },
});
// Vector search
const results = await db.search('docs', new Float32Array(256).map(() => Math.random()), { k: 5 });
console.log(results);
}
run();
Client-Side Persistence with IndexedDB
The WASM store runs entirely in memory, but the crate ships IndexedDB helpers for offline-first applications. The save and load methods (exposed via #[wasm_bindgen] in lib.rs lines 77-95 and implemented in persistence.rs) serialize the vector data to browser storage.
import { VelesDB } from '@wiscale/velesdb';
async function demoPersist() {
const db = new VelesDB({ backend: 'wasm' });
await db.init();
await db.createCollection('mem', { dimension: 64 });
// ... insert data ...
// Persist to IndexedDB
const collection = await db.getCollection('mem');
await collection?.backend?.save('my-vectors-db');
// Restore in a later session
const restored = await VectorStore.load('my-vectors-db');
}
This enables Progressive Web Apps to cache semantic-search indexes on first load and run vector queries without network connectivity.
Performance and Bundle Optimization
The velesdb-wasm crate optimizes for browser constraints through several mechanisms:
- SIMD Vectorization: Built with
wasm-pack --target weband--enable-simdflags to ensure distance calculations leverage browser SIMD support - Batch Insertion: The
insert_batchmethod reduces JavaScript-to-WebAssembly context switching overhead compared to individual inserts - Tree-Shaking: Importing only the
VectorStoreclass keeps the gzipped bundle under 200KB, as documented indocs/wasm/bundle-optimization.md - Lazy Loading: The TypeScript SDK dynamically imports the WASM module only when
backend: 'wasm'is specified, preventing unnecessary payload costs for REST-only applications
Summary
- VelesDB compiles its core Rust vector engine to WebAssembly via
wasm-bindgen, exposing theVectorStoreclass directly to browser JavaScript. - The TypeScript SDK dynamically loads the
@wiscale/velesdb-wasmpackage and routes all CRUD and search operations through the Rust-backedVectorStore. - Client-side persistence uses IndexedDB through the
save()andload()methods implemented inpersistence.rs, supporting offline-first use cases. - SIMD instructions and batch insertion APIs maximize query performance while keeping the bundle size below 200KB gzipped.
Frequently Asked Questions
Which browsers support VelesDB's WASM integration?
VelesDB requires a WebAssembly runtime with SIMD support for optimal performance, which is available in all modern browsers including Chrome, Firefox, Safari, and Edge. The build process uses wasm-pack --target web with --enable-simd to ensure vectorized distance calculations function correctly across supported environments.
How large is the WASM bundle for production deployment?
The gzipped bundle size remains under 200KB when tree-shaking is applied to import only the VectorStore class. The documentation in docs/wasm/bundle-optimization.md provides specific guidelines for minimizing payload size through compression mode selection and lazy loading patterns.
Can VelesDB WASM persist data between browser sessions?
Yes, the VectorStore class provides save(db_name) and load(db_name) methods that serialize the entire store to IndexedDB. This persistence layer is implemented in crates/velesdb-wasm/src/persistence.rs and exposed via #[wasm_bindgen], allowing applications to maintain semantic search indexes offline between sessions.
What is the difference between the WASM backend and the REST backend?
The WASM backend (backend: 'wasm') executes vector search entirely within browser memory using the compiled Rust core, while the REST backend communicates with a remote VelesDB server. The WASM approach eliminates network latency and enables offline operation but is constrained by browser memory limits, whereas the REST backend handles larger datasets server-side with persistent storage.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →