엣지 런타임은 fs, crypto, pg 같은 노드 모듈을 열지 못합니다. 로그에 찍힌 모듈을 미들웨어 임포트에서 빼고, 데이터베이스는 노드 라우트로 옮깁니다. 해시는 웹 크립토로 바꿉니다. 개발 서버가 조용해도 배포 번들은 거절할 수 있습니다. Next.js, 미들웨어, 버셀, 한국 1인 개발. 2026년 10월 문서.
엣지 런타임은 노드 내장 모듈을 열지 못합니다. 빌드 로그가 Edge Runtime에서 노드 모듈을 거절하면, 그 줄에 찍힌 모듈을 미들웨어 임포트 사슬에서 빼는 것이 먼저입니다.
로컬 개발 서버는 넘어가는데 버셀 배포만 이 줄에서 멈추는 경우가 있습니다. 카카오 콜백 미들웨어에 토큰 라이브러리나 데이터베이스 드라이버를 넣으면, 한국 프리뷰 빌드가 그 임포트에서 끊깁니다. 화면의 빨간 막만 보고 새로고침하면 같은 임포트가 배포 로그에 그대로 남습니다.
데이터베이스 조회는 노드 런타임 라우트로 옮기고, 서명은 웹 크립토로 바꿉니다. 파일 이름을 바꾸는 일과는 다른 칸입니다. 근거는 넥스트 엣지 런타임의 노드 모듈 오류입니다.
로그에 찍힌 모듈 이름부터
거절된 모듈 이름이 다음 파일의 단서입니다.
넥스트는 로컬에서 어느 파일이 그 모듈을 불러왔는지 콘솔과 브라우저에 보여 줍니다. 배포 로그에도 같은 모듈 이름이 남습니다. fs, net, crypto, pg, jsonwebtoken처럼 보이면 엣지 번들이 노드 전용 코드를 탄 것입니다.
직접 임포트가 아니어도 납니다. 미들웨어가 lib/auth.js를 부르고, 그 파일이 lib/db.js를 부르면 드라이버까지 엣지 그래프에 들어갑니다. 미들웨어 파일만 지우고 헬퍼가 남아 있으면 다음 빌드도 같은 줄입니다. 스택에 찍힌 첫 파일부터 따라 내려가세요.
공식 오류 문서는 프록시 파일과 엣지 라우트가 노드 런타임 기능을 쓸 때 이 일이 생긴다고 적습니다. 2026년 2월 엣지 런타임 문서도 파일 시스템 같은 네이티브 노드는 지원하지 않는다고 적습니다. 화면이 하얗게 되는 하이드레이션 줄과 코드가 다릅니다.
먼저 기억할 것 | 모듈 이름과 그 모듈을 연 파일을 한 쌍으로 적으세요. 런타임 설정을 바꾸기 전에 임포트 사슬을 끊는 쪽이 짧습니다.
유리 밖 입구에서는 안쪽 랙의 파일과 소켓을 직접 열 수 없다
엣지에서 되는 것과 막히는 것
웹 표준 요청과 응답은 되고, 노드 내장은 막힙니다.
하려는 일
엣지
둘 곳
fetch로 외부 주소 호출
가능
미들웨어에 둬도 됨
쿠키 이름만 검사
가능
미들웨어
웹 크립토로 해시
가능
전역 crypto.subtle
node:crypto, fs, net
거절
노드 런타임 라우트
pg, 프리즈마 기본 클라이언트
거절
노드 런타임 라우트
패키지라도 노드 내장을 부르면 같이 거절됩니다. 문서에 ESM이고 네이티브 노드를 안 쓴다고 적힌 패키지만 엣지에 남길 수 있습니다. require를 직접 호출하는 코드도 엣지에서는 허용되지 않습니다. 임포트 문법으로 바꾸라는 뜻이 아니라, 노드 전용 모듈을 그 파일에서 빼라는 뜻에 가깝습니다.
데이터베이스는 노드 라우트로
조회가 필요하면 그 핸들러의 런타임을 노드로 둡니다.
앱 라우터의 라우트 핸들러 기본값은 노드입니다. 누군가 export const runtime = 'edge'를 넣어 두었다면 그 한 줄이 드라이버를 거절합니다. 데이터베이스가 필요하면 그 선언을 nodejs로 바꾸거나 지웁니다. 미들웨어 파일에는 이 선언으로 노드를 켤 수 없는 버전이 많습니다. 미들웨어 안에서 프리즈마를 부르지 마세요.
입구에서는 쿠키가 있는지만 보고, 사용자 행을 읽는 일은 app/api/session/route.js로 넘깁니다. 카카오 콜백도 같습니다. 인가 코드를 쿼리에서 읽는 것까지는 입구에서 가능하고, 토큰 교환 뒤 테이블에 넣는 일은 노드 라우트입니다. 주소가 비어 new URL이 죽는 줄은 ERR_INVALID_URL이라 런타임 거절과 다릅니다.
공유 헬퍼를 둘로 나누세요. 쿠키와 리다이렉트만 있는 파일, 드라이버를 부르는 파일. 미들웨어는 앞 파일만 임포트합니다. 한 파일에 둘 다 있으면 번들러가 드라이버를 따라 들어옵니다.