❌ PrismaClient is unable to run in this browser environment

잭슨·2025년 5월 14일

트러블슈팅

목록 보기
8/9

🧩 배경

Auth.js의 Prisma Adapter를 사용하는 중에 아래와 같은 에러가 발생했다.

[auth][cause]: Error: PrismaClient is unable to run in this browser environment, or has been bundled for the browser (running in ``).
If this is unexpected, please open an issue: https://pris.ly/prisma-prisma-bug-report
    at Object.get (E:\investor\.next\server\edge\chunks\[root-of-the-server]__47045e83._.js:1287:23)
    ...

⚙️ 환경 정보

@auth/prisma-adapter: "^2.7.4",
@prisma/client: "^6.7.0",
next: "15.3.0",
next-auth: "5.0.0-beta.27",

🔍 에러 원인 분석

💡 요약

  • Prisma Client는 브라우저 또는 Edge 런타임에서 실행될 수 없다.
  • 현재 코드가 Edge 런타임에서 실행되고 있어 에러가 발생함.

📎 상세 분석

  • Edge Runtime 환경에서의 실행 → 에러 스택 상 경로가 .next/server/edge/로 시작됨.
  • Prisma Client는 Edge 환경과 호환되지 않음 → Prisma는 Node.js API에 의존하므로 Node.js API를 제공하지 않는 Edge 런타임에서는 동작하지 않음.
  • Next.js의 기본 동작middleware.ts나 일부 route handler는 기본적으로 Edge 런타임에서 실행됨.

✅ 해결 방법

  1. Node.js 런타임으로 강제 지정하기

    export const runtime = "nodejs"

    → 인증 관련 API 라우트, middleware.ts 등에서 설정.

  2. Edge 호환 adapter 사용

    → Prisma 대신 Edge-compatible adapter 사용 고려.

🌐 Edge 런타임이란?

✴️ Edge란?

  • 원래는 네트워크의 가장자리를 뜻함.
  • 사용자의 지리적 위치와 가까운 서버를 말함.
  • 데이터센터 중심부의 고성능 서버보다는 덜 강력한 하드웨어를 사용함.

✅ 장점:

  • 낮은 지연 시간(Latency)
  • 뛰어난 확장성(scalability)
  • 효율적인 비용 구조

❌ 단점:

  • 제한된 하드웨어 성능
  • Node.js API 미지원 등 소프트웨어 호환성 이슈

⚠️ Edge 런타임과 Node.js의 차이

항목Edge RuntimeNode.js
런타임 목적빠른 응답, 지리적으로 가까운 실행범용 서버 환경
지원 API제한적 (ex. fs, net, tls 등 미지원)완전한 Node.js API 지원
사용 사례Middleware, 캐시 응답DB 처리, 복잡한 서버 로직

❓ 내 코드는 왜 Edge 런타임에서 실행됐을까?

나는 별도로 Edge 런타임을 설정한 적이 없는데, 왜 실행됐을까?

📚 Next.js 공식 문서 확인 결과:

“Middleware에서는 기본적으로 Edge 런타임이 적용됩니다.”

문서 링크 →

🧠 코드 구조와 에러 발생 경로 분석

// middleware.ts
import { auth } from "./auth";

export default auth(async function middleware(req) {
  // ...
});
  • authNextAuth(authConfig)의 반환값
  • authConfig에는 prismaAdapter가 포함됨
  • prismaAdapter 의 인자로 전달된 prisma 인스턴스는 PrismaClient 에 의해 생성됨

🔗 결국: PrismaClientmiddleware와 함께 번들링 → Edge 런타임에서 실행 → 에러 발생

📘 공식 문서에서도 명시된 Prisma의 Edge 호환성 제한

이 외에도 Auth.js 의 공식 문서에도 Prisma사용 시 Edge 호환성에 대해 언급되어있었다.

Prisma는 v5.12.0부터 일부 Edge 환경을 지원하지만, 모든 데이터베이스/호스팅 환경에서 호환되지는 않음.

✅ 참고 링크:

💡 1. Edge 환경에서 Prisma 사용 우회 방법

현재 Prisma는 Edge 환경을 공식 지원하지 않는다. 다만 다음과 같은 우회 방법을 통해 사용할 수 있다:

✅ 우회 방법 요약

