Ray Book
Next.js 깊이 보기

Next.js 16과 Turbopack, 빌드 도구의 전환

Webpack의 한계에서 Turbopack까지, Next.js가 빌드 도구를 교체한 여정과 16.2에서 만나볼 수 있는 최신 기능들을 정리합니다.

nextjsturbopackwebpackbuild-tools

Webpack이라는 오래된 기반

Next.js는 출시 초기부터 Webpack 을 빌드 도구로 사용해왔습니다. 사실 2016~2020년대 초반까지 JavaScript 생태계에서 Webpack은 거의 표준이었습니다. 복잡한 모듈 그래프, 코드 분할, 로더 시스템, 플러그인 생태계, 이 모든 기능이 Webpack에 있었고, 다른 대안은 없었습니다.

하지만 Webpack에는 근본적인 한계가 있었습니다. JavaScript로 작성되었다는 것 입니다.

Webpack은 노드에서 실행되는 JavaScript 프로그램입니다. 의존성 그래프를 분석하고, 모듈을 변환하고, 번들을 만드는 모든 작업이 단일 스레드 JavaScript로 이루어집니다. 작은 앱에서는 문제가 없지만, 수천 개의 모듈을 가진 앱에서는 빌드가 수십 초에서 수 분까지 걸리는 일이 일상이었습니다.

Next.js 팀은 이 문제를 수년간 다양한 방식으로 완화해왔습니다.

Babel을 SWC로 교체 (2021). Webpack 자체는 못 바꾸더라도, 트랜스파일러만큼은 네이티브로 바꿀 수 있었습니다. Next.js 12에서 Babel을 Rust 기반 SWC로 교체하여 트랜스파일 속도를 17배 높였습니다.

Terser를 SWC Minifier로 교체 (2022). 압축 단계도 마찬가지로 SWC로 전환해서 6배 빨라졌습니다.

이런 부분적 교체만으로도 큰 개선이 있었지만, 여전히 Webpack 자체가 병목이었습니다. 진짜 해결은 빌드 도구 자체를 네이티브로 바꾸는 것이었습니다.

Turbopack의 탄생

Turbopack 은 2022년 10월 Next.js 13 과 함께 알파 버전으로 공개되었습니다. 이것은 Webpack의 제작자인 Tobias Koppers 와 Vercel 팀이 함께 만든, Rust 기반의 새로운 번들러 입니다.

Turbopack의 핵심 아이디어는 단순합니다.

  1. Rust로 작성 , JavaScript의 싱글 스레드 한계를 벗어난다
  2. 증분 엔진 , 변경된 부분만 다시 계산하는 아키텍처
  3. 캐시 우선 , 모든 계산 결과를 캐시해서 재사용

Turbopack이 처음 발표되었을 때 Next.js 팀은 인상적인 벤치마크를 보여줬습니다.

  • Webpack 대비 700배 빠른 업데이트 (큰 앱에서 HMR)
  • Vite 대비 10배 빠른 업데이트
  • Webpack 대비 4배 빠른 cold start

3,000개 모듈을 가진 앱에서 Turbopack은 1.8초에 시작했고, 같은 앱에서 Vite는 11.4초, Webpack은 16.5초가 걸렸습니다.

하지만 초기에는 몇 가지 제약이 있었습니다.

  • next dev 에서만 동작 (개발 모드 전용)
  • 많은 Webpack 로더와 플러그인 호환 안 됨
  • Alpha라서 프로덕션에서 쓰기엔 불안정

그래서 Turbopack은 "점진적으로 안정화되는 플래그" 로 제공되었습니다. 원하는 개발자만 next dev --turbo 로 켜서 써볼 수 있었습니다.

단계적 안정화

Turbopack은 몇 년에 걸쳐 단계적으로 안정화되었습니다.

Next.js 13.4 (2023년 5월), Beta. 알파에서 베타로 승격. 주요 버그가 수정되고 더 많은 기능이 지원되었습니다. 여전히 dev 모드 전용.

Next.js 14.x (2023~2024). 프로덕션 빌드 지원 작업이 시작되었고, Webpack 플러그인 호환성 레이어가 개선되었습니다. Vercel 내부 앱들이 Turbopack으로 점진적으로 전환되며 실제 프로덕션에서 검증되었습니다.

Next.js 15.x (2024~2025). dev 모드에서 안정, 프로덕션 빌드도 베타 수준까지 도달. 적극적인 dogfooding 단계.

Next.js 16 (2025년 10월), Stable, Default. 마침내 Turbopack이 기본 번들러 가 되었습니다. 새 Next.js 프로젝트는 별도 설정 없이 Turbopack을 사용합니다. Webpack은 여전히 사용 가능하지만, 명시적으로 --webpack 플래그를 붙여야 합니다.

# 기본 (Turbopack)
next dev
next build

# 옵트아웃 (Webpack 사용)
next dev --webpack
next build --webpack

Next.js 16 발표 시점에서 Vercel의 통계에 따르면, Next.js 15.3+ 의 개발 세션 중 50% 이상, 프로덕션 빌드 중 20% 이상이 이미 Turbopack을 사용하고 있었습니다. 기본값이 된 것은 자연스러운 수순이었습니다.

Next.js 16의 Turbopack 성능

Next.js 16에서 Turbopack이 가져온 성능 개선을 숫자로 보면:

  • 프로덕션 빌드 2~5배 빠름 , next build가 Webpack 대비
  • Fast Refresh 최대 10배 빠름 , 개발 중 파일 저장 시 반영 속도
  • next dev 시작 ~400% 빠름 (16.2 기준)
  • 렌더링 ~50% 빠름 (16.2 기준)

이 수치들은 실제로 체감할 수 있는 차이입니다. 큰 Next.js 프로젝트에서 빌드 대기 시간이 분 단위에서 초 단위로 바뀌는 경험을 할 수 있습니다.

파일 시스템 캐싱

Next.js 16의 Turbopack은 파일 시스템 캐싱 (File System Caching) 을 베타로 지원합니다. 이것은 컴파일 결과를 디스크에 저장해서, next dev를 다시 시작해도 이전 빌드 결과를 재사용하는 기능입니다.

// next.config.ts
const nextConfig = {
  experimental: {
    turbopackFileSystemCacheForDev: true,
  },
};

대형 앱에서 이 기능의 효과는 극적입니다. 첫 번째 빌드 후 두 번째 next dev 실행은 캐시 적중으로 거의 즉시 시작됩니다. Vercel 내부의 모든 앱이 이 기능을 사용 중이며, 개발 생산성에 큰 향상이 있다고 합니다.

Cache Components, 16의 또 다른 큰 변화

Turbopack 외에도 Next.js 16에는 Cache Components 라는 큰 변화가 있습니다 (4편에서 자세히 다뤘습니다). 이것은 캐싱 모델을 "기본 캐시" 에서 "기본 동적 + 명시적 캐시" 로 뒤집었습니다.

// next.config.ts
const nextConfig = {
  cacheComponents: true,
};
// 페이지나 함수를 명시적으로 캐시
"use cache";

export default async function Page() {
  const posts = await db.posts.findAll();
  return <PostList posts={posts} />;
}

이 변화는 Partial Prerendering (PPR) 의 이전 실험들을 통합한 결과입니다. 개발자가 "무엇을 캐시할 것인가"를 직관적으로 선언할 수 있는 모델입니다.

middleware.tsproxy.ts

Next.js 16은 middleware.tsproxy.ts 로 이름을 바꾸고, 실행 런타임도 정리했습니다.

// proxy.ts (이전: middleware.ts)
export default function proxy(request: NextRequest) {
  return NextResponse.redirect(new URL("/home", request.url));
}

두 가지 변화가 있습니다.

이름이 역할을 드러냅니다. "middleware"라는 이름은 Express.js 스타일의 미들웨어를 연상시켰지만, Next.js의 그것은 실제로는 네트워크 경계에서 요청을 가로채는 프록시 에 가까웠습니다. 이름을 proxy로 바꿔 역할을 분명히 한 것입니다.

