Getting Started
Install Vectra and run your first queries in minutes.
Table of contents
Requirements
- Node.js 22.x or newer (for the TypeScript library and CLI)
- A package manager (npm or yarn)
- An embeddings provider for similarity search (pick one):
- OpenAI (API key + model, e.g.,
text-embedding-3-large) - Azure OpenAI (endpoint, deployment name, API key)
- OpenAI-compatible OSS endpoint (model name + base URL)
- Local embeddings — no API key needed (install optional
@huggingface/transformerspackage)
- OpenAI (API key + model, e.g.,
- Sufficient RAM to hold your index in memory during queries (see Performance and limits)
Vectra also runs in browsers and Electron. Import from vectra/browser for a bundle that excludes Node-specific modules. See the Storage guide for browser setup.
Install
# npm
npm install vectra
# yarn
yarn add vectra
Optional dependencies:
# For local embeddings (no API key needed)
npm install @huggingface/transformers
# For Protocol Buffer storage format
npm install protobufjs
For CLI usage without a global install:
npx vectra --help
Or install globally:
npm install -g vectra
vectra --help
Quick Start
Vectra offers two paths depending on your use case:
| Path | You bring | Vectra handles |
|---|---|---|
| A — LocalIndex | Vectors + metadata | Storage, filtering, similarity search |
| B — LocalDocumentIndex | Raw text (strings, files, URLs) | Chunking, embedding, retrieval |
Path A: LocalIndex (items + metadata)
Use LocalIndex when you already have vectors (or can generate them) and want to store items with metadata.
import path from 'node:path';
import { LocalIndex } from 'vectra';
import { OpenAI } from 'openai';
// 1) Create an index folder
const index = new LocalIndex(path.join(process.cwd(), 'my-index'));
// 2) Create the index (set which metadata fields you want searchable)
if (!(await index.isIndexCreated())) {
await index.createIndex({
version: 1,
metadata_config: { indexed: ['category'] },
});
}
// 3) Prepare an embeddings helper
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY! });
async function getVector(text: string): Promise<number[]> {
const resp = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: text,
});
return resp.data[0].embedding;
}
// 4) Insert items
await index.insertItem({
vector: await getVector('apple'),
metadata: { text: 'apple', category: 'food', note: 'stored on disk if not indexed' },
});
await index.insertItem({
vector: await getVector('blue'),
metadata: { text: 'blue', category: 'color' },
});
// 5) Query by vector, optionally filter by metadata
const v = await getVector('banana');
const results = await index.queryItems(v, '', 3, { category: { $eq: 'food' } });
for (const r of results) {
console.log(r.score.toFixed(4), r.item.metadata.text);
}
Only fields listed in metadata_config.indexed are stored inline and available for filtering. Everything else is kept in per-item JSON files on disk.
Path B: LocalDocumentIndex (documents + chunking + retrieval)
Use LocalDocumentIndex when you have raw text and want Vectra to handle chunking, embedding, and retrieval.
import path from 'node:path';
import { LocalDocumentIndex, OpenAIEmbeddings } from 'vectra';
// 1) Configure embeddings
const embeddings = new OpenAIEmbeddings({
apiKey: process.env.OPENAI_API_KEY!,
model: 'text-embedding-3-small',
maxTokens: 8000,
});
// 2) Create the index
const docs = new LocalDocumentIndex({
folderPath: path.join(process.cwd(), 'my-doc-index'),
embeddings,
});
if (!(await docs.isIndexCreated())) {
await docs.createIndex({ version: 1 });
}
// 3) Add a document
await docs.upsertDocument('doc://welcome', `
Vectra is a local, file-backed, in-memory vector database.
It supports Pinecone-like metadata filtering and fast local retrieval.
`, 'md');
// 4) Query and render sections for your prompt
const results = await docs.queryDocuments('What is Vectra best suited for?', {
maxDocuments: 5,
maxChunks: 20,
});
if (results.length > 0) {
const top = results[0];
console.log('URI:', top.uri, 'score:', top.score.toFixed(4));
const sections = await top.renderSections(2000, 1, true);
for (const s of sections) {
console.log('Section score:', s.score.toFixed(4), 'tokens:', s.tokenCount);
console.log(s.text);
}
}
Set isBm25: true in queryDocuments options to enable hybrid retrieval — blending keyword matches alongside semantic results.
Next steps
- Core Concepts — understand index types, metadata filtering, and on-disk layout
- Embeddings Guide — choose and configure an embeddings provider
- Document Indexing — deep dive on chunking, retrieval, hybrid search, and FolderWatcher
- CLI Reference — manage indexes from the command line
- API Reference — TypeScript API overview
- Storage — pluggable storage backends, browser support, and custom implementations
- gRPC Server — cross-language access via gRPC
- Best Practices — performance tuning and troubleshooting
- Tutorials — end-to-end walkthroughs: RAG pipeline, browser app, gRPC, custom storage, folder sync