Examples
Real-world usage patterns for the JavaScript / TypeScript SDK.
RAG (Retrieval-Augmented Generation)
Use LocalVectorDB as the retrieval layer for a RAG pipeline:
import { LocalVectorDBClient } from "@localvectordb/sdk";
import Anthropic from "@anthropic-ai/sdk";
const lvdb = new LocalVectorDBClient({ baseUrl: "http://localhost:8000" });
const db = lvdb.database("knowledge_base");
const anthropic = new Anthropic();
async function askQuestion(question: string): Promise<string> {
// 1. Retrieve relevant documents
const { results } = await db.query(question, {
search_type: "hybrid",
k: 5,
score_threshold: 0.3,
});
// 2. Build context from results
const context = results
.map((r) => `[${r.id}] (score: ${r.score.toFixed(2)})\n${r.content}`)
.join("\n\n---\n\n");
// 3. Generate answer with context
const response = await anthropic.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
messages: [
{
role: "user",
content: `Based on the following documents, answer the question.
Documents:
${context}
Question: ${question}`,
},
],
});
return response.content[0].type === "text" ? response.content[0].text : "";
}
Document Ingestion Pipeline
Ingest files from a directory with metadata:
import { readFile, readdir, stat } from "fs/promises";
import { join, extname, basename } from "path";
import { LocalVectorDBClient } from "@localvectordb/sdk";
const client = new LocalVectorDBClient({ baseUrl: "http://localhost:8000" });
const db = client.database("documents");
async function ingestDirectory(dirPath: string): Promise<void> {
const entries = await readdir(dirPath);
for (const entry of entries) {
const filePath = join(dirPath, entry);
const fileStat = await stat(filePath);
if (!fileStat.isFile()) continue;
const ext = extname(entry).toLowerCase();
if (![".pdf", ".docx", ".txt", ".md"].includes(ext)) continue;
const data = await readFile(filePath);
await db.upload(
[{ name: entry, data, type: mimeType(ext) }],
{
metadata: {
source: dirPath,
filename: entry,
size_bytes: fileStat.size,
ingested_at: new Date().toISOString(),
},
use_filename_as_id: true,
}
);
console.log(`Ingested: ${entry}`);
}
}
function mimeType(ext: string): string {
const types: Record<string, string> = {
".pdf": "application/pdf",
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
".txt": "text/plain",
".md": "text/markdown",
};
return types[ext] ?? "application/octet-stream";
}
Express.js Search API
Expose LocalVectorDB search through an Express API:
import express from "express";
import { LocalVectorDBClient, DatabaseNotFoundError } from "@localvectordb/sdk";
const app = express();
app.use(express.json());
const lvdb = new LocalVectorDBClient({
baseUrl: process.env.LVDB_URL ?? "http://localhost:8000",
apiKey: process.env.LVDB_API_KEY,
});
app.get("/api/search/:database", async (req, res) => {
try {
const db = lvdb.database(req.params.database);
const { q, k = "10", type = "hybrid" } = req.query as Record<string, string>;
if (!q) {
return res.status(400).json({ error: "Missing query parameter 'q'" });
}
const results = await db.query(q, {
search_type: type as "vector" | "keyword" | "hybrid",
k: parseInt(k, 10),
});
return res.json({
query: q,
total: results.total_results,
results: results.results.map((r) => ({
id: r.id,
score: r.score,
content: r.content,
metadata: r.metadata,
})),
});
} catch (err) {
if (err instanceof DatabaseNotFoundError) {
return res.status(404).json({ error: `Database '${req.params.database}' not found` });
}
throw err;
}
});
app.listen(3000, () => console.log("API server running on :3000"));
Browser Search Widget
A minimal HTML search widget using the SDK via a bundler:
<div id="search">
<input type="text" id="query" placeholder="Search documents..." />
<button id="btn">Search</button>
<ul id="results"></ul>
</div>
<script type="module">
import { LocalVectorDBClient } from "@localvectordb/sdk";
const client = new LocalVectorDBClient({
baseUrl: "http://localhost:8000",
});
const db = client.database("my_docs");
document.getElementById("btn").addEventListener("click", async () => {
const query = document.getElementById("query").value;
const ul = document.getElementById("results");
ul.innerHTML = "<li>Searching...</li>";
try {
const { results } = await db.query(query, {
search_type: "hybrid",
k: 10,
});
ul.innerHTML = results
.map(
(r) =>
`<li><strong>${r.score.toFixed(2)}</strong> — ${r.content.slice(0, 120)}...</li>`
)
.join("");
} catch (err) {
ul.innerHTML = `<li style="color:red">Error: ${err.message}</li>`;
}
});
</script>
Multi-Database Comparison
Compare documents across databases:
const client = new LocalVectorDBClient({ baseUrl: "http://localhost:8000" });
// Search across all databases
const global = await client.globalSearch("climate change impacts", {
search_type: "hybrid",
k: 5,
});
for (const [dbName, hits] of Object.entries(global.results)) {
console.log(`\n=== ${dbName} ===`);
for (const hit of hits) {
console.log(` [${hit.score.toFixed(3)}] ${hit.content.slice(0, 100)}`);
}
}
Streaming Progress
Show a progress indicator while streaming results:
const db = client.database("large_corpus");
let count = 0;
const results = [];
for await (const result of db.queryStream("complex query", { k: 200 })) {
results.push(result);
count++;
process.stdout.write(`\rReceived ${count} results...`);
}
console.log(`\nDone! ${results.length} total results.`);