Sign In

@monlite/vector

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@monlite/vector

Local vector / semantic search for @monlite/core, powered by sqlite-vec. Adds collection.findSimilar().

Source
npmnpm
Version
0.5.5
Version published
Weekly downloads
54
38.46%
Maintainers
1
Weekly downloads
 
Created
Source

@monlite/vector

Local vector / semantic search for @monlite/core, powered by sqlite-vec. Adds collection.findSimilar() — RAG and AI-agent memory, all in your local .db.

A monlite plugin. Store documents with an embedding field, and search by nearest neighbour. The index is maintained automatically on every write, including changes applied by @monlite/sync.

import { createDb } from "@monlite/core";
import { vector } from "@monlite/vector";

const db = createDb("./app.db", {
  allowExtensions: true, // required: loads the sqlite-vec extension
  plugins: [vector({ docs: { field: "embedding", dimensions: 384 } })],
});

await db.collection("docs").create({
  data: { title: "Black holes", embedding: await embed("Black holes …") },
});

const hits = await db.collection("docs").findSimilar({
  vector: await embed("astrophysics"),
  topK: 5,
  where: { published: true }, // optional structured filter
});
// [ { _id, title, _distance, … } ]  — nearest first

You bring the embeddings (from any model — OpenAI, local, etc.); monlite stores and searches them.

Install

npm install @monlite/core @monlite/vector

@monlite/vector depends on sqlite-vec, which ships prebuilt native binaries. It works on both monlite backends (better-sqlite3 and node:sqlite), but the database must be opened with { allowExtensions: true }.

API

Plugin

vector(spec: Record<string, {
  field: string;               // document field holding the embedding (number[])
  dimensions: number;          // must match your embedding model's output size
  distance?: "l2" | "cosine"; // default "l2"
}>): MonlitePlugin

findSimilar

collection.findSimilar({
  vector: number[],         // query embedding (length must equal dimensions)
  topK?: number,            // number of results (default 10)
  where?: WhereInput<T>,    // combine with a normal monlite filter
}): Promise<Array<WithId<T> & { _distance: number }>>

Results are ordered nearest-first; _distance is the raw metric (smaller = closer). Documents without a valid embedding field are not indexed.

Reindex

import { reindex } from "@monlite/vector";
reindex(db, "docs", { field: "embedding", dimensions: 384 });

Dynamic store — createVectorStore(db)

The vector() plugin attaches semantic search to a collection with a static spec. For a programmatic store over collections created at runtime — RAG corpora, per-tenant indexes, "give me a vector table for this id" — use createVectorStore(db):

import { createDb } from "@monlite/core";
import { createVectorStore } from "@monlite/vector";

const db = createDb("./rag.db", { allowExtensions: true });
const store = createVectorStore(db);

store.ensureCollection("docs", { dimensions: 384, indexedFields: ["docId"] });
store.upsert("docs", [{ id: "c1", vector: emb, metadata: { docId: "d1", text } }]);

// where on an indexed field is applied inside the KNN — exact pre-filtered recall
store.search("docs", { vector: q, topK: 5, where: { docId: "d1" } });
store.delete("docs", { where: { docId: "d1" } });

Synchronous (raw SQLite). Each collection maps to its own vec0 table; indexedFields become filterable metadata columns, and the rest of metadata rides in a +payload column. Scales well to ~1M vectors locally; beyond that use a dedicated vector database.

How it works

For each configured collection, the plugin creates a sqlite-vec vec0 virtual table keyed by the document _id, backfills existing documents on init, and keeps the index current via the plugin afterWrite hook. findSimilar runs a KNN query and returns the live documents in distance order.

Multi-process ingest

afterWrite only sees writes from its own connection. If a separate process ingests vectors (the common agent pattern), call collection.catchUp() in the searching process to incrementally index new vectors and reconcile cross-process deletes before querying — no full reindex needed:

db.collection("memories").catchUp(); // → { indexed, removed }; call periodically
await db.collection("memories").findSimilar({ vector, topK: 5 });

Combine keyword (FTS) and semantic (vector) results for the best retrieval quality. hybridSearch runs both and fuses the rankings with Reciprocal Rank Fusion — no score normalization needed.

import { createDb } from "@monlite/core";
import { fts } from "@monlite/fts";
import { vector, hybridSearch } from "@monlite/vector";

const db = createDb("./app.db", {
  allowExtensions: true,
  plugins: [
    fts({ docs: ["title", "body"] }),
    vector({ docs: { field: "embedding", dimensions: 384 } }),
  ],
});

const hits = await hybridSearch(db.collection("docs"), {
  text: "black holes",              // keyword arm (FTS)
  vector: await embed("black holes"), // semantic arm (vector)
  topK: 10,
  where: { published: true },       // applied to both arms
});
// [ { _id, title, …, _rrf } ]  — fused, best first

If @monlite/fts is not configured on the collection, it falls back to vector-only.

License

MIT

Keywords

monlite

FAQs

Package last updated on 28 Jun 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts