React

[Next.js 15] Turbopack 정식 지원과 React 19 호환: 개발자가 알아야 할 핵심 변경점 및 마이그레이션 가이드

코딩하는 Jay 2026. 10. 29. 07:48
반응형

안녕하세요. 코딩하는 Jay입니다.

모던 프론트엔드 개발의 표준 프레임워크로 자리 잡은 Next.js가 15 버전으로 메이저 판올림되었습니다. 이번 릴리즈는 단순한 기능 추가를 넘어, 개발 생산성의 병목이었던 로컬 빌드 속도의 극적인 개선(Turbopack 정식 지원)과 React 19 생태계 전면 수용, 그리고 수많은 개발자들을 혼란스럽게 했던 캐싱 동작의 직관적 재정의를 핵심으로 담고 있습니다.

프로덕션 레벨에서 Next.js를 운영 중인 팀이라면 언제, 어떻게 업그레이드를 진행해야 할지 고민이 깊으실 텐데요.

오늘은 Next.js 15에서 실무 개발자가 반드시 짚고 넘어가야 할 핵심 변경점 4가지와 브레이킹 체인지 대응 및 마이그레이션 팁을 정리해 보았습니다.


한눈에 보는 Next.js 15 핵심 변경점

구분 Next.js 14 이하 Next.js 15 개발자 체감 포인트
개발 번들러 Webpack (기본), Turbopack (실험적) Turbopack Dev 안정화 (기본 권장) 로컬 구동 속도 최대 76% 향상, 빠른 HMR
React 지원 React 18 및 카나리 기능 일부 React 19 정식 지원 & 컴파일러 호환 Actions, useActionState, use() 훅 활용 가능
Request API 동기식 (cookies().get(), params.id) 비동기식 (await cookies(), (await params).id) ⚠️ 브레이킹 체인지 (Codemod 필수)
캐싱 기본값 fetch 기본 강력 캐싱 (force-cache) 기본 비캐싱 (no-store) 의도치 않은 데이터 불일치 이슈 해소
클라이언트 탐색 페이지 컴포넌트 5분/30초 기본 캐시 staleTimes: 0 (새로고침 시 최신 반영) 내비게이션 시 즉각적인 최신 데이터 반영

1. Turbopack Dev 안정화: "드디어 Webpack을 내려놓을 시간"

Rust 기반으로 밑바닥부터 다시 설계된 Turbopack이 next dev --turbo 플래그를 통해 안정화 단계에 진입했습니다. Vercel 팀의 수백 개 대규모 앱 테스트 결과:

  • 로컬 서버 기동 속도: 최대 76.7% 단축
  • 코드 수정 후 Fast Refresh(HMR) 반영: 최대 96.3% 단축

대규모 엔터프라이즈 프로젝트일수록 컴포넌트가 늘어남에 따라 로컬 서버 구동에 수십 초 이상 걸리던 스트레스가 완전히 해소되었습니다. 별도의 설정 없이 package.json 스크립트에 플래그만 추가하면 즉시 적용할 수 있습니다.

{
  "scripts": {
    "dev": "next dev --turbo"
  }
}

2. React 19 호환 및 React 컴파일러 지원

Next.js 15는 React 19 GA(일반 제공)를 완벽하게 지원합니다. 프론트엔드 개발자들의 오랜 고민이었던 폼 상태 관리와 비동기 UI 처리가 네이티브 훅으로 대폭 간소화되었습니다.

  • useActionState & Server Actions: 폼 제출 상태, 펜딩 플래그, 에러 핸들링을 보일러플레이트 없이 직관적으로 처리할 수 있습니다.
  • useOptimistic: 낙관적 UI 업데이트를 기본 제공하여 네트워크 지연 중에도 즉각적인 사용자 피드백을 구현합니다.
  • React Compiler (실험적 지원): Babel 플러그인 형태로 React Compiler를 활성화할 수 있어, 지긋지긋했던 useMemo, useCallback 수동 메모이제이션 지옥에서 벗어날 수 있는 기반이 마련되었습니다.
// next.config.ts
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  experimental: {
    reactCompiler: true,
  },
};

export default nextConfig;

3. 비동기 요청 API(Async Request APIs): 필수 브레이킹 체인지

가장 주의해야 할 브레이킹 체인지는 서버 컴포넌트에서 요청 관련 데이터(cookies, headers, params, searchParams)가 비동기(Promise)로 변경된 점입니다. 런타임 환경 최적화와 향후 부분 사전 렌더링(PPR) 호환을 위한 변경점입니다.

기존 (Next.js 14)

import { cookies } from 'next/headers';

export default function Page({ params }: { params: { id: string } }) {
  const cookieStore = cookies();
  const token = cookieStore.get('token');
  const userId = params.id;
  return <div>User: {userId}</div>;
}

변경 (Next.js 15)

import { cookies } from 'next/headers';

export default async function Page({
  params,
}: {
  params: Promise<{ id: string }>;
}) {
  const cookieStore = await cookies();
  const token = cookieStore.get('token');
  const { id } = await params;
  return <div>User: {id}</div>;
}

💡 마이그레이션 팁: Next.js 15 런타임에서는 하위 호환성을 위해 당분간 동기 호출 시 경고(Warning)를 띄우지만, 빌드 에러를 방지하고 최적화를 위해 Vercel 공식 Codemod를 실행하여 자동 변환하는 것을 권장합니다.

npx @next/codemod@canary next-async-request-api .

4. 캐싱 기본값 정책의 대전환 (Uncached by Default)

Next.js 13/14에서 가장 악명 높았던 부분 중 하나는 "왜 내 API 데이터가 새로고침해도 안 바뀌지?"라는 질문이었습니다. fetch 요청이 기본적으로 force-cache 상태였기 때문인데요.

Next.js 15부터는 개발자들의 피드백을 적극 수용하여 기본값이 no-store(비캐시)로 변경되었습니다.

  • fetch 요청: 캐시 옵션을 생략하면 기본적으로 캐시하지 않습니다. 캐싱이 필요한 정적 데이터만 명시적으로 { cache: 'force-cache' }를 지정하면 됩니다.
  • GET Route Handler: 요청 핸들러 역시 기본적으로 캐시되지 않고 매 요청마다 동적으로 실행됩니다.
  • 클라이언트 라우터 캐시: staleTimes 기본값이 페이지의 경우 0초로 재조정되어, 뒤로가기/앞으로가기나 링크 이동 시 동적 페이지가 오래된 데이터를 보여주던 문제가 자연스럽게 해결되었습니다.

5. 한 줄 마이그레이션 가이드

기존 프로젝트를 Next.js 15로 업그레이드할 때는 공식 업그레이드 도구를 활용하는 것이 가장 안전합니다.

# 공식 codemod를 통한 일괄 업그레이드
npx @next/codemod@canary upgrade latest

이 명령어를 실행하면 package.json의 의존성 업데이트뿐만 아니라 비동기 파라미터 변경 사항(params, cookies)까지 프로젝트 전반의 코드를 안전하게 분석하여 자동 리팩토링해 줍니다.


💡 정리하며

Next.js 15는 과도하게 공격적이었던 캐싱 정책을 상식적으로 되돌려놓고, 개발자들의 최대 숙원이었던 로컬 빌드 속도를 Turbopack으로 시원하게 해결한 "개발자 친화적인 완성형 릴리즈"입니다.

새로운 프로젝트를 기획 중이시라면 주저 없이 Next.js 15를 도입하시길 추천드리며, 기존 프로젝트 역시 Codemod를 통해 점진적으로 업그레이드해 보시길 권장합니다!

반응형