ChromaStore — Chroma (ChromaDB) vector database
Read this page in the documentation
ChromaStore — Chroma (ChromaDB) vector database Overview Chroma (ChromaDB) is an embedding database organized around collections. A collection holds records that are { id, embedding, metadata?, document? } tuples, and the core operation is an approximate-nearest-neighbor query over a collection's embeddings (optionally narrowed by a metadata where filter) — not SQL, not joins, not a transaction log. None of that fits the SQL-shaped Dialect interface used by the SQL dialects in this repo, so ChromaStore implements the minimal NoSqlStore marker interface (src/nosql/store.ts) — connection lifecycle plus a getClient() escape hatch — and exposes Chroma's real collection- and embedding-level operations directly. Every embedding-level method takes a collection name; the underlying Collection handle is resolved (and cached) via client.getOrCreateCollection(...) so callers never have to thread a collection object through by hand. Identity: Property | Value | --------- | ------------ | name | 'chroma' | library | 'chromadb' | Lazy loading — not a hard dependency The chromadb driver is not a hard dependency of this package. It is loaded lazily via require('chromadb') inside connect() rather than a top-level import, so importing this module does not require the driver to be installed — it is only needed when a Chroma store is actually connected without an injected client. The client talks to Chroma's HTTP API and is stateless, so connect()/disconnect() construct/discard the client rather than opening a real socket. Injected client ChromaStoreOptions.client accepts a pre-built ChromaClient (typed as ChromaClientLike). When provided, connect() skips the require('chromadb') / new ChromaClient(...) step and uses it directly. This is how the test suite injects a mock client (no driver, no network). Connection Build a store from connection options and call connect(). path is the base URL of the Chroma server and is forwarded to new ChromaClient({ path }); any other ChromaClient option passes through unchanged. Option | Type | Purpose | -------- | ------------------ | ------------------------------------------------------------------- | path | string | Base URL of the Chroma server (e.g. http://localhost:8000). | client | ChromaClientLike | A pre-built ChromaClient to use directly (mock or custom config). | [key] | unknown | Any other option accepted by new ChromaClient(...). | Injected-client form Methods Every operation goes through an internal exec() wrapper: driver failures are wrapped in a DatabaseError (preserving the original error, prefixed e.g. Chroma QUERY failed: ...); using any method before connect() (or after disconnect()) throws a ConnectionError. Lifecycle Method | Signature | Behavior | ------------ | ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | connect | connect(): Promise<void> | Uses an injected client if provided, otherwise lazy-requires chromadb and builds new ChromaClient({ path }). Wraps failures in ConnectionError (mapping ECONNREFUSED/fetch failed to a 'Connection refused' message). Idempotent when already connected. | disconnect | disconnect(): Promise<void> | Drops the client reference and clears the cached collection handles. | isConnected| isConnected(): boolean | true only when connected and a client is present. | getClient | getClient(): ChromaClientLike | Returns the underlying ChromaClient. Throws ConnectionError if not connected. | Collection management Method | Signature | Behavior | ----------------------- | -------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | createCollection | createCollection(name: string, options?: CollectionOptions): Promise<ChromaCollectionLike> | Create a new collection (fails if one with name already exists) and cache its handle. options (e.g. { metadata }) is spread into the create call. | getOrCreateCollection | getOrCreateCollection(name: string, options?: CollectionOptions): Promise<ChromaCollectionLike> | Get an existing collection, creating it if absent. Idempotent. Caches the handle. | deleteCollection | deleteCollection(name: string): Promise<unknown> | Delete a collection and all of its embeddings, and drop its cached handle. | Embedding data plane Each of these resolves (and caches) the named collection via getOrCreateCollection before delegating to the collection handle. Method | Signature | Behavior | ------------------ | -------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | addEmbeddings | addEmbeddings(collection: string, params: AddEmbeddingsParams): Promise<unknown>| Add embeddings to a collection. ids/embeddings (and optional metadatas/documents) are index-aligned parallel arrays. | query | query(collection: string, params: QueryEmbeddingsParams): Promise<unknown> | For each query embedding, find the nResults closest records (optionally narrowed by a where filter). Returns the driver's raw response ({ ids, distances, metadatas, documents, ... }, each an array-per-query-embedding). | get | get(collection: string, params: GetEmbeddingsParams): Promise<unknown> | Fetch records by id (and/or a metadata where filter). | deleteEmbeddings | deleteEmbeddings(collection: string, params: DeleteEmbeddingsParams): Promise<unknown> | Delete records by id (and/or a metadata where filter). | Parameter shapes Example Verification status Unit / mock-verified only. The tests in tests/nosql/chroma.test.ts are fully mock-driven: a fake ChromaClient (with getOrCreateCollection/createCollection/deleteCollection, each returning a collection mock exposing add/query/get/delete spies) is injected via ChromaStoreOptions.client. The real chromadb package is not installed, and there is no live Chroma access and no network in the test run. What this proves: Each collection-management method calls the client with { name, ...options } and maintains the handle cache. Each data-plane method resolves the collection via getOrCreateCollection and forwards its params to the collection handle unchanged, returning the driver's response shape. The collection handle is cached across calls (getOrCreateCollection is invoked once for repeated operations on the same collection). Lifecycle: connecting via an injected client without the driver, disconnect clearing the cache (post-disconnect operations throw ConnectionError), ConnectionError before connect() and from getClient(), and ConnectionError when the driver require()/construction fails. Error handling: driver failures (collection ops, query, delete) wrapped in DatabaseError. What this does not prove: live execution against a real Chroma server. Behavior is verified against the driver's documented contract, not end-to-end over the wire. Related reading All data stores — the full catalogue, grouped by purpose Database types — where this sits among the 22 categories