---
name: chroma
description: Use when building vector databases for AI applications, implementing semantic search, managing embeddings, querying collections, or deploying retrieval systems. Agents should reach for this skill when working with embeddings, vector storage, similarity search, metadata filtering, or building RAG (Retrieval-Augmented Generation) pipelines.
metadata:
    mintlify-proj: chroma
    version: "1.0"
---

# Chroma Skill

## Product Summary

Chroma is an open-source vector database for AI applications. It provides storage and retrieval of embeddings with metadata, supports dense and sparse vector search, full-text search, and metadata filtering. Agents use Chroma to build semantic search systems, RAG pipelines, and AI-powered retrieval applications.

**Key files and commands:**
- Python: `import chromadb` → `chromadb.Client()`, `chromadb.PersistentClient()`, `chromadb.CloudClient()`
- TypeScript: `npm install chromadb` → `new ChromaClient()`, `new CloudClient()`
- CLI: `chroma run`, `chroma login`, `chroma db create`, `chroma db connect`
- Collections are the core unit: store embeddings, documents, and metadata
- Embedding functions: default is `all-MiniLM-L6-v2` (local), or use OpenAI, Cohere, Hugging Face, etc.

**Primary docs:** https://docs.trychroma.com

## When to Use

Reach for this skill when:
- Building semantic search or similarity search systems
- Implementing RAG (Retrieval-Augmented Generation) pipelines
- Storing and querying embeddings with metadata
- Filtering search results by metadata conditions
- Combining dense vector search with full-text search
- Deploying a vector database locally, self-hosted, or on Chroma Cloud
- Working with multimodal data (text, images, audio)
- Agents need to index documents and retrieve relevant context for LLM applications

Do NOT use Chroma for: traditional SQL databases, non-embedding-based queries, or systems that don't need semantic search.

## Quick Reference

### Client Types

| Client Type | Use Case | Persistence |
|---|---|---|
| `Client()` (Python) | Development, prototyping | In-memory only |
| `PersistentClient(path)` (Python) | Local development with persistence | Disk-based |
| `ChromaClient()` (TypeScript) | Requires running server | Via server |
| `CloudClient()` | Production, managed service | Chroma Cloud |
| `ChromaHttpClient` (Rust) | HTTP client for server | Via server |

### Core Collection Operations

| Operation | Method | Purpose |
|---|---|---|
| Create | `client.create_collection(name)` | New collection |
| Get | `client.get_collection(name)` | Retrieve existing |
| Get or Create | `client.get_or_create_collection(name)` | Idempotent |
| List | `client.list_collections()` | All collections |
| Delete | `client.delete_collection(name)` | Remove collection |
| Add data | `collection.add(ids, documents, metadatas)` | Insert records |
| Update | `collection.update(ids, documents, metadatas)` | Modify existing |
| Upsert | `collection.upsert(ids, documents, metadatas)` | Add or update |
| Delete | `collection.delete(ids)` or `collection.delete(where={...})` | Remove records |
| Query | `collection.query(query_texts, n_results)` | Similarity search |
| Get | `collection.get(ids)` or `collection.get(where={...})` | Retrieve without ranking |

### Metadata Filtering Operators

| Operator | Example | Meaning |
|---|---|---|
| `$eq` | `{"page": {"$eq": 10}}` | Equal to |
| `$ne` | `{"page": {"$ne": 10}}` | Not equal |
| `$gt` | `{"page": {"$gt": 10}}` | Greater than |
| `$gte` | `{"page": {"$gte": 10}}` | Greater than or equal |
| `$lt` | `{"page": {"$lt": 10}}` | Less than |
| `$lte` | `{"page": {"$lte": 10}}` | Less than or equal |
| `$contains` | `{"tags": {"$contains": "tech"}}` | Array contains value |
| `$not_contains` | `{"tags": {"$not_contains": "draft"}}` | Array does not contain |
| `$in` | `{"page": {"$in": [1, 2, 3]}}` | Value in list |
| `$nin` | `{"page": {"$nin": [1, 2, 3]}}` | Value not in list |

### Document Filtering Operators

| Operator | Example | Purpose |
|---|---|---|
| `$contains` | `{"$contains": "search text"}` | Substring match (case-sensitive) |
| `$not_contains` | `{"$not_contains": "exclude"}` | Exclude substring |
| `$regex` | `{"$regex": "^pattern"}` | Regex pattern match |
| `$not_regex` | `{"$not_regex": "^draft"}` | Exclude regex pattern |

### CLI Commands

```bash
chroma run --path ./data              # Start local server
chroma login                          # Authenticate with Chroma Cloud
chroma db create my-db                # Create database
chroma db connect my-db --env-file    # Generate .env file
chroma profile show                   # Show active profile
chroma profile use team-name          # Switch profile
```

## Decision Guidance

### When to Use Query vs Get

| Scenario | Use Query | Use Get |
|---|---|---|
| Find similar documents | ✓ | |
| Retrieve by exact ID | | ✓ |
| Semantic search | ✓ | |
| Pagination without ranking | | ✓ |
| Combine with metadata filter | ✓ | ✓ |
| Need distance scores | ✓ | |

### When to Use Add vs Upsert vs Update

| Scenario | Use Add | Use Upsert | Use Update |
|---|---|---|---|
| Insert new records | ✓ | | |
| Insert or update (idempotent) | | ✓ | |
| Modify existing records | | | ✓ |
| Avoid duplicates | | ✓ | |
| Fail on duplicate IDs | ✓ | | |

### Deployment Mode Selection

