docs/config/extensions/prismaExtension.mdx
The prismaExtension supports multiple Prisma versions and deployment strategies through three distinct modes that handle the evolving Prisma ecosystem, from legacy setups to Prisma 7.
import { prismaExtension } from "@trigger.dev/build/extensions/prisma";
extensions: [
prismaExtension({
schema: "prisma/schema.prisma",
migrate: true,
typedSql: true,
directUrlEnvVarName: "DATABASE_URL_UNPOOLED",
}),
];
import { prismaExtension } from "@trigger.dev/build/extensions/prisma";
extensions: [
prismaExtension({
mode: "legacy", // MODE IS REQUIRED
schema: "prisma/schema.prisma",
migrate: true,
typedSql: true,
directUrlEnvVarName: "DATABASE_URL_UNPOOLED",
}),
];
Use this decision tree to determine which mode is right for your project:
flowchart TD
Start([Which mode should I use?]) --> Q1{Using Prisma 7 or
6.20+ beta?}
Q1 -->|Yes| Modern[Modern Mode]
Q1 -->|No| Q2{Using Prisma 6.16+
with engineType='client'?}
Q2 -->|Yes| Modern
Q2 -->|No| Q3{Need custom client
output path?}
Q3 -->|Yes| Q4{Want to manage
prisma generate yourself?}
Q4 -->|Yes| Engine[Engine-only Mode]
Q4 -->|No| Legacy[Legacy Mode]
Q3 -->|No| Legacy
Modern -->|Features| ModernFeatures["• Zero configuration
• Database adapters
• Plain TypeScript (no binaries)
• You manage generation"]
Engine -->|Features| EngineFeatures["• Only installs engines
• Auto version detection
• You manage generation
• Minimal overhead"]
Legacy -->|Features| LegacyFeatures["• Auto prisma generate
• Migrations support
• TypedSQL support
• Config file support"]
style Modern fill:#10b981,stroke:#059669,color:#fff
style Engine fill:#3b82f6,stroke:#2563eb,color:#fff
style Legacy fill:#8b5cf6,stroke:#7c3aed,color:#fff
Use when: You're using Prisma 6.x or earlier with the prisma-client-js provider.
Features:
prisma generate during deploymentprisma/schema.prisma)prisma.config.ts) via @prisma/config packagemigrate: truetypedSql: trueSchema configuration:
generator client {
provider = "prisma-client-js"
previewFeatures = ["typedSql"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
directUrl = env("DATABASE_URL_UNPOOLED")
}
Extension configuration:
// Single-file schema
prismaExtension({
mode: "legacy",
schema: "prisma/schema.prisma",
migrate: true,
typedSql: true,
directUrlEnvVarName: "DATABASE_URL_UNPOOLED",
});
// Multi-file schema (Prisma 6.7+)
prismaExtension({
mode: "legacy",
schema: "./prisma", // Point to directory
migrate: true,
typedSql: true,
directUrlEnvVarName: "DATABASE_URL_UNPOOLED",
});
Tested versions:
Use when: You have a custom Prisma client output path and want to manage prisma generate yourself.
Features:
@prisma/clientprisma generate runsSchema configuration:
generator client {
provider = "prisma-client-js"
output = "../src/generated/prisma"
// Ensure the "debian-openssl-3.0.x" binary target is included for deployment to the trigger.dev cloud
binaryTargets = ["native", "debian-openssl-3.0.x"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
directUrl = env("DATABASE_URL_UNPOOLED")
}
Extension configuration:
// Auto-detect version
prismaExtension({
mode: "engine-only",
});
// Explicit version (recommended for reproducible builds)
prismaExtension({
mode: "engine-only",
version: "6.19.0",
});
Important notes:
prisma generate yourself (typically in a prebuild script)binaryTargets for deployment to the trigger.dev cloud. The binary target is debian-openssl-3.0.x.PRISMA_QUERY_ENGINE_LIBRARY and PRISMA_QUERY_ENGINE_SCHEMA_ENGINE environment variables to the correct paths for the binary targets.package.json example:
{
"scripts": {
"prebuild": "prisma generate",
"dev": "trigger dev",
"deploy": "trigger deploy"
}
}
Tested versions:
Use when: You're using Prisma 6.16+ with the new prisma-client provider (with engineType = "client") or preparing for Prisma 7.
Features:
@prisma/client as externalSchema configuration (Prisma 6.16+ with engineType):
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
engineType = "client"
previewFeatures = ["views"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
directUrl = env("DATABASE_URL_UNPOOLED")
}
Schema configuration (Prisma 7):
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
datasource db {
provider = "postgresql"
}
Extension configuration:
prismaExtension({
mode: "modern",
});
Prisma config (Prisma 7):
// prisma.config.ts
import { defineConfig, env } from "prisma/config";
import "dotenv/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
Important notes:
prisma generate yourself.prisma-client provider generates plain TypeScript (no Rust binaries)@prisma/adapter-pg for PostgreSQL)Tested versions:
engineType = "client"If you were using the previous prismaExtension, migrate to legacy mode:
// Old
prismaExtension({
schema: "prisma/schema.prisma",
migrate: true,
});
// New - add mode
prismaExtension({
mode: "legacy",
schema: "prisma/schema.prisma",
migrate: true,
});
If you want to adopt the new Prisma architecture, use modern mode:
prisma-client providerprismaExtension({
mode: "modern",
});
When using modern and engine-only modes, you'll need to ensure that you run prisma generate yourself before deploying your project.
If you are deploying your project using GitHub Actions, you can add a step to your workflow to run prisma generate before deploying your project, for example:
steps:
- name: Generate Prisma client
run: npx [email protected] generate
- name: Deploy Trigger.dev
run: npx [email protected] deploy
env:
TRIGGER_ACCESS_TOKEN: ${{ secrets.TRIGGER_ACCESS_TOKEN }}
If you are using the Trigger.dev Github integration, you can configure a pre-build command to run prisma generate before deploying your project. Navigate to your project's settings page and configure the pre-build command to run prisma generate, for example:
| Prisma version | Recommended mode | Notes |
|---|---|---|
| < 5.0 | Legacy | Older Prisma versions |
| 5.0 - 6.15 | Legacy | Standard Prisma setup |
| 6.7+ | Legacy | Multi-file schema support |
| 6.16+ | Engine-only or Modern | Modern mode requires engineType = "client" |
| 6.20+ (7.0 beta) | Modern | Prisma 7 with new architecture |
Legacy mode supports loading configuration from a prisma.config.ts file using the official @prisma/config package.
Use when: You want to use Prisma's new config file format (Prisma 6+) to centralize your Prisma configuration.
Benefits:
prisma.config.ts:
import { defineConfig, env } from "prisma/config";
import "dotenv/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
directUrl: env("DATABASE_URL_UNPOOLED"),
},
});
trigger.config.ts:
import { prismaExtension } from "@trigger.dev/build/extensions/prisma";
prismaExtension({
mode: "legacy",
configFile: "./prisma.config.ts", // Use config file instead of schema
migrate: true,
directUrlEnvVarName: "DATABASE_URL_UNPOOLED", // For migrations
});
What gets extracted:
schema - The schema file or directory pathmigrations.path - The migrations directory path (if specified)Note: Either schema or configFile must be specified, but not both.
When to use which:
Use schema option | Use configFile option |
|---|---|
| Standard Prisma setup | Using Prisma 6+ with config files |
| Single or multi-file schemas | Preparing for Prisma 7 |
No prisma.config.ts file | Centralized configuration needed |
| Simple setup | Want migrations path in config |
Prisma 6.7 introduced support for splitting your schema across multiple files in a directory structure.
Example structure:
prisma/
├── schema.prisma (main file with generator/datasource)
├── models/
│ ├── users.prisma
│ └── posts.prisma
└── sql/
└── getUserByEmail.sql
Configuration:
prismaExtension({
mode: "legacy",
schema: "./prisma", // Point to directory instead of file
migrate: true,
typedSql: true,
});
package.json:
{
"prisma": {
"schema": "./prisma"
}
}
TypedSQL is available in legacy mode for Prisma 5.19.0+ with the typedSql preview feature.
Schema configuration:
generator client {
provider = "prisma-client-js"
previewFeatures = ["typedSql"]
}
Extension configuration:
prismaExtension({
mode: "legacy",
schema: "prisma/schema.prisma",
typedSql: true, // Enable TypedSQL
});
Usage in tasks:
import { db, sql } from "./db";
const users = await db.$queryRawTyped(sql.getUserByEmail("[email protected]"));
Migrations are supported in legacy mode only.
Extension configuration:
// Using schema option
prismaExtension({
mode: "legacy",
schema: "prisma/schema.prisma",
migrate: true, // Run migrations on deployment
directUrlEnvVarName: "DATABASE_URL_UNPOOLED", // For connection pooling
});
// Using configFile option
prismaExtension({
mode: "legacy",
configFile: "./prisma.config.ts", // Migrations path extracted from config
migrate: true,
});
What this does:
prisma/migrations/ to the build outputprisma migrate deploy before generating the clientdirectUrlEnvVarName for unpooled connections (required for migrations)When using configFile, the migrations path is automatically extracted from your prisma.config.ts:
// prisma.config.ts
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations", // Automatically used by the extension
},
});
The default binary target is debian-openssl-3.0.x for Trigger.dev Cloud deployments.
Legacy mode: Handled automatically
Engine-only mode: Specify in schema like so:
generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "debian-openssl-3.0.x"]
}
Modern mode: Handled by database adapters
For local deployments (e.g., Docker on macOS), you may need a different binary target like so:
prismaExtension({
mode: "engine-only",
version: "6.19.0",
binaryTarget: "linux-arm64-openssl-3.0.x", // For macOS ARM64
});
All modes:
DATABASE_URL: Your database connection stringLegacy mode with migrations:
DATABASE_URL_UNPOOLED (or your custom directUrlEnvVarName): Direct database connection for migrationsEngine-only mode sets:
PRISMA_QUERY_ENGINE_LIBRARY: Path to the query enginePRISMA_QUERY_ENGINE_SCHEMA_ENGINE: Path to the schema engineLegacy mode: Ensure the schema path is correct relative to your working directory.
// If your project structure is:
// project/
// trigger.config.ts
// prisma/
// schema.prisma
prismaExtension({
mode: "legacy",
schema: "./prisma/schema.prisma", // Correct
// schema: "prisma/schema.prisma", // Also works
});
The extension includes improved version detection that tries multiple strategies:
@prisma/client is imported in your code (externals)version option if specified@prisma/client or prisma in node_modulesLegacy mode: The extension will automatically detect the version from your installed packages. If it still fails, specify the version explicitly:
prismaExtension({
mode: "legacy",
schema: "prisma/schema.prisma",
version: "6.19.0", // Add explicit version
});
Engine-only mode: Specify the version explicitly:
prismaExtension({
mode: "engine-only",
version: "6.19.0", // Add explicit version
});
Engine-only mode: Make sure your schema includes the deployment binary target:
generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "linux-arm64-openssl-3.0.x"]
}
Legacy mode: Make sure typedSql: true is set and you have Prisma 5.19.0+:
prismaExtension({
mode: "legacy",
schema: "prisma/schema.prisma",
typedSql: true, // Required for TypedSQL
});
Legacy mode with configFile: Ensure the config file path is correct:
prismaExtension({
mode: "legacy",
configFile: "./prisma.config.ts", // Path relative to project root
migrate: true,
});
Requirements:
prisma package installed (Prisma 6+)schema pathDebugging:
Use --log-level debug in your trigger deploy command to see detailed logs:
npx trigger.dev@latest deploy --log-level debug
Then grep for [PrismaExtension] in your build logs to see detailed information about config loading, schema resolution, and migrations setup.
prisma/schema.prisma:
generator client {
provider = "prisma-client-js"
previewFeatures = ["typedSql"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
directUrl = env("DATABASE_URL_UNPOOLED")
}
trigger.config.ts:
import { defineConfig } from "@trigger.dev/sdk";
import { prismaExtension } from "@trigger.dev/build/extensions/prisma";
export default defineConfig({
project: process.env.TRIGGER_PROJECT_REF!,
build: {
extensions: [
prismaExtension({
mode: "legacy",
schema: "prisma/schema.prisma",
migrate: true,
typedSql: true,
directUrlEnvVarName: "DATABASE_URL_UNPOOLED",
}),
],
},
});
prisma/schema.prisma:
generator client {
provider = "prisma-client-js"
previewFeatures = ["typedSql"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
directUrl = env("DATABASE_URL_UNPOOLED")
}
prisma/models/users.prisma:
model User {
id String @id @default(cuid())
email String @unique
name String?
posts Post[]
}
prisma/models/posts.prisma:
model Post {
id String @id @default(cuid())
title String
content String
authorId String
author User @relation(fields: [authorId], references: [id])
}
package.json:
{
"prisma": {
"schema": "./prisma"
}
}
trigger.config.ts:
prismaExtension({
mode: "legacy",
schema: "./prisma", // Directory, not file
migrate: true,
typedSql: true,
directUrlEnvVarName: "DATABASE_URL_UNPOOLED",
});
Use a prisma.config.ts file to centralize your Prisma configuration.
prisma.config.ts:
import { defineConfig, env } from "prisma/config";
import "dotenv/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
directUrl: env("DATABASE_URL_UNPOOLED"),
},
});
prisma/schema.prisma:
generator client {
provider = "prisma-client-js"
previewFeatures = ["typedSql"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
directUrl = env("DATABASE_URL_UNPOOLED")
}
model User {
id String @id @default(cuid())
email String @unique
name String?
}
trigger.config.ts:
import { defineConfig } from "@trigger.dev/sdk";
import { prismaExtension } from "@trigger.dev/build/extensions/prisma";
export default defineConfig({
project: process.env.TRIGGER_PROJECT_REF!,
build: {
extensions: [
prismaExtension({
mode: "legacy",
configFile: "./prisma.config.ts", // Load from config file
migrate: true,
typedSql: true,
// schema and migrations path are extracted from prisma.config.ts
}),
],
},
});
src/db.ts:
import { PrismaClient } from "@prisma/client";
export * as sql from "@prisma/client/sql";
export const db = new PrismaClient({
datasources: {
db: {
url: process.env.DATABASE_URL,
},
},
});
prisma/schema.prisma:
generator client {
provider = "prisma-client-js"
output = "../src/generated/prisma"
binaryTargets = ["native", "linux-arm64-openssl-3.0.x"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
directUrl = env("DATABASE_URL_UNPOOLED")
}
package.json:
{
"scripts": {
"generate": "prisma generate",
"dev": "pnpm generate && trigger dev",
"deploy": "trigger deploy"
}
}
trigger.config.ts:
prismaExtension({
mode: "engine-only",
version: "6.19.0",
binaryTarget: "linux-arm64-openssl-3.0.x",
});
src/db.ts:
import { PrismaClient } from "./generated/prisma/client.js";
export const db = new PrismaClient({
datasources: {
db: {
url: process.env.DATABASE_URL,
},
},
});
prisma/schema.prisma:
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
datasource db {
provider = "postgresql"
}
prisma.config.ts:
import { defineConfig, env } from "prisma/config";
import "dotenv/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
package.json:
{
"dependencies": {
"@prisma/client": "6.20.0-integration-next.8",
"@prisma/adapter-pg": "6.20.0-integration-next.8"
},
"scripts": {
"generate": "prisma generate",
"dev": "pnpm generate && trigger dev",
"deploy": "trigger deploy"
}
}
trigger.config.ts:
prismaExtension({
mode: "modern",
});
src/db.ts:
import { PrismaClient } from "./generated/prisma/client.js";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
});
export const db = new PrismaClient({ adapter });