Fix 'PrismaClient is unable to be run in the browser' in Next.js
By Flavio Copes
Fix the Next.js error PrismaClient is unable to be run in the browser by keeping Prisma on the server: App Router Server Components / Route Handlers, or Pages getStaticProps.
This error means Prisma code ended up in your client-side JavaScript bundle. The fix is to keep the Prisma import and every Prisma call on the server only.
In Next.js 16 the default is the App Router, so that means a Server Component, a Server Action or a Route Handler. On older Pages Router projects, keep Prisma inside getStaticProps() or getServerSideProps() on a page route.
Let me show you how I ran into it.
I ran into this error while working on a Next.js website:
PrismaClient is unable to be run in the browser
I had this page and it all worked fine until I commented one line in my code, in particular in my getStaticProps() method.
In that line I called a method from my Prisma instance, which I imported at the top of the page file.
Why this error happens
Prisma Client talks directly to your database. It opens a connection using your database credentials, and it relies on Node.js APIs to do so.
None of that can happen in the browser. And even if it could, you would be shipping your database credentials to every visitor. So Prisma refuses to run there, and throws this error instead.
Normally you never see it, because Next.js is smart about server-only code. It analyzes what you use on the server and strips that code from the frontend bundle. The Prisma import stays on the server.
But this only works as long as the import is actually used in server-only code.
When I commented out the line in getStaticProps() where I used Prisma, Next.js could no longer tell the import was server-only. It included Prisma in my frontend code, and I got the error.
App Router fix (Next.js 16)
Keep Prisma out of Client Components, the files that start with 'use client'.
First, create one Prisma Client for the whole app in lib/prisma.js. This is the Prisma 7 setup: the generated client lives in the output folder of your schema, and the client needs a driver adapter (here the PostgreSQL one). Install with npm install prisma@7 @prisma/client@7 @prisma/adapter-pg@7 pg, pinning the major because prisma@latest is the Prisma 8 release candidate right now.
import { PrismaPg } from '@prisma/adapter-pg'
import { PrismaClient } from '../generated/prisma/client'
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL })
export const prisma = globalThis.prisma ?? new PrismaClient({ adapter })
if (process.env.NODE_ENV !== 'production') globalThis.prisma = prisma
The globalThis trick keeps a single instance across hot reloads in development. Without it, next dev creates a new client, and a new connection pool, every time it reloads the module.
Then query it inside a Server Component:
import { prisma } from '@/lib/prisma'
export default async function Page() {
const posts = await prisma.post.findMany()
return <pre>{JSON.stringify(posts, null, 2)}</pre>
}
If the data has to be loaded on demand from the browser, move the call into a Route Handler (app/api/posts/route.js) or a Server Action, and let the client receive only the JSON result.
One more way to leak Prisma into the browser: a shared module imports lib/prisma, and a Client Component imports that same module for a type or a helper. Split the file, so the Prisma helpers live in a server-only module and the shared UI bits somewhere else. For a related Prisma deploy gotcha on Vercel, see Prisma Client did not initialize yet.
Pages Router fix (legacy)
The solution was to also comment (or remove) the Prisma import at the top of the file.
The rule is: the import and its usage go together. If you remove the last usage inside getStaticProps(), remove the import too. When you add the usage back, add the import back.
Also remember that getStaticProps() is only called on page routes, the files inside the pages folder. It does not work in other components.
So if this error comes from a component, you can’t fix it there. You have to move the data fetching up to the page route component, run Prisma inside its getStaticProps(), and pass the data down to the component as props.
Another option is to move the Prisma call into an API route, and have the component fetch from that endpoint. Either way, Prisma code only runs on the server.
Want me to talk about your product? You can sponsor this site.
Related posts about next: