# How VelesDB WASM Integration Works for Browser-Based Applications

> Discover how VelesDB WASM integration enables browser-based vector search. Explore its Rust core compiled with wasm-bindgen and the TypeScript SDK for efficient client-side operations. Learn more today.

- Repository: [Wiscale/velesdb](https://github.com/cyberlife-coder/velesdb)
- Tags: internals
- Published: 2026-02-28

---

**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`](https://github.com/cyberlife-coder/velesdb/blob/main/crates/velesdb-wasm/src/lib.rs) |
| **JavaScript Glue** | Dynamic module loading and `VectorStore` class re-export | [`sdks/typescript/src/backends/wasm.ts`](https://github.com/cyberlife-coder/velesdb/blob/main/sdks/typescript/src/backends/wasm.ts) |
| **Demo & SDK** | HTML examples and TypeScript wrappers for CDN distribution | [`examples/wasm-browser-demo/README.md`](https://github.com/cyberlife-coder/velesdb/blob/main/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`](https://github.com/cyberlife-coder/velesdb/blob/main/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.

```html
<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`](https://github.com/cyberlife-coder/velesdb/blob/main/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`](https://github.com/cyberlife-coder/velesdb/blob/main/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`](https://github.com/cyberlife-coder/velesdb/blob/main/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`](https://github.com/cyberlife-coder/velesdb/blob/main/wasm.ts)):

1. Calls `WasmBackend.init()` to trigger the dynamic import
2. Resolves the `@wiscale/velesdb-wasm` npm package
3. Executes the default export to run the `wasm-bindgen` generated `init()` function
4. 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.

```ts
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`](https://github.com/cyberlife-coder/velesdb/blob/main/lib.rs) lines 77-95 and implemented in [`persistence.rs`](https://github.com/cyberlife-coder/velesdb/blob/main/persistence.rs)) serialize the vector data to browser storage.

```ts
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 web` and `--enable-simd` flags to ensure distance calculations leverage browser SIMD support
- **Batch Insertion**: The `insert_batch` method reduces JavaScript-to-WebAssembly context switching overhead compared to individual inserts
- **Tree-Shaking**: Importing only the `VectorStore` class keeps the gzipped bundle under 200KB, as documented in [`docs/wasm/bundle-optimization.md`](https://github.com/cyberlife-coder/velesdb/blob/main/docs/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 the `VectorStore` class directly to browser JavaScript.
- The TypeScript SDK dynamically loads the `@wiscale/velesdb-wasm` package and routes all CRUD and search operations through the Rust-backed `VectorStore`.
- Client-side persistence uses IndexedDB through the `save()` and `load()` methods implemented in [`persistence.rs`](https://github.com/cyberlife-coder/velesdb/blob/main/persistence.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`](https://github.com/cyberlife-coder/velesdb/blob/main/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`](https://github.com/cyberlife-coder/velesdb/blob/main/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.