파운더 노트

Next.js 16에서 middleware가 proxy로 바뀌었습니다: 마이그레이션과 조용히 빠지는 인증 주의점

logicallabs 2026. 8. 1. 19:23

프레임워크가 어느 날 파일 이름을 바꾸면, 혼자 제품을 만드는 사람은 그걸 어떻게 따라가야 할까요.

 

저는 제품 프론트엔드를 Next.js로 만들고 있습니다. 그래서 Next.js 16이 나오면서 나온 여러 변경 중에서도 middleware를 proxy로 바꾼 개편은 그냥 지나칠 수가 없었습니다.

 

이름만 바뀐 사소한 변경처럼 보이지만, 마이그레이션을 어중간하게 끝내면 인증이 소리 없이 비어 버릴 수 있습니다. 오늘은 공식 문서를 직접 확인하며 정리한 내용을 남깁니다.

 

무엇이 바뀌었나

 

Next.js 16(정식 릴리스 2025년 10월 21일)부터 middleware.ts 파일 컨벤션이 지원 중단(deprecated)되고 proxy.ts로 이름이 바뀌었습니다. 기존 이름이 곧바로 없어진 것은 아니고 하위 호환으로 당분간 남지만, 새 표준은 proxy.ts입니다.

 

파일 이름만이 아니라 export 하는 함수 이름과 설정 플래그까지 함께 바뀌었습니다.

 

항목 변경 전 (v15) 변경 후 (v16)
파일명 middleware.ts / .js proxy.ts / .js
export 함수명 export function middleware() export function proxy()
설정 플래그 skipMiddlewareUrlNormalize skipProxyUrlNormalize
런타임 기본 Edge Runtime Node.js 런타임 고정 (변경 불가)

 

로직 자체는 그대로입니다. 파일과 함수의 이름, 그리고 실행 런타임이 달라졌을 뿐입니다.

 

코드는 이렇게 바뀝니다.

 

// 변경 전: middleware.ts
export function middleware(request) {
  // 인증, 리다이렉트, 헤더 조작 등
}

// 변경 후: proxy.ts
export function proxy(request) {
  // 동일한 로직, 이름만 proxy
}

 

한 가지 눈여겨볼 점은 런타임입니다. proxy는 Node.js 런타임으로 고정되어 있고 Edge Runtime을 지원하지 않습니다.

 

Edge에서 돌려야 하는 로직이 있다면 (지원 중단으로 표시된) 기존 middleware를 당분간 유지해야 합니다. 다만 middleware는 현재 지원 중단(deprecated) 상태라, 이후 나올 공식 안내를 지켜봐야 합니다.

 

왜 이름을 proxy로 바꿨을까

 

이름 하나 바꾸자고 이렇게까지 한 데는 이유가 있습니다. 공식 문서가 밝힌 배경은 크게 두 가지입니다.

 

첫째, "middleware"라는 단어가 Express.js의 미들웨어와 자주 혼동을 일으켰습니다. 이름 때문에 사람들이 이 기능의 용도를 오해하곤 했습니다.

 

둘째, middleware가 너무 강력해서 남용을 부추기는 면이 있었습니다. Next.js 팀은 이 기능을 최후의 수단으로만 쓰기를 권장해 왔고, 더 나은 API로 목표를 달성하도록 방향을 틀고 있습니다.

 

"proxy"라는 이름은 앱 앞단의 네트워크 경계(요청이 앱에 닿기 전 거치는 지점)를 분명히 드러냅니다. 실제 기능의 본질에 더 가까운 이름인 셈입니다.

 

즉 이 개명은 단순한 취향의 문제가 아니라, 이 기능을 어떻게 써야 하는지에 대한 설계 신호를 담고 있습니다.

 

마이그레이션: 자동이 편하지만 눈으로 확인하세요

 

옮기는 방법은 두 가지입니다.

 

자동으로는 코드모드(codemod, 코드를 기계적으로 일괄 변환해 주는 도구) 한 줄이면 됩니다.

 

npx @next/codemod@canary middleware-to-proxy .

 

파일명과 함수명을 알아서 바꿔 줍니다. 통합 업그레이드 코드모드(npx @next/codemod@canary upgrade latest)를 쓰면 이 변환에 더해 설정 플래그까지 함께 정리됩니다.

 

수동으로 하려면 middleware.ts를 proxy.ts로 옮기고, 함수 이름을 middleware에서 proxy로 바꾸고, skipMiddlewareUrlNormalize 같은 설정 플래그도 새 이름으로 고치면 됩니다. default export를 쓰더라도 함수 이름은 proxy로 두기를 권장합니다.

 

자동 변환이 편하긴 하지만, 저는 변환 뒤 바뀐 파일을 눈으로 한 번 훑어보길 권합니다. 다음에 이야기할 함정 때문입니다.

 

가장 위험한 함정: 조용히 빠지는 인증 커버리지

 

먼저 오해 하나를 풀어야 합니다. Next.js 16으로 올린 뒤에 옛 middleware.ts 파일을 그대로 두면 그 파일이 갑자기 무시되는 건 아닙니다.

 

하위 호환이 유지되어 계속 동작하고, 대신 지원 중단(deprecated)으로 표시되니 정리해 두길 권합니다. 공식 문서도 Edge 런타임이 필요하면 당분간 middleware를 계속 쓰라고 안내합니다.

 

그러니 파일을 남겨 뒀다는 이유만으로 인증이 소리 없이 죽지는 않습니다.

 

진짜 조심할 지점은 다른 데 있습니다. 마이그레이션이 어중간하게 끝났을 때입니다.

 

파일만 proxy.ts로 옮기고 export 하는 함수 이름을 middleware인 채로 두면, proxy.ts는 그 함수를 인식하지 못합니다. proxy 파일은 default export이거나 이름이 정확히 proxy인 named export만 인식하기 때문입니다.

 

이 경우 빌드는 통과하는데 정작 인증 로직이 실행되지 않을 수 있습니다.

 

또 하나는 커버리지 누락입니다. 공식 문서가 직접 "silently(소리 없이)"라는 단어로 경고하는 부분입니다.

 

config.matcher를 손봤거나 Server Function을 다른 경로로 옮기는 리팩터링을 하면, Proxy가 걸려 있던 보호 범위가 조용히 빠질 수 있습니다. 그래서 공식 문서는 Proxy 하나만 믿지 말고 각 Server Function 안에서 인증과 인가를 직접 확인하라고 권합니다.

 

에러가 나면 오히려 다행인데, 이 두 경우 모두 아무 신호 없이 지나갈 수 있다는 점이 위험합니다.

 

그래서 업그레이드 뒤에는 아래를 체크리스트로 점검하시길 권합니다.

 

  • proxy.ts로 옮긴 파일 안의 export 함수 이름이 proxy로 바뀌어 있는가 (middleware인 채면 인식 안 됨. default export나 이름이 proxy인 named export만 인식)
  • skipMiddlewareUrlNormalize 등 옛 설정 플래그가 새 이름으로 교체되었는가
  • config.matcher를 바꿨거나 Server Function을 옮겼다면, Proxy 보호가 빠진 경로가 없는지 확인했는가
  • 인증이 필요한 경로에 로그인 없이 접근해 보고, 정말 막히는지 실제로 확인했는가
  • 옛 middleware.ts를 남겨 뒀다면, 지원 중단(deprecated) 상태임을 인지하고 정리 계획을 세웠는가
  • Edge 런타임에 의존하던 로직이 있었다면, Node.js 고정으로 바뀐 뒤에도 문제없이 동작하는가

 

특히 실제로 로그인 없이 보호 경로를 눌러 보는 확인은 빼먹지 마세요. 파일과 함수가 옮겨졌는지가 아니라, 인증이 실제로 작동하는지를 봐야 합니다.

 

혼자 만드는 사람에게 프레임워크 변화란

 

메이저 업그레이드는 부담입니다. 특히 팀 없이 혼자 제품을 붙들고 있으면 더 그렇습니다.

 

그럴 때 저는 두 가지를 기준으로 삼습니다.

 

하나는 변경이 왜 일어났는지를 먼저 읽는 것입니다. 이번처럼 이름만 바뀐 것처럼 보이는 변경에도 대개 설계 의도가 깔려 있고, 그 의도를 알면 다음 방향도 짐작할 수 있습니다.

 

다른 하나는 자동 도구를 믿되 결과를 눈으로 확인하는 것입니다. 코드모드는 시간을 아껴 주지만, 함수 이름이나 커버리지처럼 조용히 빠지는 함정까지 대신 잡아 주지는 않습니다.

 

결국 마지막 확인은 사람 몫으로 남습니다.

 

Next.js 16은 이 proxy 개명 말고도 Turbopack 기본화, 비동기 요청 API 강제, React 19.2 같은 큰 변화를 함께 담고 있습니다. proxy 이야기는 그중 한 조각일 뿐입니다.

 

나머지 조각들도 하나씩 정리해 남겨 두려 합니다.