방법설명
Prisma Accelerate 사용글로벌 커넥션 풀링과 캐싱을 제공. Edge 환경에서도 안정적인 쿼리 수행 가능.
JWT 세션 전략 + Auth 설정 분리Edge Compatibility 가이드를 따라 auth.ts 파일을 Edge/Node 전용으로 분리. PrismaClient는 Node 환경에서만 호출.
Node.js 런타임 미들웨어 사용 (Next.js v15.2~)미들웨어에 Node 런타임을 지정하는 실험적 기능. 아직 안정적이지 않음.

🔗 관련 링크:

🔒 Prisma 5.9.1 이상에서의 주의사항

  • @prisma/client@5.9.1부터는 인스턴스화 시점이 아닌 쿼리 실행 시점에 에러 발생.
  • 따라서 미들웨어에서 PrismaClient를 import하는 건 가능하지만, 쿼리를 실행하면 에러 발생.

🚀 2. Prisma Accelerate + Prisma Postgres 사용 배경

나는 Accelerate를 사용하는 방법을 선택했다. 나는 Supabase를 사용 중이었고, 기존 DB에 Accelerate만 활성화하려고 했지만 그럴려면 database direct connection string이 필요했다.

Supabase에서 유료 플랜에서만 direct connection string 제공 했기 때문에 기존 DB에 Accelerate만 추가하는 것은 어려웠다.

그러나 Prisma Postgres를 사용하면 Accelerate가 기본 번들링되어 무료 티어에서도 충분히 Accelerate를 사용할 수 있기 때문에 DB를 Supabase에서 Prisma Postgres로 이관하기로 결정 했다.

🔍 3. Prisma Postgres란?

Prisma에서 제공하는 관리형 PostgreSQL 서비스.

주요 특징:

  • Always-on: 콜드 스타트 없음
  • 글로벌 커넥션 풀링 및 캐싱 기본 탑재
  • 10만 쿼리/월 무료
  • Unikernel, MicroVM 기반 고성능
  • Prisma Accelerate, Optimize 완전 통합

🔗 자세히 보기:

⚡ 4. Prisma Accelerate란?

Prisma ORM에 통합되는 커넥션 풀링 + 글로벌 캐싱 계층. 특징:

  • 15개 리전에 커넥션 풀 배치
  • 300개 이상 엣지 노드에서 쿼리 캐싱
  • 캐싱 전략 (TTL, SWR) 직접 설정 가능
  • 서버리스/엣지 환경 최적화

📦 설치 예시:

import { PrismaClient } from '@prisma/client'
import { withAccelerate } from '@prisma/extension-accelerate'

const prisma = new PrismaClient().$extends(withAccelerate())

const users = await prisma.user.findMany({
  cacheStrategy: {
    ttl: 30,
    swr: 60
  }
})

🔗 Accelerate 공식 문서

🛠️ 5. 기존 DB에서 Prisma Postgres로 마이그레이션

✅ 사전 준비

항목상태
Supabase Connection URL확보 완료
Prisma Data Platform 계정가입 완료
Node.js 18+설치 완료
PostgreSQL CLI (pg_dump, pg_restore)설치 및 환경변수 등록 완료 (→ 설치 방법은 아래에서 자세히 설명)

🧱 1단계: Prisma Postgres 생성

  1. Prisma Data Platform 접속

  2. New Project > 이름 입력

  3. Prisma Postgres 선택 > Get started

  4. Region은 한국과 가까운 Asia Pacific (Tokyo) 선택

  5. Create project 클릭

📤 2단계: 기존 DB 데이터 덤프 추출

기존 DB에 있던 데이터를 로컬에 저장하자.

pg_dump -Fc -v -d postgresql://USER:PASSWORD@HOST:PORT/DATABASE -n public -f db_dump.bak
  • postgresql://USER:PASSWORD@HOST:PORT/DATABASE 에 기존 DB의 connection URL 입력
  • pg_dump.bak 파일로 DB를 로컬에 저장하는 명령어
  • PostgreSQL CLI가 없다면 설치 가이드 참고하여 OS에 맞게 설치 및 환경 변수 세팅 (환경변수를 설정한 뒤에 열려있는 cmd 창을 닫았다가 다시 열어줘야 환경 변수가 적용된다.)
  • 설치 후 pg_dump --version 명령어로 정상 작동 확인

📥 3단계: Prisma Postgres로 데이터 import

