Vectra

raw JSON →
0.14.0 verified Thu Apr 23 auth: no javascript

Vectra is a lightweight, local, file-backed, in-memory vector database designed for Node.js (v22.x+) and browser environments. Currently at version 0.14.0, it follows an active release cadence, introducing significant features and occasional breaking changes. Its key differentiators include operating entirely locally with a file-system backend (each index corresponds to a folder on disk), offering Pinecone-compatible metadata filtering, and integrating hybrid BM25 keyword search for advanced Retrieval-Augmented Generation (RAG) pipelines. The package also provides an optional gRPC server for cross-language access, comprehensive browser and Electron support via a dedicated `vectra/browser` entry point, and the capability to use local embeddings with HuggingFace models without requiring external API keys. Data storage can be optimized using Protocol Buffers for more compact files.

error Error: Minimum Node.js version is 22.x
cause Running Vectra with an outdated Node.js version, typically 20.x or earlier, after upgrading Vectra to v0.14.0 or later.
fix
Upgrade your Node.js environment to version 22.x or higher. For example, using nvm: nvm install 22 && nvm use 22.
error TypeError: LocalDocumentIndex is not a constructor
cause Attempting to import `LocalDocumentIndex` (or other named exports) using CommonJS `require()` syntax without destructuring, or in an environment that expects ESM.
fix
Use ES module import syntax: import { LocalDocumentIndex } from 'vectra';. If strictly using CommonJS, ensure proper destructuring: const { LocalDocumentIndex } = require('vectra');.
error Error: OpenAI API key is missing. Please set the OPENAI_API_KEY environment variable.
cause The `apiKey` option for `OpenAIEmbeddings` was not provided or the `OPENAI_API_KEY` environment variable was not set.
fix
Ensure process.env.OPENAI_API_KEY is set in your environment, or pass the API key directly in the OpenAIEmbeddings constructor: new OpenAIEmbeddings({ apiKey: 'your-api-key' }).
error TypeError: fetch is not a function
cause Occurs in older Node.js versions (pre-18) where `fetch` is not global, or if a browser environment is misconfigured to use a Node.js-specific polyfill that conflicts, or when an embedding provider expected `axios` but now uses `fetch`.
fix
Ensure you are using Node.js v22.x or higher (due to Vectra's requirements) which has fetch built-in. If you encounter this in a very specific environment, consider explicitly polyfilling fetch if Node.js v22.x is not an option (though it's required by Vectra v0.14+).
breaking Vectra `v0.14.0` removed `axios` in favor of the built-in `fetch()` API for all HTTP requests. Projects that relied on `axios` interceptors or custom `axios` configurations must now migrate to using the `requestConfig` option (which accepts a standard `RequestInit` object) when configuring `OpenAIEmbeddings` or other HTTP-based embedding providers.
fix Replace `axios`-specific configurations with `requestConfig` (a `RequestInit` object) on embedding provider options, e.g., `new OpenAIEmbeddings({ ..., requestConfig: { headers: { 'Authorization': 'Bearer ...' } } })`.
breaking As of `v0.14.0`, the minimum required Node.js version is 22.x (previously 20.x). This change is primarily driven by updated dependencies, specifically `undici@8.0.0`, which mandates `node >=22.19.0`.
fix Ensure your development and deployment environments are running Node.js 22.x or later. Use a Node Version Manager (e.g., `nvm`) to update: `nvm install 22 && nvm use 22`.
gotcha When initializing a new `LocalDocumentIndex`, it must be explicitly created using `await docs.createIndex()` if it does not already exist. Failing to do so will result in runtime errors when attempting to upsert or query documents.
fix Always check for index existence with `await docs.isIndexCreated()` and conditionally call `await docs.createIndex({ version: 1 })` before interacting with the index, especially in application startup logic.
gotcha For browser-based applications, the `vectra/browser` entry point must be used. Attempting to import from the main `vectra` package will likely result in Node.js-specific dependencies failing or not being properly bundled.
fix Change your imports from `import { Symbol } from 'vectra';` to `import { Symbol } from 'vectra/browser';` when targeting browser or Electron environments.
npm install vectra
yarn add vectra
pnpm add vectra

This quickstart demonstrates how to initialize a `LocalDocumentIndex`, ensure its creation, upsert a document, and perform a semantic search using OpenAI embeddings in Node.js. It includes necessary environment variable checks for API keys.

import { LocalDocumentIndex, OpenAIEmbeddings } from 'vectra';
import { createHash } from 'crypto';

// Ensure you have your OpenAI API key set in environment variables
const OPENAI_API_KEY = process.env.OPENAI_API_KEY ?? '';
if (!OPENAI_API_KEY) {
  console.error('OPENAI_API_KEY environment variable is not set.');
  process.exit(1);
}

async function runVectorSearch() {
  const docs = new LocalDocumentIndex({
    folderPath: './my-vectra-index',
    embeddings: new OpenAIEmbeddings({
      apiKey: OPENAI_API_KEY,
      model: 'text-embedding-3-small',
      maxTokens: 8000
    })
  });

  // Check if the index exists, create it if not
  if (!(await docs.isIndexCreated())) {
    await docs.createIndex({ version: 1 });
    console.log('New vector index created.');
  }

  // Generate a unique ID for the document
  const docContent = 'Vectra is a local, file-backed, in-memory vector database with optional gRPC.';
  const docId = `doc://${createHash('sha256').update(docContent).digest('hex')}`;

  // Upsert a document into the index
  await docs.upsertDocument(docId, docContent, 'txt');
  console.log(`Document '${docId}' upserted.`);

  // Query the index
  const results = await docs.queryDocuments('What is Vectra?', { maxDocuments: 2 });

  if (results.length > 0) {
    console.log('Query Results:');
    for (const result of results) {
      console.log(`  Document: ${result.documentId}, Score: ${result.score}`);
      const sections = await result.renderSections(2000, 1, true);
      if (sections.length > 0) {
        console.log(`    Content: ${sections[0].text.substring(0, 100)}...`);
      }
    }
  } else {
    console.log('No results found.');
  }
}

runVectorSearch().catch(console.error);