런타임이 Node.js로 통일되었습니다. proxy.tsNode.js 런타임에서 실행 됩니다. 이전의 middleware.ts는 Edge 런타임 전용이었고, Node.js API (예: fs, crypto 일부) 를 쓸 수 없다는 제약이 있었습니다. proxy.ts에서는 이런 제약이 사라집니다.

middleware.ts 파일은 Edge 런타임이 꼭 필요한 경우 를 위해 여전히 사용할 수 있지만, deprecated 상태이며 향후 제거 예정입니다. Edge 배포가 필수가 아니라면 새 프로젝트는 proxy.ts를 사용하는 것이 권장됩니다.

React Compiler 통합

Next.js 16은 React Compiler 1.0 을 안정 버전으로 통합했습니다. React Compiler는 컴포넌트 코드를 자동으로 최적화해서, useMemo, useCallback, memo 같은 수동 메모이제이션을 불필요하게 만듭니다.

// next.config.ts
const nextConfig = {
  reactCompiler: true,
};

이 옵션을 켜면 모든 컴포넌트가 빌드 시 자동으로 메모이제이션됩니다. 개발자는 이제 성능 최적화를 위해 useMemo를 남발할 필요가 없습니다. 컴파일러가 어떤 값이 재계산되어야 하는지 분석해서 최소한의 연산만 수행하게 만듭니다.

React Compiler는 아직 기본값은 아닙니다 (빌드 시간 증가 등의 트레이드오프가 있어서). 하지만 점진적으로 더 많은 앱이 이 기능을 채택하게 될 것입니다.

Next.js Devtools MCP

Next.js 16의 독특한 추가 기능 중 하나는 Next.js Devtools MCP (Model Context Protocol) 입니다. 이것은 AI 에이전트가 Next.js 앱의 디버깅과 개발에 직접 참여할 수 있게 하는 통합입니다.

MCP는 Claude 같은 AI 에이전트와 개발 도구 사이의 표준 인터페이스입니다. Next.js DevTools MCP는 에이전트에게 다음 정보를 제공합니다.

  • Next.js 지식 (라우팅, 캐싱, 렌더링 동작)
  • 브라우저와 서버의 통합 로그
  • 자동 에러 접근 (스택 트레이스 포함)
  • 페이지 인식 (현재 라우트의 컨텍스트)

이것은 AI 기반 개발 워크플로우가 점점 보편화되는 현실을 반영한 것입니다. AI가 코드를 생성하고, 디버깅하고, 리팩토링하는 시대에, 프레임워크가 직접 에이전트와 통신할 수 있는 채널을 제공하는 것은 자연스러운 방향입니다.

Next.js 16.2, 최신 개선사항

Next.js 16.2 (2026년 3월 18일) 는 16.x 라인의 최신 업데이트입니다. 주요 추가 사항:

Server Fast Refresh. 서버 사이드 코드의 hot reload가 더 세밀해졌습니다. Server Component나 Server Action을 수정해도 전체 서버 재시작 없이 해당 부분만 갱신됩니다.

Agent DevTools (실험적). AI 에이전트가 터미널을 통해 React DevTools와 Next.js 진단 정보에 접근할 수 있는 실험적 기능입니다. MCP 통합의 연장선입니다.

Tree Shaking of Dynamic Imports. 동적 import() 의 결과에서 사용되지 않는 export를 제거하는 최적화가 추가되었습니다. 번들 크기가 더 작아집니다.

Subresource Integrity 지원. 번들된 JS 파일에 SRI 해시가 자동으로 추가되어, 배포된 스크립트의 무결성을 브라우저가 검증할 수 있습니다.

Browser Log Forwarding. 브라우저의 console.log나 에러가 개발 서버 터미널로 전달됩니다. 여러 창을 오가지 않고 한 곳에서 디버깅할 수 있습니다.

Next.js 16의 Breaking Changes

Next.js 16으로의 업그레이드에는 몇 가지 주의사항이 있습니다.