로컬에 설치한 db_dump.bak 파일을 Prisma Postgres로 불러오자.

✅필요한 정보

  • Prisma Postgres의 DATABASE_URL (prisma+postgres://...)
  • API_KEY는 Prisma 프로젝트의 Setup 탭에서 복사

이 단계에선 TCP tunnel 을 이용해서 Prisma Postgres를 연결하고 pg_restore 를 통해 데이터를 불러와야 한다.

만약에 현재 디렉토리(cli 명령어를 실행시키는 디렉토리)에 .env 파일이 이미 있고 DATABASE_URL 환경변수에 해당 connection URL이 설정되어있다면 tunnel CLI는 자동으로 이를 사용할 것이다.

다음 명령어를 통해 TCP tunnel 을 실행시키자.

npx @prisma/ppg-tunnel --host 127.0.0.1 --port 5433 

위와 같은 결과가 출력되면 잘 연결된 것이다. 그런 다음 현재 TCP tunnel이 실행되고 있는 cmd창은 그대로 유지하고 cmd 창을 하나 더 열어서 다음 명령어를 수행해주자.

PGSSLMODE=disable
pg_restore -h 127.0.0.1 -p 5433 -v -d postgres ./db_dump.bak

만약 Power Shell을 사용중이라면 PGSSLMODE가 없는 명령어라며 에러가 뜰 것인데, 이땐 다음과 같이 입력해주면 된다.

$env:PGSSLMODE = "disable"
pg_restore -h 127.0.0.1 -p 5433 -v -d postgres ./db_dump.bak

PGSSLMODE는 Postgres에서 SSL 모드를 사용할지 말지 결정하는 환경변수다.

위 명령이 정상적으로 수행되었다면 Prisma Postgres의 Studio 탭에서 데이터가 업로드되어 테이블이 생성된 것을 확인할 수 있을 것이다.

🛠️ 4. Prisma Postgres에 맞게 코드 수정하기

기존에 Prisma ORM을 사용하고 있다면, Prisma Postgres 및 Accelerate 환경에 맞게 프로젝트 설정을 업데이트해야 한다.

✅ 1. Prisma Accelerate 패키지 설치

Prisma Accelerate는 Prisma Postgres를 사용할 때 필수적이다.

먼저, 아래 명령어로 패키지를 설치하자.

npm install @prisma/client@latest @prisma/extension-accelerate

이렇게 하면 최신 Prisma Client와 Accelerate 확장 기능이 함께 프로젝트에 추가된다.

✅ 2. DATABASE_URL 환경 변수 수정

schema.prisma 파일의 datasource 블록의 url 필드에 등록된 env("DATABASE_URL") 은 환경 변수 DATABASE_URL을 참조한다. 따라서 환경 변수를 수정해주자.

DATABASE_URL="prisma+postgres://accelerate.prisma-data.net/?api_key=__API_KEY__"
  • __API_KEY__: 아까 Prisma Postgres 프로젝트 생성할 때 API 키

schema.prisma의 구조는 다음과 같이 유지한다:

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

✅ 3. Prisma Client 재생성

📦 일반 환경 (Node.js 서버 등)

npx prisma generate

🌐 Edge 환경 또는 서버리스 환경 (Cloudflare, Vercel Edge 등)

npx prisma generate --no-engine
  • -no-engine: Query 엔진 파일 생성을 막아 번들 사이즈를 최소화
  • Edge 환경에서 PrismaClient의 Query Engine이 작동하지 않음

✅ 4. Prisma Client 인스턴스 확장

Prisma Accelerate 기능을 사용하려면 Prisma Client 인스턴스를 확장해야 한다.

운영 환경에 따라 다음 중 하나를 선택한다.

🧠 일반 환경 (Node.js)

import { PrismaClient } from '@prisma/client'
import { withAccelerate } from '@prisma/extension-accelerate'

const prisma = new PrismaClient().$extends(withAccelerate())

⚡ Edge 환경 (Cloudflare Workers, Vercel Edge Functions 등)

import { PrismaClient } from '@prisma/client/edge'
import { withAccelerate } from '@prisma/extension-accelerate'

const prisma = new PrismaClient().$extends(withAccelerate())

✅ 이렇게 하면 PrismaClient is unable to run in this browser environment 에러를 방지할 수 있다.

🔗 참고 자료

profile
지속적인 성장

0개의 댓글