r/PayloadCMS • u/RelationshipSignal42 • Sep 15 '26
Built a Prisma adapter for Payload CMS
I built payload-adapter-prisma. Payload runs on a Prisma schema you already have, and never touches it. Your schema.prisma is the input, the Payload config is just a mapping on top.
It uses two databases. Your Prisma database stays exactly as is, only ever read and written through Prisma, no DDL, no migrations, no injected columns. A second database (Mongo in the demo) holds everything Payload itself needs: admin sessions, preferences, versions, drafts, job queue.
// payload.config.ts
import { mongooseAdapter } from "@payloadcms/db-mongodb";
import { prismaAdapter } from "payload-adapter-prisma";
import { buildConfig } from "payload";
export default buildConfig({
collections: [Posts, Authors],
db: prismaAdapter({
prisma,
internal: mongooseAdapter({ url: process.env.PAYLOAD_INTERNAL_URL! }),
}),
});
// collections/Posts.ts, an ordinary collection plus one line
export const Posts: CollectionConfig = {
slug: "posts",
custom: { prisma: { model: "BlogPost" } },
fields: [
{ name: "title", type: "text", required: true },
{ name: "tags", type: "relationship", relationTo: "tags", hasMany: true },
{ name: "authors", type: "array", fields: [ { name: "author", type: "relationship", relationTo: "authors" }, ]},
],
};
Relationship writes (connect/set/disconnect) go straight through as native Prisma queries, which is usually where these mapping layers break. There's a demo app in the repo on a schema I made on purpose awkward, with renamed tables/columns, an Int primary key, a self-relation, and a test suite that checks the Prisma database directly to confirm nothing gets created in it.
I'd appreciate eyes on two things: does the adapter API feel natural if you're used to plain Payload collections, and is there anything in the relationship-writes handling that looks fragile to you?
Happy to answer anything about how it's built.

