# chromadb-java-client
**Repository Path**: changshu/chromadb-java-client
## Basic Information
- **Project Name**: chromadb-java-client
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-04-13
- **Last Updated**: 2026-04-13
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Chroma Vector Database Java Client
Production-ready Java client for ChromaDB v2 API.
This client works with Chroma Versions `>=1.0.0` | Requires Java 8+
## Requirements
- Java 8 or higher
- Maven or Gradle
- A running ChromaDB instance (`>=1.0.0`) or a Chroma Cloud account
## Installation
**Maven:**
```xml
io.github.amikos-tech
chromadb-java-client
0.2.0
```
**Gradle:**
```gradle
implementation 'io.github.amikos-tech:chromadb-java-client:0.2.0'
```
## Quick Start
```java
import tech.amikos.chromadb.v2.*;
import tech.amikos.chromadb.embeddings.DefaultEmbeddingFunction;
Client client = ChromaClient.builder()
.baseUrl(System.getenv("CHROMA_URL"))
.build();
DefaultEmbeddingFunction ef = new DefaultEmbeddingFunction();
Collection collection = client.getOrCreateCollection(
"my-collection",
CreateCollectionOptions.builder()
.embeddingFunction(ef)
.build()
);
collection.add()
.documents("Hello, my name is John. I am a Data Scientist.",
"Hello, my name is Bond. I am a Spy.")
.ids("id-1", "id-2")
.execute();
QueryResult result = collection.query()
.queryTexts("Who is the spy?")
.nResults(5)
.include(Include.DOCUMENTS, Include.DISTANCES)
.execute();
System.out.println(result);
```
## Usage
### Authentication
#### Basic Auth
```java
import tech.amikos.chromadb.v2.*;
Client client = ChromaClient.builder()
.baseUrl(System.getenv("CHROMA_URL"))
.auth(BasicAuth.of("admin", "password"))
.build();
```
#### Token Auth
```java
import tech.amikos.chromadb.v2.*;
Client client = ChromaClient.builder()
.baseUrl(System.getenv("CHROMA_URL"))
.auth(TokenAuth.of(System.getenv("CHROMA_TOKEN")))
.build();
```
#### Chroma Token Auth
```java
import tech.amikos.chromadb.v2.*;
Client client = ChromaClient.builder()
.baseUrl(System.getenv("CHROMA_URL"))
.auth(ChromaTokenAuth.of(System.getenv("CHROMA_TOKEN")))
.build();
```
### Cloud (Chroma Cloud)
```java
import tech.amikos.chromadb.v2.*;
Client client = ChromaClient.cloud()
.apiKey(System.getenv("CHROMA_API_KEY"))
.tenant(System.getenv("CHROMA_TENANT"))
.database(System.getenv("CHROMA_DATABASE"))
.build();
```
### Cloud vs Self-Hosted Feature Parity
| Operation | Self-Hosted | Chroma Cloud | Notes |
|-----------|:-----------:|:------------:|-------|
| `heartbeat()` | Yes | Yes | |
| `version()` | Yes | Yes | |
| `preFlight()` | Yes | Yes | |
| `getIdentity()` | Yes | Yes | |
| `reset()` | Yes | No | Server-side reset, not available on cloud |
| `createTenant()` | Yes | Yes | |
| `getTenant()` | Yes | Yes | |
| `createDatabase()` | Yes | Yes | |
| `getDatabase()` | Yes | Yes | |
| `listDatabases()` | Yes | Yes | |
| `deleteDatabase()` | Yes | Yes | |
| `createCollection()` | Yes | Yes | |
| `getCollection()` | Yes | Yes | |
| `getOrCreateCollection()` | Yes | Yes | |
| `listCollections()` | Yes | Yes | |
| `deleteCollection()` | Yes | Yes | |
| `countCollections()` | Yes | Yes | |
| `collection.add()` | Yes | Yes | |
| `collection.query()` | Yes | Yes | |
| `collection.get()` | Yes | Yes | |
| `collection.update()` | Yes | Yes | |
| `collection.upsert()` | Yes | Yes | |
| `collection.delete()` | Yes | Yes | |
| `collection.count()` | Yes | Yes | |
| `collection.modifyName()` | Yes | Yes | |
| `collection.modifyMetadata()` | Yes | Yes | |
| `collection.modifyConfiguration()` | Yes | Yes | |
| `collection.fork()` | No | Yes | Copy-on-write; 256-fork-edge limit |
| `collection.forkCount()` | No | Yes | |
| `collection.indexingStatus()` | No | Yes | Requires Chroma >= 1.4.1 |
### Transport Options
`ChromaClient.builder()` supports transport customization for production and platform integration scenarios:
```java
import okhttp3.OkHttpClient;
import tech.amikos.chromadb.v2.ChromaClient;
import tech.amikos.chromadb.v2.Client;
import java.nio.file.Paths;
import java.time.Duration;
// Custom CA certificate + env-based tenant/database
Client client = ChromaClient.builder()
.baseUrl("https://your-chroma-host")
.sslCert(Paths.get("/path/to/ca-cert.pem"))
.tenantFromEnv("CHROMA_TENANT")
.databaseFromEnv("CHROMA_DATABASE")
.connectTimeout(Duration.ofSeconds(5))
.readTimeout(Duration.ofSeconds(30))
.build();
// Provide a fully configured OkHttpClient (mutually exclusive with builder timeout/TLS options)
OkHttpClient custom = new OkHttpClient.Builder()
.readTimeout(Duration.ofSeconds(20))
.build();
Client clientWithCustomHttp = ChromaClient.builder()
.httpClient(custom)
.build();
```
Notes:
- `.insecure(true)` enables trust-all TLS (development only).
- `.sslCert(...)` augments default JVM trust with your custom CA certificate(s).
- `.httpClient(...)` cannot be combined with `.connectTimeout(...)`, `.readTimeout(...)`, `.writeTimeout(...)`, `.sslCert(...)`, or `.insecure(...)`.
- `.tenantAndDatabaseFromEnv()` reads `CHROMA_TENANT` and `CHROMA_DATABASE`.
### Collection Lifecycle
```java
import tech.amikos.chromadb.v2.*;
import java.util.List;
// Create a new collection (throws ChromaConflictException if already exists)
Collection collection = client.createCollection("my-collection");
// Get or create (idempotent)
Collection collection = client.getOrCreateCollection("my-collection");
// Get an existing collection
Collection collection = client.getCollection("my-collection");
// List all collections
List collections = client.listCollections();
// Delete a collection
client.deleteCollection("my-collection");
// Count collections
int count = client.countCollections();
```
### Adding Records
```java
import tech.amikos.chromadb.v2.*;
import java.util.HashMap;
import java.util.Map;
// Add with documents and metadata
Map meta1 = new HashMap();
meta1.put("type", "scientist");
Map meta2 = new HashMap();
meta2.put("type", "spy");
collection.add()
.documents("Hello, my name is John. I am a Data Scientist.",
"Hello, my name is Bond. I am a Spy.")
.metadatas(meta1, meta2)
.ids("id-1", "id-2")
.execute();
// Add with pre-computed embeddings
collection.add()
.embeddings(new float[]{0.1f, 0.2f, 0.3f}, new float[]{0.4f, 0.5f, 0.6f})
.ids("embed-1", "embed-2")
.execute();
```
### Querying
```java
import tech.amikos.chromadb.v2.*;
// Query by text
QueryResult result = collection.query()
.queryTexts("Who is the spy?")
.nResults(5)
.include(Include.DOCUMENTS, Include.DISTANCES)
.execute();
// Query with metadata filter
QueryResult filtered = collection.query()
.queryTexts("scientist")
.nResults(5)
.where(Where.eq("type", "scientist"))
.execute();
// Query by pre-computed embeddings
QueryResult byEmbedding = collection.query()
.queryEmbeddings(new float[]{0.1f, 0.2f, 0.3f})
.nResults(3)
.execute();
```
### Schema and CMEK
```java
import tech.amikos.chromadb.v2.*;
import java.util.Collections;
Client client = ChromaClient.builder()
.baseUrl(System.getenv("CHROMA_URL"))
.build();
Schema schema = Schema.builder()
.key(Schema.EMBEDDING_KEY, ValueTypes.builder()
.floatList(FloatListValueType.builder()
.vectorIndex(VectorIndexType.builder()
.config(VectorIndexConfig.builder()
.space(DistanceFunction.COSINE)
.embeddingFunction(EmbeddingFunctionSpec.builder()
.type("known")
.name("openai")
.config(Collections.singletonMap("api_key_env_var", "OPENAI_API_KEY"))
.build())
.build())
.build())
.build())
.build())
.cmek(Cmek.gcpKms("projects/my-project/locations/us-central1/keyRings/my-keyring/cryptoKeys/my-key"))
.build();
Collection collection = client.getOrCreateCollection(
"v2-schema-demo",
CreateCollectionOptions.builder()
.schema(schema)
.build()
);
QueryResult result = collection.query()
.queryTexts("find documents about transformers")
.nResults(3)
.include(Include.DOCUMENTS, Include.DISTANCES)
.execute();
```
Notes:
- Runtime embedding function precedence: explicit runtime function passed during collection construction (`CreateCollectionOptions.embeddingFunction(...)` or `client.getCollection(name, embeddingFunction)`) wins.
- Descriptor fallback order when no runtime function is provided: `configuration.embedding_function`, then top-level `schema` `#embedding` vector index embedding function, then `configuration.schema` `#embedding` vector index embedding function.
- Unsupported providers in descriptors fail fast with `ChromaException` and guidance to use `queryEmbeddings(...)`.
### ID Generators
You can generate IDs client-side for `add()` and `upsert()` via `.idGenerator(...)`.
```java
import tech.amikos.chromadb.v2.*;
// Random UUID IDs (works with embeddings-only or documents)
collection.add()
.idGenerator(UuidIdGenerator.INSTANCE)
.embeddings(new float[]{1.0f, 2.0f}, new float[]{3.0f, 4.0f})
.execute();
// ULID IDs
collection.upsert()
.idGenerator(UlidIdGenerator.INSTANCE)
.documents("doc-1", "doc-2")
.execute();
// Deterministic IDs from document SHA-256
collection.add()
.idGenerator(Sha256IdGenerator.INSTANCE)
.documents("hello")
.execute();
```
Rules:
- `ids(...)` and `idGenerator(...)` are mutually exclusive (validated at `execute()` time).
- `idGenerator(...)` requires at least one non-empty data field (`documents`, `embeddings`, `metadatas`, or `uris`) to infer record count.
- `Sha256IdGenerator` requires a non-null document or non-null metadata; throws `IllegalArgumentException` if both are null.
- Duplicate generated IDs within the same batch are rejected client-side before sending the request.
### Embedding Functions
#### Default (Local)
The default embedding function runs locally using ONNX Runtime and requires no API key.
```java
import tech.amikos.chromadb.v2.*;
import tech.amikos.chromadb.embeddings.DefaultEmbeddingFunction;
DefaultEmbeddingFunction ef = new DefaultEmbeddingFunction();
Collection collection = client.getOrCreateCollection(
"my-collection",
CreateCollectionOptions.builder()
.embeddingFunction(ef)
.build()
);
```
#### OpenAI
Ensure `OPENAI_API_KEY` environment variable is set.
```java
import tech.amikos.chromadb.v2.*;
import tech.amikos.chromadb.embeddings.openai.OpenAIEmbeddingFunction;
import tech.amikos.chromadb.embeddings.WithParam;
String apiKey = System.getenv("OPENAI_API_KEY");
OpenAIEmbeddingFunction ef = new OpenAIEmbeddingFunction(WithParam.apiKey(apiKey), WithParam.model("text-embedding-3-small"));
Collection collection = client.getOrCreateCollection(
"openai-collection",
CreateCollectionOptions.builder()
.embeddingFunction(ef)
.build()
);
```
#### Cohere
Ensure `COHERE_API_KEY` environment variable is set.
```java
import tech.amikos.chromadb.v2.*;
import tech.amikos.chromadb.embeddings.cohere.CohereEmbeddingFunction;
import tech.amikos.chromadb.embeddings.WithParam;
String apiKey = System.getenv("COHERE_API_KEY");
CohereEmbeddingFunction ef = new CohereEmbeddingFunction(WithParam.apiKey(apiKey), WithParam.model("embed-english-v2.0"));
Collection collection = client.getOrCreateCollection(
"cohere-collection",
CreateCollectionOptions.builder()
.embeddingFunction(ef)
.build()
);
```
#### HuggingFace
Ensure `HF_API_KEY` environment variable is set.
```java
import tech.amikos.chromadb.v2.*;
import tech.amikos.chromadb.embeddings.hf.HuggingFaceEmbeddingFunction;
import tech.amikos.chromadb.embeddings.WithParam;
String apiKey = System.getenv("HF_API_KEY");
HuggingFaceEmbeddingFunction ef = new HuggingFaceEmbeddingFunction(WithParam.apiKey(apiKey));
Collection collection = client.getOrCreateCollection(
"hf-collection",
CreateCollectionOptions.builder()
.embeddingFunction(ef)
.build()
);
```
For self-hosted HuggingFace Text Embeddings Inference (HFEI), start a local server first:
```bash
docker run -d -p 8008:80 --platform linux/amd64 --name hfei \
ghcr.io/huggingface/text-embeddings-inference:cpu-1.8.3 \
--model-id sentence-transformers/all-MiniLM-L6-v2
```
Then use the HFEI API type:
```java
import tech.amikos.chromadb.embeddings.hf.HuggingFaceEmbeddingFunction;
import tech.amikos.chromadb.embeddings.WithParam;
HuggingFaceEmbeddingFunction ef = new HuggingFaceEmbeddingFunction(
WithParam.baseAPI("http://localhost:8008"),
new HuggingFaceEmbeddingFunction.WithAPIType(HuggingFaceEmbeddingFunction.APIType.HFEI_API));
```
#### Ollama
```java
import tech.amikos.chromadb.v2.*;
import tech.amikos.chromadb.embeddings.ollama.OllamaEmbeddingFunction;
OllamaEmbeddingFunction ef = new OllamaEmbeddingFunction();
Collection collection = client.getOrCreateCollection(
"ollama-collection",
CreateCollectionOptions.builder()
.embeddingFunction(ef)
.build()
);
```
## Status
**Supported:**
- v2 API (collections, records, queries, tenants, databases)
- Authentication: Basic Auth, Token (Bearer), Chroma Token, Chroma Cloud
- Embedding functions: Default/local (ONNX, no API key), OpenAI, Cohere, HuggingFace Inference API, HuggingFace Text Embeddings Inference (HFEI), Ollama
- ID generators: UUID, ULID, SHA-256
- Schema and CMEK (GCP KMS)
- Transport options: SSL certificates, custom timeouts, custom OkHttpClient
- Java 8+
- Chroma 1.0.0+
**Planned:**
- Async/reactive API
- Cloudflare Workers AI embeddings
- Gemini embeddings
- Observability hooks
- Spring integration
## Development
This project includes a `Makefile` to simplify common development tasks.
### Quick Start
```bash
# Display available commands
make help
# Build the project
make build
# Run tests
make test
# Create JAR package
make package
```
### Common Development Commands
| Command | Description |
|---------|-------------|
| `make build` | Clean and compile the project |
| `make test` | Run all tests |
| `make test-unit` | Run unit tests only |
| `make test-integration` | Run integration tests only |
| `make test-version CHROMA_VERSION=1.5.5` | Test with specific ChromaDB version |
| `make test-class TEST=YourTestClass` | Run specific test class |
| `make test-method TEST=YourTestClass#yourTestMethod` | Run specific test method |
| `make package` | Create JAR package |
| `make install` | Install to local Maven repository |
| `make clean` | Clean build artifacts |
| `make deps` | Download/update dependencies |
| `make deps-tree` | Display dependency tree |
| `make info` | Display project information |
### Environment Variables
For testing with external services, set these environment variables:
- `OPENAI_API_KEY` - Required for OpenAI embedding tests
- `COHERE_API_KEY` - Required for Cohere embedding tests
- `HF_API_KEY` - Required for HuggingFace embedding tests
- `CHROMA_VERSION` - Specify ChromaDB version for integration tests (default: `1.5.5`)
### Shortcuts
The Makefile also provides single-letter shortcuts for common commands:
- `make b` - Build
- `make t` - Test
- `make c` - Clean
- `make i` - Install
## Contributing
Pull requests are welcome.
## Upgrading from 0.1.x
Version 0.2.0 removes the v1 API classes and introduces a new builder-based v2 API. See [MIGRATION.md](MIGRATION.md) for breaking changes, a v1-to-v2 mapping table, and migration examples.
## References
- https://docs.trychroma.com/ - Official Chroma documentation
- https://github.com/amikos-tech/chromadb-chart - Chroma Helm chart for cloud-native deployments
- https://github.com/openai/openai-openapi - OpenAI OpenAPI specification
## Appendix: v1 API Examples (Legacy)
Expand v1 examples (deprecated)
> These examples use the removed v1 API. See [Quick Start](#quick-start) above for current v2 usage.
### Default Embedding Function (v1)
```java
package tech.amikos;
import tech.amikos.chromadb.*;
import tech.amikos.chromadb.Collection;
import tech.amikos.chromadb.embeddings.DefaultEmbeddingFunction;
import java.util.*;
public class Main {
public static void main(String[] args) {
try {
Client client = new Client(System.getenv("CHROMA_URL"));
client.reset();
EmbeddingFunction ef = new DefaultEmbeddingFunction();
Collection collection = client.createCollection("test-collection", null, true, ef);
List