Architecture¶
This page describes the storage, search, embedding, and SDK layers of Vecnest.
Overview¶
Vecnest is a browser-based vector database. Vectors are stored in IndexedDB and queried via cosine similarity. HNSW (Hierarchical Navigable Small World) indexing provides approximate nearest neighbor search; a brute-force path is used when HNSW is unavailable or disabled.
Core components¶
Vecnest
├── Storage Layer (IndexedDB)
├── Search Layer (HNSW + brute-force fallback + Web Workers)
├── Embedding Layer (Transformers.js / optional)
└── SDK (JS API + React hooks)
1. Storage layer (IndexedDB)¶
- Database name: Configurable (default
vecnest). Set viaVecnestDBconstructor oropenDB(name). - Object store:
vectors; keyPathid(auto-increment). - Record shape:
{ id, vector: number[], metadata: object, created: number }. - Indexes:
createdfor ordering (e.g. list newest first). - HNSW index store:
hnsw_indexstores serialized HNSW graph data per dimension. - Persistence: Same-origin IndexedDB. Data survives reloads; cleared when the user clears site data.
Vectors store (conceptual)¶
erDiagram
vectors {
int id PK
string vector
string metadata
int created
}
(In practice, vector is stored as a number[] and metadata as a plain object; the schema indicates logical types.)
2. Search layer¶
- HNSW (primary): Approximate nearest neighbor via hnswlib-wasm (WebAssembly). O(log n) query time. Used when the index exists and is valid.
- Brute-force (fallback): Full cosine-similarity scan over all vectors when HNSW is unavailable or disabled. O(n).
- Web Workers: Brute-force search can run in a background thread (
useWorker: true) to keep the UI responsive. - Metadata filtering: Filters applied after retrieval using operators
$eq,$ne,$gt,$gte,$lt,$lte,$in,$nin. See Metadata filtering. - Index rebuilding: HNSW is rebuilt asynchronously after updates and deletes. You can also call
rebuildIndexmanually.
3. Embedding layer (Transformers.js)¶
- Library: @huggingface/transformers (Transformers.js).
- Usage: Optional. Use
addText/searchTextfor built-in embeddings, or supply your own vectors viainsertandsearch. - Model: Default is typically
Xenova/all-MiniLM-L6-v2(384 dimensions). Fetched on first use and cached. - Runtime: WebAssembly in the browser; no server required.
4. SDK design¶
Low-level (core) API¶
openDB,insert,insertBatch,search,update,remove,count,list,getStorageEstimate,cosineSimilarity,embed,embedBatch,rebuildHnswIndex.- Use when you need direct control over transactions or storage.
High-level API (VecnestDB)¶
- Wraps the core API:
connect,insert,addText,addTexts,search,searchText,update,delete,count,list,rebuildIndex,close. addText/addTexts: embed via Transformers.js, then insert (HNSW updated).searchText: embed query, thensearch.- React hooks:
useVecnest,useSearch,useSearchTextinvecnest/react.
Data flow¶
flowchart LR
subgraph Input
Text[Text]
Vectors[Vectors]
end
subgraph Embedding
HF[Transformers.js]
end
subgraph Store
IDB[(IndexedDB)]
end
subgraph Search
Cos[Cosine Similarity]
HNSW[HNSW]
end
Text --> HF
HF --> Vectors
Vectors --> IDB
IDB --> Cos
Cos --> HNSW
HNSW --> Results[Results]
Technology stack¶
| Layer | Choice | Notes |
|---|---|---|
| Storage | IndexedDB | Persistent; large per-origin quotas |
| Embeddings | Transformers.js | WASM; local; optional |
| Search | HNSW (WASM) | hnswlib-wasm for approximate NN |
| Workers | Web Workers | Background brute-force when needed |
| SDK | JS (ESM) | React hooks optional |
| Build | Vite | Examples and tooling |