Prisma ORM 8 is here.Read the docs

Using extensions

Extensions add database capabilities like vector search, geospatial data, and full-text search to a Prisma ORM project.

An extension is a package that adds a database capability Prisma ORM does not have out of the box: new column types, query operations, and index types, along with the migrations that install the underlying database feature. Vector search, geospatial data, full-text search, typed JSON, and provider-specific integrations are all added through extensions.

Use an extension when you need one of these database features while keeping typed schema declarations, generated TypeScript, migration support, and query helpers in your Prisma ORM project.

To add an extension, install its package and register it in two places: the config and the client. The steps below use pgvector, the vector search extension, as the example. Supabase is wired differently; see the note on the catalog.

1. Install the package

Terminal
bun add @prisma/orm-extension-pgvector

2. Register it in the config

Prisma ORM uses this registration when it emits your contract and plans migrations:

prisma.config.ts
import { definePrismaConfig } from 'prisma/config';
import pgvector from '@prisma/orm-extension-pgvector/control';
import { defineConfig as ormConfig } from '@prisma/orm-postgres/config';

export default definePrismaConfig({
  orm: ormConfig({
    contract: './src/prisma/contract.prisma',
    extensions: [pgvector],
    db: {
      connection: process.env['DATABASE_URL']!,
    },
  }),
});

3. Register it on the client

Prisma ORM uses this registration when your app runs queries: it adds the extension's query operations and value types:

src/prisma/db.ts
import pgvector from '@prisma/orm-extension-pgvector/runtime';
import postgres from '@prisma/orm-postgres/runtime';
import type { Contract } from './contract.d';
import contractJson from './contract.json' with { type: 'json' };

export const db = postgres<Contract>({
  contractJson,
  url: process.env['DATABASE_URL']!,
  extensions: [pgvector],
});

4. Use the new type in your schema

The extension's types are now available in your contract. Declare a vector column with an explicit dimension:

src/prisma/contract.prisma
types {
  Embedding1536 = pgvector.Vector(1536)
}

model Post {
  id        String         @id @default(uuid())
  title     String
  embedding Embedding1536?
}

5. Apply and query

Run npx prisma@latest db init (or db update on an existing database). The extension ships its own migration, so this step runs CREATE EXTENSION IF NOT EXISTS vector for you. If db init reports a contract-space layout violation instead, run npx prisma@latest migration plan once: it writes the extension's baseline migration under migrations/<extension>/, and db init then proceeds. Then query with the operations the extension adds:

src/prisma/similarity-search.ts
const plan = db.sql.public.post
  .select('id', 'title')
  .select('distance', (f, fns) => fns.cosineDistance(f.embedding, queryVector))
  .orderBy((f, fns) => fns.cosineDistance(f.embedding, queryVector), { direction: 'asc' })
  .limit(10)
  .build();

const similar = await db.runtime().query(plan);

pgvector contributes fns.cosineSimilarity alongside fns.cosineDistance. Both take two vector expressions and return a float8; similarity sorts descending where distance sorts ascending.

How the pieces fit

One package, two registrations, one database:

One extension package, two registrations, one databaseStep 1 of 4
db initqueriespgvectorone npm packageprisma-next.config.tsmigrationsdb.tsqueriesPostgreSQL
One package brings everything the extension needs.

Capabilities

Each extension names what it adds under a key like pgvector.cosine. You never write these keys by hand. Registering the extension in the config records them in your contract. Registering it in db.ts provides them at runtime.

The point of this bookkeeping is to fail early:

  • If your contract needs an extension that db.ts does not register, creating the client fails immediately. A query never runs with the extension only partially registered.
  • If the database itself cannot install the extension, db init or db update reports it before your app takes traffic.

Available extensions

Every extension, by Prisma and by the community, is listed in the extension directory with install commands and registration snippets. The table below is generated from the same registry.

NameWhat it addsPackageDatabasesBy
arktype-jsonJSON columns validated by an arktype schema and typed end to end.@prisma/orm-extension-arktype-jsonPostgreSQLPrisma
MongoDBMongoDB support for Prisma ORM: config, runtime, contract authoring, BSON values, and migrations in one package.@prisma/orm-mongoMongoDBPrisma
ParadeDB (experimental)BM25 full-text search indexes.@prisma/orm-extension-paradedbPostgreSQLPrisma
pgvectorVector columns and similarity search for embeddings.@prisma/orm-extension-pgvectorPostgreSQLPrisma
PostGISGeometry columns and geospatial queries such as distance and containment.@prisma/orm-extension-postgisPostgreSQLPrisma
PostgreSQLPostgreSQL support for Prisma ORM: config, runtime, contract authoring, and migrations in one package.@prisma/orm-postgresPostgreSQLPrisma
SQLite (experimental)SQLite support for Prisma ORM: config, runtime, contract authoring, and migrations in one package.@prisma/orm-sqliteSQLitePrisma
Supabase (experimental)Supabase auth and storage tables plus role-bound clients for row-level security.@prisma/orm-extension-supabasePostgreSQLPrisma
IndexedDB (experimental)Prisma 8 for IndexedDB: a browser database from your PSL schema, with typed accessors and explicit migrations.@prisma-next-idb/client-idbIndexedDBPrisma IDB
typed-jsonTyped JSON and text columns with no validator dependency.prisma-orm-extension-typed-jsonPostgreSQLOmar Dulaimi
zod-jsonTyped JSON columns described and enforced by a zod schema.prisma-orm-extension-zod-jsonPostgreSQLOmar Dulaimi

The database packages are extensions too: @prisma/orm-postgres, @prisma/orm-sqlite, and @prisma/orm-mongo plug the SQL and document families into the same core, which is how a community package can add another database. Experimental extensions work but their surface is still moving: ParadeDB supports the key_field index option only so far, and SQLite is published but not yet covered by a quickstart. Names link to each extension's directory page, which links on to the package README. Middleware is listed on How middleware works.

For a working project per extension, see the runnable examples: pgvector, PostGIS, ParadeDB, and Supabase.

You can build an extension that does not exist yet. Extension packs are versioned npm packages with a documented layout; the call for extension authors explains how to write and publish one. When it is on npm, submit it to the directory: the form validates the entry and opens the pull request for you.

See also

On this page