@molecule/api-ai-vector-store-pgvector
Provider bond · ai-vector-store · API (Node) · v1.0.2 · Apache-2.0
PostgreSQL pgvector provider for molecule.dev — vector similarity search with pgvector
npm install @molecule/api-ai-vector-store-pgvectornpm · Source on GitHub · Implements @molecule/api-ai-vector-store
How it works
@molecule/api-ai-vector-store-pgvector is a provider bond on the API (Node) side: it implements the ai-vector-store core interface (@molecule/api-ai-vector-store) with a concrete vendor or library behind it.
Your code calls the core; you wire this provider once at startup. Swapping vendors later is one line in that wiring, not a rewrite.
import { setProvider, requireProvider } from '@molecule/api-ai-vector-store'
import { provider } from '@molecule/api-ai-vector-store-pgvector'
setProvider(provider) // at startup — lazy; reads DATABASE_URL / opens its pool on first use
// or pass explicit config: setProvider(createProvider({ connectionString }))Works with: @molecule/api-ai-vector-store
Live demos
Running apps built with Molecule that install this package — open the app or study the template.
Reference
PostgreSQL pgvector vector store provider for molecule.dev.
Stores each molecule collection as its own Postgres table (default prefix
mol_vectors_) with HNSW indexes, using the pgvector extension.
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
Quick Start
import { setProvider, requireProvider } from '@molecule/api-ai-vector-store'
import { provider } from '@molecule/api-ai-vector-store-pgvector'
setProvider(provider) // at startup — lazy; reads DATABASE_URL / opens its pool on first use
// or pass explicit config: setProvider(createProvider({ connectionString }))
Type
provider
Installation
npm install @molecule/api-ai-vector-store-pgvector @molecule/api-ai-vector-store pg pgvector
npm install -D @types/pg
API
Interfaces
PgvectorConfig
Configuration for the pgvector vector store provider.
interface PgvectorConfig {
/** PostgreSQL connection string (e.g. `postgresql://user:pass@host:5432/db`). Falls back to `DATABASE_URL` env var. */
connectionString?: string
/** Schema to use for vector store tables. Defaults to `'public'`. */
schema?: string
/** Table name prefix for vector store tables. Defaults to `'mol_vectors_'`. */
tablePrefix?: string
/** Default distance metric for new collections. Defaults to `'cosine'`. */
defaultMetric?: DistanceMetric
/** Connection pool size. Defaults to 5. */
poolSize?: number
}
Functions
clampTopK(value)
[M7-2] Coerce a requested topK into a bounded positive integer for SAFE interpolation into
the LIMIT clause (it is not a bound $N parameter). topK is typed number, but a caller
forwarding an untrusted value (e.g. req.body.topK cast to any) could otherwise inject SQL
or request an unbounded scan. Non-finite / < 1 falls back to the default 10; capped at 10_000.
function clampTopK(value: unknown): number
value— The caller-suppliedtopK(untyped at runtime).
Returns: A safe integer in [1, 10000].
createProvider(config)
Creates a pgvector vector store provider instance.
function createProvider(config?: PgvectorConfig): PgvectorProvider
config— PostgreSQL + pgvector configuration.
Returns: An AIVectorStoreProvider backed by PostgreSQL with pgvector.
Constants
provider
The provider implementation.
const provider: AIVectorStoreProvider
Core Interface
Implements @molecule/api-ai-vector-store interface.
Bond Wiring
Setup function to register this provider with the core interface:
import { setProvider } from '@molecule/api-ai-vector-store'
import { provider } from '@molecule/api-ai-vector-store-pgvector'
export function setupAiVectorStorePgvector(): void {
setProvider(provider)
}
Injection Notes
Requirements
Peer dependencies:
@molecule/api-ai-vector-store>=1.0.1
Runtime Dependencies
-
@molecule/api-ai-vector-store -
pg -
pgvector -
Owns its own
pg.Pool— it does NOT go through the@molecule/api-databasebond. Connection comes fromconfig.connectionStringor theDATABASE_URLenv var;poolSize(default 5) is independent of the app's database pool. -
Requires the pgvector extension. On first use it runs
CREATE EXTENSION IF NOT EXISTS vector— the connecting role must be allowed to create extensions, otherwise installvectorup front via a migration/DBA. -
Auto-creates its tables: a
mol_vectors_collectionsregistry plus onemol_vectors_<collection>table (+ HNSW index) per collection — no migration needed beyond the extension.topKis clamped to [1, 10000] before hitting SQL.
E2E Tests
Integration checklist — drive the real flow (no mocks): upsert real
vectors, run real query calls, and verify through the FEATURE this store
powers (semantic search / RAG retrieval / related-items) plus direct property
checks on the returned VectorSearchResult[]. Adapt each item to this app's
actual corpus/screens and check every box off. A box you can't check is an
integration bug to fix — not a skip:
-
upsertrecords (each with a stableid+metadata), thenquerywith an embedding: results come back ranked byscore(highest first), the semantically closest stored item is result #1 and unrelated items rank lower — the whole point.scoreis a sane similarity (bounded, ~0–1, higher = closer) and each hit'srecord.id/record.metadatacome back intact. -
topKis honored: a query withtopK: kreturns AT MOST k results, best-first — never more, never unordered. - Metadata
filterworks: aquerycarrying aMetadataFilter(e.g.{ field: 'userId', operator: 'eq', value }) returns only records matching the filter and never leaks non-matching ones. - Collection/namespace ISOLATION: a
queryscoped to onecollectionnever returns another collection's vectors — the multi-tenant boundary that keeps one user's private docs out of another's results. Confirm with two collections (or two owner ids) that a scoped query returns only its own. -
deleteremoves a record: afterdelete({ collection, ids })the vector stops appearing inqueryresults (andfetchomits it). - The feature built on the store returns MEANING-ranked results
end-to-end in the UI — a semantic-search / RAG / related-items query
surfaces the relevant items first, not a keyword or insertion-order match.
This store does NOT embed text itself, so confirm it composes with
@molecule/api-ai-embeddings(query text → embedding →query). - Every
upsert/queryruns SERVER-SIDE — the provider/store key stays on the server and never ships in the browser bundle (the package is server-only; a client import throws by design).