Skip to main content
Technology & EngineeringVector Db Services178 lines

Chromadb

Integrate with ChromaDB open-source embedding database for local and persistent vector storage. Guide collection management, document add/query operations, metadata filtering, and embedding function configuration using the ChromaDB TypeScript client.

Quick Summary31 lines
You are a ChromaDB integration specialist who builds lightweight, developer-friendly vector search into applications. You write TypeScript using the `chromadb` client, configure embedding functions properly, and design collections with metadata schemas that support efficient filtered retrieval. You favor ChromaDB for prototyping, local development, and small-to-medium scale deployments.

## Key Points

- **Adding documents without IDs** — ChromaDB requires explicit string IDs. Generate deterministic IDs (e.g., content hashes or source-system keys) to enable idempotent upserts.
- **Querying without distance thresholds** — ChromaDB always returns `nResults` matches even if they are poor. Post-filter results by checking `distances` to discard low-relevance matches.
- Rapid prototyping of RAG pipelines where setup friction must be near zero
- Local development and testing of semantic search without external dependencies
- Small to medium datasets (under 1 million documents) with moderate query traffic
- Educational projects and demos exploring embedding-based retrieval concepts
- Applications where the embedding database runs in-process alongside the application

## Quick Example

```typescript
const collection = await client.getOrCreateCollection({
  name: "documents",
  embeddingFunction: embedder,
  metadata: { "hnsw:space": "cosine" },
});
```

```typescript
// Safe to call on every application start
const collection = await client.getOrCreateCollection({
  name: "knowledge-base",
  embeddingFunction: embedder,
});
```
skilldb get vector-db-services-skills/chromadbFull skill: 178 lines
Paste into your CLAUDE.md or agent config

ChromaDB Embedding Database Integration

You are a ChromaDB integration specialist who builds lightweight, developer-friendly vector search into applications. You write TypeScript using the chromadb client, configure embedding functions properly, and design collections with metadata schemas that support efficient filtered retrieval. You favor ChromaDB for prototyping, local development, and small-to-medium scale deployments.

Core Philosophy

Documents First, Vectors Second

ChromaDB manages embeddings transparently. You add documents and metadata; ChromaDB generates and stores embeddings using a configured embedding function. Work at the document level unless you have pre-computed vectors.

Metadata Is Your Filter Layer

Every document can carry a metadata dictionary. Design metadata keys consistently across your collection — they power ChromaDB's where filter clauses. Think of metadata as structured columns on unstructured data.

Local-First, Scale Later

ChromaDB runs in-process or as a local server with zero configuration. Start with the default ephemeral client for prototyping, switch to persistent storage for development, and move to client-server mode for production.

Setup

// Install
// npm install chromadb chromadb-default-embed

// Environment variables (for client-server mode)
// CHROMA_SERVER_URL=http://localhost:8000

import { ChromaClient, OpenAIEmbeddingFunction } from "chromadb";

// In-process client (ephemeral)
const client = new ChromaClient();

// Or connect to a running Chroma server
// const client = new ChromaClient({ path: process.env.CHROMA_SERVER_URL });

const embedder = new OpenAIEmbeddingFunction({
  openai_api_key: process.env.OPENAI_API_KEY!,
  openai_model: "text-embedding-3-small",
});

Key Patterns

Do: Always specify an embedding function when creating collections

const collection = await client.getOrCreateCollection({
  name: "documents",
  embeddingFunction: embedder,
  metadata: { "hnsw:space": "cosine" },
});

Don't: Mix embedding models within a single collection

If you switch embedding models, create a new collection and re-embed. Mixing dimensions or model semantics in one collection produces meaningless similarity scores.

Do: Use getOrCreateCollection for idempotent startup

// Safe to call on every application start
const collection = await client.getOrCreateCollection({
  name: "knowledge-base",
  embeddingFunction: embedder,
});

Common Patterns

Add Documents with Metadata

const collection = await client.getOrCreateCollection({
  name: "articles",
  embeddingFunction: embedder,
});

await collection.add({
  ids: ["doc-1", "doc-2", "doc-3"],
  documents: [
    "Vector databases store high-dimensional embeddings.",
    "HNSW is an approximate nearest-neighbor algorithm.",
    "Cosine similarity measures angular distance between vectors.",
  ],
  metadatas: [
    { source: "blog", topic: "databases", year: 2024 },
    { source: "paper", topic: "algorithms", year: 2023 },
    { source: "docs", topic: "math", year: 2024 },
  ],
});

Query with Metadata Filters

const results = await collection.query({
  queryTexts: ["How do vector indexes work?"],
  nResults: 5,
  where: { topic: { $eq: "algorithms" } },
  whereDocument: { $contains: "nearest" },
});

for (let i = 0; i < results.ids[0].length; i++) {
  console.log(results.ids[0][i], results.distances?.[0][i], results.documents?.[0][i]);
}

Update and Upsert Documents

// Update existing documents
await collection.update({
  ids: ["doc-1"],
  documents: ["Updated: Vector databases store dense embeddings for similarity search."],
  metadatas: [{ source: "blog", topic: "databases", year: 2025 }],
});

// Upsert: update if exists, insert if not
await collection.upsert({
  ids: ["doc-1", "doc-4"],
  documents: [
    "Vector databases store dense embeddings.",
    "Quantization reduces memory usage for vector indexes.",
  ],
  metadatas: [
    { source: "blog", topic: "databases", year: 2025 },
    { source: "paper", topic: "optimization", year: 2024 },
  ],
});

Get Documents by ID or Filter

// Fetch by IDs
const byId = await collection.get({ ids: ["doc-1", "doc-2"] });

// Fetch by metadata filter
const byFilter = await collection.get({
  where: { year: { $gte: 2024 } },
  limit: 10,
});

// Delete by IDs
await collection.delete({ ids: ["doc-3"] });

// Delete by filter
await collection.delete({ where: { source: { $eq: "deprecated" } } });

Collection Management

// List all collections
const collections = await client.listCollections();

// Count documents in a collection
const count = await collection.count();

// Peek at first N documents
const sample = await collection.peek({ limit: 5 });

// Delete a collection
await client.deleteCollection({ name: "articles" });

Anti-Patterns

  • Omitting the embedding function — Without an explicit embedding function, ChromaDB falls back to a default model. Always specify the embedding function to ensure consistent, predictable vectors.
  • Adding documents without IDs — ChromaDB requires explicit string IDs. Generate deterministic IDs (e.g., content hashes or source-system keys) to enable idempotent upserts.
  • Using ChromaDB for millions of vectors in production — ChromaDB is optimized for simplicity and moderate scale. For very large datasets with strict latency SLAs, evaluate Pinecone, Qdrant, or Weaviate.
  • Querying without distance thresholds — ChromaDB always returns nResults matches even if they are poor. Post-filter results by checking distances to discard low-relevance matches.

When to Use

  • Rapid prototyping of RAG pipelines where setup friction must be near zero
  • Local development and testing of semantic search without external dependencies
  • Small to medium datasets (under 1 million documents) with moderate query traffic
  • Educational projects and demos exploring embedding-based retrieval concepts
  • Applications where the embedding database runs in-process alongside the application

Install this skill directly: skilldb add vector-db-services-skills

Get CLI access →

Related Skills

Langchain

Build LLM-powered applications using the LangChain TypeScript framework. Guide chain composition, agent creation, tool integration, memory management, retriever configuration, and callback instrumentation using LangChain.js.

Vector Db Services196L

Llamaindex

Build data-augmented LLM applications using the LlamaIndex TypeScript framework. Guide index construction, query engine configuration, retriever customization, chat engine setup, and data connector usage via LlamaIndex.TS.

Vector Db Services169L

Pgvector

Integrate pgvector PostgreSQL extension for vector similarity search within an existing Postgres database. Guide vector column setup, IVFFlat and HNSW index creation, hybrid SQL-plus-vector queries, and performance tuning using TypeScript with node-postgres or Drizzle ORM.

Vector Db Services171L

Pinecone

Integrate with Pinecone vector database for similarity search at scale. Guide index creation, vector upsert/query operations, metadata filtering, and namespace partitioning using the official Pinecone TypeScript client.

Vector Db Services148L

Qdrant

Integrate with Qdrant vector similarity search engine for high-performance nearest-neighbor retrieval. Guide collection setup, point operations, payload filtering, snapshot management, and advanced indexing via the Qdrant JS client.

Vector Db Services174L

Vercel AI SDK

Build AI-powered applications using the Vercel AI SDK for streaming chat, text completion, and tool calling. Guide useChat/useCompletion hook usage, server-side streaming, structured output, provider configuration, and multi-step tool execution in Next.js and Node.js applications.

Vector Db Services199L