| Mode | Scale | Persistence | Use Case |
|---|---|---|---|
| In-Memory (`Client()`) | Prototyping | No | Development, notebooks |
| Persistent (`PersistentClient()`) | Small | Local disk | Local development |
| Self-Hosted Server | Medium | Configurable | Private deployment |
| Chroma Cloud | Large | Managed | Production, zero-ops |

### Embedding Function Selection

| Provider | Speed | Cost | Local | Use When |
|---|---|---|---|---|
| Default (all-MiniLM-L6-v2) | Fast | Free | Yes | Prototyping, no API keys |
| OpenAI | Medium | Paid | No | High quality, production |
| Sentence Transformers | Fast | Free | Yes | Custom models, fine-tuning |
| Hugging Face | Medium | Free/Paid | Yes/No | Specific model needs |
| Cohere | Medium | Paid | No | Multilingual support |

## Workflow

### 1. Set Up Client and Collection

```python
import chromadb

# Choose client type
client = chromadb.PersistentClient(path="./chroma_data")  # or CloudClient(), Client()

# Create or get collection
collection = client.get_or_create_collection(
    name="my_collection",
    metadata={"description": "My first collection"}
)
```

### 2. Add Documents with Embeddings

```python
# Chroma auto-embeds if you provide documents
collection.add(
    ids=["id1", "id2", "id3"],
    documents=["Document 1 text", "Document 2 text", "Document 3 text"],
    metadatas=[
        {"source": "file1", "page": 1},
        {"source": "file2", "page": 2},
        {"source": "file3", "page": 3}
    ]
)
```

### 3. Query with Filters

```python
# Semantic search with metadata filtering
results = collection.query(
    query_texts=["search query"],
    n_results=5,
    where={"page": {"$gte": 1}},  # metadata filter
    where_document={"$contains": "keyword"}  # full-text filter
)

# Access results
for ids, documents, distances, metadatas in zip(
    results["ids"][0], 
    results["documents"][0], 
    results["distances"][0], 
    results["metadatas"][0]
):
    print(f"ID: {ids}, Distance: {distances}, Metadata: {metadatas}")
```

### 4. Update or Delete Records

```python
# Update existing records
collection.update(
    ids=["id1"],
    documents=["Updated document text"],
    metadatas=[{"source": "file1", "page": 1, "updated": True}]
)

# Delete by ID
collection.delete(ids=["id1"])

# Delete by metadata filter
collection.delete(where={"source": "file1"})
```

### 5. Deploy to Production

```python
# Use CloudClient for production
import os
client = chromadb.CloudClient(
    api_key=os.getenv("CHROMA_API_KEY"),
    tenant=os.getenv("CHROMA_TENANT"),
    database=os.getenv("CHROMA_DATABASE")
)
```

## Common Gotchas

- **Duplicate IDs with `.add()`**: If you add a record with an ID that already exists, it is silently ignored. Use `.upsert()` to update or `.update()` to modify existing records.
- **Embedding dimension mismatch**: If you provide embeddings with different dimensions than existing records, an exception is raised. Ensure all embeddings have the same dimension.
- **Missing embedding function**: If you create a collection without an embedding function and later try to query with text, you must provide pre-computed embeddings. The default function is `all-MiniLM-L6-v2`.
- **Metadata type constraints**: Metadata values must be strings, integers, floats, booleans, or arrays of these types. Nested objects are not supported.
- **In-memory data loss**: `Client()` loses all data when the process terminates. Use `PersistentClient()` or `CloudClient()` for production.
- **Collection name restrictions**: Names must be 3-512 characters, start/end with lowercase letter or digit, and cannot contain consecutive dots or be valid IP addresses.
- **Query returns column-major format**: Results are grouped by field (all IDs together, all documents together), not by record. Iterate carefully.
- **Default n_results is 10**: If you don't specify `n_results`, Chroma returns 10 results. Set it explicitly for different counts.
- **Metadata filtering is exact by default**: Use `$contains` for substring matching on metadata arrays, not on string fields.
- **Document filtering is case-sensitive**: `$contains` and `$regex` on documents are case-sensitive by default.

## Verification Checklist

Before submitting work with Chroma:

- [ ] Collection created with appropriate name (3-512 chars, valid format)
- [ ] Embedding function specified or default acceptable
- [ ] All record IDs are unique strings
- [ ] Metadata values are valid types (string, int, float, bool, or arrays)
- [ ] Embeddings (if provided) match collection dimension
- [ ] Query results parsed correctly (column-major format)
- [ ] Metadata filters use correct operators for field types
- [ ] Document filters use `where_document` parameter, not `where`
- [ ] Destructive operations (delete, reset) are intentional
- [ ] Client type matches deployment (CloudClient for production, PersistentClient for local)
- [ ] Environment variables set for CloudClient (CHROMA_API_KEY, CHROMA_TENANT, CHROMA_DATABASE)
- [ ] Collection persists data appropriately (not using in-memory Client for production)

## Resources

**Comprehensive navigation:** https://docs.trychroma.com/llms.txt

**Critical documentation pages:**
1. [Getting Started](https://docs.trychroma.com/docs/overview/getting-started) — Quick setup for Python, TypeScript, Rust
2. [Collections & Data Management](https://docs.trychroma.com/docs/collections/manage-collections) — Create, add, update, delete operations
3. [Querying & Filtering](https://docs.trychroma.com/docs/querying-collections/query-and-get) — Query API, metadata filtering, full-text search

---

> For additional documentation and navigation, see: https://docs.trychroma.com/llms.txt