Node.js 20.9+ 필요. Node.js 18은 더 이상 지원되지 않습니다.

params, searchParams는 async. Next.js 15에서 시작된 변경이 16에서 완성되었습니다.

// 이전: 동기 접근 (deprecated)
export default function Page({ params }) {
  return <div>{params.id}</div>;
}

// 현재: async
export default async function Page({ params }: { params: Promise<{ id: string }> }) {
  const { id } = await params;
  return <div>{id}</div>;
}

cookies(), headers(), draftMode()도 async. 같은 이유로 비동기화되었습니다.

// 이전
const cookieStore = cookies();

// 현재
const cookieStore = await cookies();

AMP 지원 제거. useAmp, export const config = { amp: true } 같은 AMP 관련 API가 모두 제거되었습니다.

next lint 명령 제거. ESLint나 Biome을 직접 사용해야 합니다. codemod가 제공됩니다.

middleware.ts deprecated. proxy.ts로 이름이 바뀌었습니다.

Next.js 팀은 codemod를 제공해서 대부분의 변경을 자동으로 처리할 수 있게 했습니다.

npx @next/codemod@canary upgrade latest

10년의 여정을 정리하며

2016년에 시작된 Next.js는 10년 동안 프론트엔드 생태계의 중심 중 하나가 되었습니다. 각 주요 버전이 해결한 문제들을 돌아보면:

  • v1v8 (20162019) , zero-config SSR, 파일 기반 라우팅, Automatic Static Optimization 확립
  • v9.3~9.5 (2020) , getStaticProps, getServerSideProps, ISR 도입/안정화
  • v10v12 (20202022) , SWC, 이미지 최적화, 미들웨어
  • v13 (2022) , App Router 베타, Server Components, Turbopack 알파
  • v13.4 (2023) , App Router 안정, Server Actions 알파
  • v14 (2023) , Server Actions 안정
  • v15 (2024) , React 19 통합, async params
  • v16 (2025) , Turbopack 기본값, Cache Components, proxy.ts, React Compiler
  • v16.2 (2026) , Server Fast Refresh, MCP 확장, 성능 개선

이 발전의 공통된 방향은 일관됩니다. 더 적은 설정, 더 세밀한 제어, 더 빠른 피드백, 더 나은 개발자 경험. Next.js는 "React 앱을 만드는 가장 쉬운 방법"이라는 초기 철학에서 한번도 벗어난 적이 없습니다. 다만 그 "쉬움" 을 유지하기 위해, 뒤에 숨어있는 도구들은 계속 진화해왔을 뿐입니다.

시리즈를 마치며

7편에 걸쳐 Next.js의 핵심 기능과 그 발전 과정을 살펴봤습니다. 정리하면:

  1. Next.js는 왜 만들어졌나 , 2016년 React 생태계의 설정 지옥을 해결하기 위해
  2. App Router와 파일 기반 라우팅 , Pages Router의 한계를 파일 규칙으로 해결
  3. Server Components , 워터폴과 번들 비대를 근본적으로 해결
  4. 데이터 패칭과 캐싱의 진화 , getServerSideProps에서 Cache Components까지
  5. 렌더링 전략 , SSR, SSG, ISR, PPR을 하나의 모델로 통합
  6. Server Actions , API 라우트 없이 mutation을 다루는 새로운 방식
  7. Next.js 16과 Turbopack , 빌드 도구의 근본적인 교체와 최신 개선

각 단계마다 해결하려는 문제가 있었고, 그 해결책이 다음 단계의 출발점이 되었습니다. Next.js의 현재 모습은 하루아침에 만들어진 것이 아니라, 10년 동안 쌓인 결정들의 결과입니다.

프레임워크는 계속 변합니다. 이 시리즈에서 다룬 내용도 몇 년 후에는 옛날 이야기가 될지도 모릅니다. 하지만 "무엇이 문제였고, 어떻게 해결했는가"를 아는 것은 어떤 새로운 프레임워크를 배울 때든 도움이 됩니다. Next.js의 여정이 그 이해의 좋은 사례가 되기를 바랍니다.