DEV Community

Cover image for Using Prisma with Next.js and Supabase — What Actually Works (and What Doesn’t)
Mridu Dixit
Mridu Dixit

Posted on

Using Prisma with Next.js and Supabase — What Actually Works (and What Doesn’t)

Next.js, Supabase, and Prisma are often mentioned together — but the integration isn’t always obvious.

Should you use Supabase as a database, as auth only, or both?
Where does Prisma fit when Supabase already exposes Postgres?

Let’s clear the confusion and look at real-world usage patterns.

The Real Roles (Clear This First)

🔹 Supabase

  • Managed PostgreSQL
  • Authentication (JWT-based)
  • Realtime, Storage, Edge Functions
  • Auto-generated REST & GraphQL APIs

🔹 Prisma

  • Type-safe ORM
  • Schema-driven data modeling
  • Migrations
  • Excellent DX for complex queries

🔹 Next.js

  • App Router / Server Actions
  • API routes
  • SSR / SSG / ISR
  • Backend + frontend in one app

👉 Supabase ≠ Prisma replacement
👉 Prisma ≠ Auth provider

They solve different problems.

Most Common (and Best) Architecture

Supabase for:

  • PostgreSQL hosting
  • Authentication
  • Row Level Security (RLS)
  • Storage

Prisma for:

  • Database access
  • Complex queries
  • Business logic
  • Type safety

Next.js for:

  • UI
  • Server Actions
  • API orchestration
  • This combo gives you control + safety + speed.

How Prisma Connects to Supabase

Supabase is just Postgres under the hood.

You connect Prisma using the direct database URL:

DATABASE_URL="postgresql://user:password@db.supabase.co:5432/postgres"

Enter fullscreen mode Exit fullscreen mode

Then define your Prisma schema normally:

model User {
  id        String   @id @default(uuid())
  email     String   @unique
  createdAt DateTime @default(now())
}

Enter fullscreen mode Exit fullscreen mode

Run:

npx prisma migrate dev

Enter fullscreen mode Exit fullscreen mode

Prisma migrations work perfectly with Supabase.

Auth: Supabase Auth + Prisma (Important Pattern)

Supabase Auth users live in:

auth.users

Enter fullscreen mode Exit fullscreen mode

Best practice:

  • Do not manage auth users with Prisma
  • Reference auth.users.id in your tables

Example:

model Profile {
  id     String @id
  userId String @unique
  name   String
}

Enter fullscreen mode Exit fullscreen mode

Then sync on signup using:

  • Supabase Edge Functions
  • Next.js Server Actions
  • Webhooks

Row Level Security (RLS) vs Prisma — The Tradeoff

⚠️ Important Truth

Prisma bypasses Supabase RLS when using the service role or DB URL.

That means:

  • RLS does not protect Prisma queries
  • You must enforce authorization in your backend

Best Practice:

  • Use Prisma only in server-side code
  • Validate user identity from Supabase JWT
  • Apply access rules in Prisma queries
  • This is why Next.js Server Actions work beautifully here.

When NOT to Use Prisma with Supabase

❌ If you only need simple CRUD
❌ If you rely heavily on Supabase auto-generated APIs
❌ If you want RLS to handle all security

In these cases, Supabase client SDK alone may be enough.

When Prisma + Supabase Is a Power Combo

✅ Complex relational queries
✅ Non-trivial business logic
✅ Multi-tenant apps
✅ Admin dashboards
✅ Type safety across backend

This is where Prisma shines.

Performance & DX Benefits

  • Prisma gives compile-time safety
  • Supabase gives infra + auth
  • Next.js gives full-stack control

You avoid:

  • Raw SQL everywhere
  • Duplicate types
  • Unclear data ownership

Final Verdict

Supabase + Prisma is not redundant — it’s complementary.

Use Supabase as:

Infrastructure + Auth + Platform

Use Prisma as:

Your application’s data layer

Together with Next.js, this stack is:

  • scalable
  • maintainable
  • production-ready

Top comments (0)