Warning
V1 API Removed: The V1 API has been removed in v0.3.0. If you require V1 API compatibility, please use versions prior to v0.3.0.
go get github.com/amikos-tech/chroma-go@v0.2.4A simple Chroma Vector Database client written in Go
Works with Chroma Version: v0.6.3 - v1.5.1
We invite users to visit the docs site for the library for more in-depth information: Chroma Go Docs
| Operation | Support |
|---|---|
| Create Tenant | ✅ |
| Get Tenant | ✅ |
| Create Database | ✅ |
| Get Database | ✅ |
| Delete Database | ✅ |
| Reset | ✅ |
| Heartbeat | ✅ |
| List Collections | ✅ |
| Count Collections | ✅ |
| Get Version | ✅ |
| Create Collection | ✅ |
| Delete Collection | ✅ |
| Collection Add | ✅ |
| Collection Get | ✅ |
| Collection Count | ✅ |
| Collection Query | ✅ |
| Collection Update | ✅ |
| Collection Upsert | ✅ |
| Collection Delete (delete documents) | ✅ |
| Modify Collection | ✅ |
| Search API | ✅ |
Additional support features:
- ✅ Authentication (Basic, Token with Authorization header, Token with X-Chroma-Token header)
- ✅ Private PKI and self-signed certificate support
- ✅ Chroma Cloud support
- ✅ Structured Logging - Injectable logger with Zap bridge for structured logging
- ✅ Persistent Embedding Function support - automatically load embedding function from Chroma collection configuration
- ✅ Persistent Client support - Run/embed full-featured Chroma in your Go application without running an external Chroma server process.
- ✅ Search API Support
- ✅ Array Metadata support with
$contains/$not_containsoperators (Chroma >= 1.5.0)
- ✅ Default Embedding Support - the default
all-MiniLM-L6-v2model running on Onnx Runtime (ORT). - ✅ OpenAI Embedding Support
- ✅ Cohere (including Multi-language support)
- ✅ Sentence Transformers (HuggingFace Inference API and HFEI local server)
- ✅ Google Gemini Embedding Support
- ✅ HuggingFace Embedding Inference Server Support
- ✅ Ollama Embedding Support
- ✅ Cloudflare Workers AI Embedding Support
- ✅ Together AI Embedding Support
- ✅ Voyage AI Embedding Support
- ✅ Mistral AI API Embedding Support
- ✅ Nomic AI Embedding Support
- ✅ Jina AI Embedding Support
- ✅ Roboflow CLIP Embedding Support (Multimodal: text + images)
- ✅ Amazon Bedrock Embedding Support (Titan models, bearer token + SDK auth)
- ✅ Baseten Embedding Support
- ✅ Morph Embedding Support
Sparse & Specialized Embedding Functions:
- ✅ Chroma Cloud Embedding Support
- ✅ Chroma Cloud Splade Embedding Support (sparse)
- ✅ BM25 Embedding Support (sparse)
The Chroma Go client supports Reranking functions:
go get github.com/amikos-tech/chroma-goImport:
import (
chroma "github.com/amikos-tech/chroma-go/pkg/api/v2"
)Ensure you have a running instance of Chroma running. We recommend one of the two following options:
- Official documentation
- If you are a fan of Kubernetes, you can use the Helm chart (Note: You
will need
Docker,minikubeandkubectlinstalled)
The Setup (Cloud-native):
minikube start --profile chromago
minikube profile chromago
helm repo add chroma https://amikos-tech.github.io/chromadb-chart/
helm repo update
helm install chroma chroma/chromadb --set chromadb.allowReset=trueNote
To delete the minikube cluster: minikube delete --profile chromago
- We create a new collection
- Add documents using the default embedding function
- Query the collection using the same embedding function
- Delete documents from the collection
package main
import (
"context"
"fmt"
"log"
chroma "github.com/amikos-tech/chroma-go/pkg/api/v2"
)
func main() {
// Create a new Chroma client
client, err := chroma.NewHTTPClient()
if err != nil {
log.Fatalf("Error creating client: %s \n", err)
return
}
// Close the client to release any resources such as local embedding functions
defer func() {
err = client.Close()
if err != nil {
log.Fatalf("Error closing client: %s \n", err)
}
}()
// Create a new collection with options. We don't provide an embedding function here, so the default embedding function will be used
col, err := client.GetOrCreateCollection(context.Background(), "col1",
chroma.WithCollectionMetadataCreate(
chroma.NewMetadata(
chroma.NewStringAttribute("str", "hello"),
chroma.NewIntAttribute("int", 1),
chroma.NewFloatAttribute("float", 1.1),
),
),
)
if err != nil {
log.Fatalf("Error creating collection: %s \n", err)
return
}
err = col.Add(context.Background(),
chroma.WithIDs("1", "2"),
chroma.WithTexts("hello world", "goodbye world"),
chroma.WithMetadatas(
chroma.NewDocumentMetadata(chroma.NewIntAttribute("int", 1)),
chroma.NewDocumentMetadata(chroma.NewStringAttribute("str", "hello")),
))
if err != nil {
log.Fatalf("Error adding collection: %s \n", err)
}
count, err := col.Count(context.Background())
if err != nil {
log.Fatalf("Error counting collection: %s \n", err)
return
}
fmt.Printf("Count collection: %d\n", count)
qr, err := col.Query(context.Background(),
chroma.WithQueryTexts("say hello"),
chroma.WithInclude(chroma.IncludeDocuments),
)
if err != nil {
log.Fatalf("Error querying collection: %s \n", err)
return
}
fmt.Printf("Query result: %v\n", qr.GetDocumentsGroups()[0][0])
err = col.Delete(context.Background(), chroma.WithIDs("1", "2"))
if err != nil {
log.Fatalf("Error deleting collection: %s \n", err)
return
}
}You can run Chroma locally in-process (no external server process) with NewLocalClient.
The runtime uses chroma-go-local. By default, NewLocalClient auto-downloads the correct shim library from the matching chroma-go-local GitHub release and caches it under ~/.cache/chroma/local_shim.
You can still override this with CHROMA_LIB_PATH or WithLocalLibraryPath(...).
NewLocalClient defaults to embedded mode; use WithLocalRuntimeMode(chroma.LocalRuntimeModeServer) (or WithLocalPort(...)) when you want a local HTTP server.
For persistence, WithLocalPersistPath(...) is typically all you need.
In server mode, the default port is 8000 unless overridden.
client, err := chroma.NewLocalClient(
chroma.WithLocalPersistPath("./chroma_data"),
chroma.WithLocalAllowReset(true),
chroma.WithLocalClientOption(chroma.WithDatabaseAndTenant("default_database", "default_tenant")),
)
if err != nil {
log.Fatalf("Error creating local client: %s", err)
}
defer client.Close()When metadata comes from map[string]interface{}:
NewMetadataFromMapis best-effort and silently skips invalid[]interface{}values.NewMetadataFromMapStrictreturns an error for invalid or unsupported values.WithCollectionMetadataMapCreateStrictapplies strict conversion in create/get-or-create flows and returns a deferred option error before any HTTP request is sent.
// Strict create/get-or-create metadata map conversion
col, err := client.GetOrCreateCollection(context.Background(), "col1",
chroma.WithCollectionMetadataMapCreateStrict(map[string]interface{}{
"description": "validated metadata",
"tags": []interface{}{"a", "b"},
}),
)
if err != nil {
log.Fatalf("Error creating collection: %s", err)
}
// Strict metadata map conversion before collection metadata update
newMetadata, err := chroma.NewMetadataFromMapStrict(map[string]interface{}{
"description": "updated description",
"tags": []interface{}{"x", "y"},
})
if err != nil {
log.Fatalf("Invalid metadata map: %s", err)
}
if err := col.ModifyMetadata(context.Background(), newMetadata); err != nil {
log.Fatalf("Error modifying metadata: %s", err)
}The V2 API provides a unified options pattern where common options work across multiple operations:
| Option | Get | Query | Delete | Add | Update | Search |
|---|---|---|---|---|---|---|
WithIDs |
✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
WithWhere |
✓ | ✓ | ✓ | |||
WithWhereDocument |
✓ | ✓ | ✓ | |||
WithInclude |
✓ | ✓ | ||||
WithTexts |
✓ | ✓ | ||||
WithMetadatas |
✓ | ✓ | ||||
WithEmbeddings |
✓ | ✓ |
// Get documents by ID or filter
results, _ := col.Get(ctx,
chroma.WithIDs("id1", "id2"),
chroma.WithWhere(chroma.EqString("status", "active")),
chroma.WithInclude(chroma.IncludeDocuments, chroma.IncludeMetadatas),
)
// Query with semantic search
results, _ := col.Query(ctx,
chroma.WithQueryTexts("machine learning"),
chroma.WithWhere(chroma.GtInt("year", 2020)),
chroma.WithNResults(10),
)
// Delete by filter
_ = col.Delete(ctx, chroma.WithWhere(chroma.EqString("status", "archived")))
// Search API with ranking and pagination
results, _ := col.Search(ctx,
chroma.NewSearchRequest(
chroma.WithKnnRank(chroma.KnnQueryText("query")),
chroma.WithFilter(chroma.EqString(chroma.K("category"), "tech")),
chroma.NewPage(chroma.Limit(20)),
chroma.WithSelect(chroma.KDocument, chroma.KScore),
),
)The client supports injectable loggers for structured logging. Here's a quick example using Zap:
package main
import (
"context"
"log"
"go.uber.org/zap"
chromalogger "github.com/amikos-tech/chroma-go/pkg/logger"
chroma "github.com/amikos-tech/chroma-go/pkg/api/v2"
)
func main() {
// Create a zap logger
zapLogger, _ := zap.NewDevelopment()
defer zapLogger.Sync()
// Wrap it in the Chroma logger
logger := chromalogger.NewZapLogger(zapLogger)
// Create client with the logger
client, err := chroma.NewHTTPClient(
chroma.WithBaseURL("http://localhost:8000"),
chroma.WithLogger(logger),
)
if err != nil {
log.Fatal(err)
}
defer client.Close()
// All client operations will now be logged with structured logging
ctx := context.Background()
collections, _ := client.ListCollections(ctx)
// You can also log directly
logger.Info("Retrieved collections",
chromalogger.Int("count", len(collections)),
)
// For debug logging, use WithLogger with a debug-level logger
devLogger, _ := chromalogger.NewDevelopmentZapLogger()
debugClient, _ := chroma.NewHTTPClient(
chroma.WithBaseURL("http://localhost:8000"),
chroma.WithLogger(devLogger),
)
defer debugClient.Close()
}See the logging documentation for more details.
make buildmake testmake lint-fixNote: Docker must be installed
make server- Official Chroma documentation
- Chroma Helm chart for cloud-native deployments
- Chroma Cookbook for examples and recipes