Skip to main content
Chroma is an open-source AI-native embedding database designed to make it easy to build AI applications with embeddings.

Installation

npm install @mastra/chroma

Configuration

1

Start Chroma Server

Run Chroma locally with Docker:
docker run -p 8000:8000 chromadb/chroma
2

Import ChromaVector

import { ChromaVector } from '@mastra/chroma';
3

Create vector store instance

const vectorStore = new ChromaVector({
  id: 'embeddings',
  url: 'http://localhost:8000',
});
4

Configure Mastra

import { Mastra } from '@mastra/core';

const mastra = new Mastra({
  vectors: {
    embeddings: vectorStore,
  },
});

Configuration Options

id
string
required
Unique identifier for the vector store instance
url
string
default:"http://localhost:8000"
Chroma server URL
auth
object
Authentication configuration for secured Chroma instances:
{
  provider: 'token',
  credentials: 'your-token'
}

Vector Operations

Create Collection

const vectorStore = new ChromaVector({
  id: 'embeddings',
  url: 'http://localhost:8000',
});

await vectorStore.createIndex({
  indexName: 'documents',
  dimension: 1536,
  metric: 'cosine',
});

Upsert Vectors

const vectors = [
  [0.1, 0.2, 0.3, ...], // 1536 dimensions
  [0.4, 0.5, 0.6, ...],
];

const metadata = [
  { text: 'First document', source: 'doc1.pdf' },
  { text: 'Second document', source: 'doc2.pdf' },
];

const ids = await vectorStore.upsert({
  indexName: 'documents',
  vectors,
  metadata,
});

Query Similar Vectors

const queryVector = [0.15, 0.25, 0.35, ...];

const results = await vectorStore.query({
  indexName: 'documents',
  queryVector,
  topK: 5,
  includeVector: false,
});

results.forEach(result => {
  console.log(`Score: ${result.score}`);
  console.log(`Metadata: ${JSON.stringify(result.metadata)}`);
});

Query with Metadata Filters

const results = await vectorStore.query({
  indexName: 'documents',
  queryVector,
  topK: 5,
  filter: {
    source: 'doc1.pdf',
  },
});

Update Vector

await vectorStore.updateVector({
  indexName: 'documents',
  id: 'vector-id-123',
  update: {
    vector: [0.2, 0.3, 0.4, ...],
    metadata: { text: 'Updated document' },
  },
});

Delete Operations

// Delete by ID
await vectorStore.deleteVector({
  indexName: 'documents',
  id: 'vector-id-123',
});

// Delete multiple by IDs
await vectorStore.deleteVectors({
  indexName: 'documents',
  ids: ['id1', 'id2', 'id3'],
});

// Delete by metadata filter
await vectorStore.deleteVectors({
  indexName: 'documents',
  filter: {
    source: 'doc1.pdf',
  },
});

Collection Management

// List collections
const collections = await vectorStore.listIndexes();
console.log('Collections:', collections);

// Describe collection
const stats = await vectorStore.describeIndex({
  indexName: 'documents',
});
console.log('Dimension:', stats.dimension);
console.log('Vector count:', stats.count);

// Delete collection
await vectorStore.deleteIndex({
  indexName: 'documents',
});

// Clear all vectors
await vectorStore.truncateIndex({
  indexName: 'documents',
});

RAG Integration

import { Mastra } from '@mastra/core';
import { ChromaVector } from '@mastra/chroma';
import { createOpenAI } from '@ai-sdk/openai';
import { embed } from 'ai';

const mastra = new Mastra({
  vectors: {
    embeddings: new ChromaVector({
      id: 'embeddings',
      url: 'http://localhost:8000',
    }),
  },
});

const openai = createOpenAI({
  apiKey: process.env.OPENAI_API_KEY!,
});

// Index document
const { embedding } = await embed({
  model: openai.embedding('text-embedding-3-small'),
  value: 'Your document text',
});

await mastra.vectors.embeddings.upsert({
  indexName: 'documents',
  vectors: [embedding],
  metadata: [{ text: 'Your document text', source: 'manual' }],
});

// Query for context
const { embedding: queryEmbedding } = await embed({
  model: openai.embedding('text-embedding-3-small'),
  value: 'User question',
});

const results = await mastra.vectors.embeddings.query({
  indexName: 'documents',
  queryVector: queryEmbedding,
  topK: 3,
});

const context = results.map(r => r.metadata.text).join('\n\n');

Distance Metrics

Chroma supports three distance metrics:
  • cosine - Cosine similarity (default)
  • euclidean - Euclidean distance (L2)
  • dotproduct - Inner product
await vectorStore.createIndex({
  indexName: 'documents',
  dimension: 1536,
  metric: 'cosine', // or 'euclidean' or 'dotproduct'
});

Deployment Options

Docker (Development)

docker run -p 8000:8000 chromadb/chroma

Docker Compose

version: '3.8'
services:
  chroma:
    image: chromadb/chroma:latest
    ports:
      - "8000:8000"
    volumes:
      - chroma-data:/chroma/chroma
    environment:
      - IS_PERSISTENT=TRUE

volumes:
  chroma-data:

Persistent Storage

docker run -p 8000:8000 \
  -v ./chroma-data:/chroma/chroma \
  -e IS_PERSISTENT=TRUE \
  chromadb/chroma

Authentication

Token Authentication

const vectorStore = new ChromaVector({
  id: 'embeddings',
  url: 'https://your-chroma-instance.com',
  auth: {
    provider: 'token',
    credentials: process.env.CHROMA_TOKEN!,
  },
});

Best Practices

Persistent Storage

Always use persistent volumes in production to preserve data across restarts.

Batch Operations

Insert vectors in batches for better performance.

Collection Naming

Use descriptive collection names that indicate purpose and embedding model.

Monitor Collection Size

Use describeIndex() to track collection growth.

Python Integration

Chroma works seamlessly with Python:
import chromadb

client = chromadb.HttpClient(host="localhost", port=8000)
collection = client.get_collection("documents")

# Query from Python
results = collection.query(
    query_embeddings=[[0.1, 0.2, ...]],
    n_results=5
)

Pinecone

Managed vector database service

Qdrant

Open-source vector search engine

Chroma Docs

Official Chroma documentation

Chroma GitHub

Chroma open-source repository

Build docs developers (and LLMs) love