İçeriğe geç
Web Geliştirme

Next.js 16'ya Geçiş Rehberi

Next.js 16’ya geçiş yalnızca sürüm yükseltmek değil. Turbopack, async API’ler, Proxy, caching ve image değişikliklerini bu rehberde inceleyin.

Ertuğrul TokerSon Güncelleme: 17 Ağustos 2026

Next.js 16'ya Geçiş Rehberi: Adım Adım Migration

Bir Next.js projesini major sürümler arasında güncellemek, çoğu zaman npm install next@latest çalıştırıp devam etmek kadar basit olmuyor. Özellikle production'da çalışan, authentication, middleware, caching, image optimization ve özel build ayarları kullanan bir projede sürüm yükseltmek doğrudan uygulamanın mimarisine dokunabiliyor.

Next.js 16 da tam olarak böyle bir sürüm.

İlk sürümü Ekim 2025'te yayınlanan Next.js 16; Turbopack'in varsayılan bundler hâline gelmesi, caching modelinin yeniden ele alınması, React Compiler desteği ve routing tarafındaki geliştirmelerin yanında migration sırasında doğrudan kod değişikliği gerektirebilecek breaking change'ler getirdi. Üstelik framework burada durmadı; 3 Ağustos 2026'da yayınlanan Next.js 16.3 ile 16 ailesi performans ve geliştirici deneyimi tarafında gelişmeye devam ediyor.

Bu nedenle bu yazıda yalnızca "Next.js 16'da neler yeni?" sorusuna bakmayacağım. Asıl mesele şu:

Mevcut bir Next.js 15 projesini Next.js 16'ya geçirirken nereler kırılabilir ve migration'ı nasıl kontrollü yapabiliriz?

Önce Ortamı Kontrol Edelim

Migration'a başlamadan önce benim ilk baktığım yer framework değil, çalışma ortamı olur. Çünkü Next.js 16'nın minimum sistem gereksinimleri de değişti.

Next.js 16 ile birlikte minimum Node.js sürümü 20.9.0, minimum TypeScript sürümü ise 5.1.0 oldu. Node.js 18 artık desteklenmiyor.

Önce mevcut Node sürümünü kontrol etmek gerekiyor:

node -v

Eğer proje Docker kullanıyorsa yalnızca local makineyi güncellemek de yetmez. Dockerfile içerisindeki Node image'ı, CI/CD pipeline'ı ve production sunucusundaki Node sürümü de ayrıca kontrol edilmeli.

Örneğin eski bir Dockerfile şöyleyse:

FROM node:18-alpine

Next.js 16 sonrasında bunu desteklenen bir Node 20 sürümüne taşımak gerekir.

Major framework migration'larında en kolay gözden kaçan noktalardan biri tam olarak bu: uygulama local'de çalışırken production build ortamının hâlâ eski Node sürümünde kalması.

Next.js 16'ya Nasıl Yükseltilir?

Next.js ekibi bu geçiş için doğrudan bir codemod sunuyor.

npm kullanıyorsanız:

npx @next/codemod@canary upgrade latest

Manuel ilerlemek isteyenler için temel paket güncellemesi ise şöyle:

npm install next@latest react@latest react-dom@latest

TypeScript kullanılan projelerde React type paketlerini de güncellemek gerekiyor:

npm install -D @types/react@latest @types/react-dom@latest

Ben burada mümkün olduğunca codemod ile başlamayı daha mantıklı buluyorum. Çünkü v16 codemod yalnızca dependency sürümünü değiştirmiyor; Turbopack configuration'ını güncelleyebiliyor, next lint kullanımını ESLint CLI'a taşıyabiliyor, middleware yapısını proxy convention'ına çevirebiliyor ve bazı eski experimental ayarları temizleyebiliyor.

Ama önemli bir ayrım var:

Codemod migration'ı kolaylaştırıyor, migration'ın tamamını sizin yerinize yapmıyor.

Özellikle custom webpack config, üçüncü parti paketler, authentication katmanı ve caching davranışları manuel olarak test edilmeli.

Turbopack Artık Varsayılan

Bence Next.js 16'ya geçerken en fazla dikkat edilmesi gereken değişikliklerden biri bu.

Next.js 16 itibarıyla Turbopack hem next dev hem de next build için varsayılan bundler hâline geldi. Artık ayrıca --turbo veya --turbopack parametresi vermek gerekmiyor.

Eski kullanım:

{
  "scripts": {
    "dev": "next dev --turbopack",
    "build": "next build --turbopack"
  }
}

Yeni kullanım:

{
  "scripts": {
    "dev": "next dev",
    "build": "next build"
  }
}

Buraya kadar güzel. Problem custom Webpack configuration kullanan projelerde başlıyor.

next.config.js içerisinde özel bir webpack() tanımınız varsa Next.js 16'nın doğrudan Turbopack ile build almaya başlaması beklenmedik sonuçlara yol açabilir. Next.js bu durumda yanlış bir configuration ile build almamak için build'i durdurabiliyor.

Webpack ile devam etmek istiyorsanız:

next dev --webpack
next build --webpack

kullanabilirsiniz.

Turbopack artık oldukça olgun durumda ancak hâlâ Webpack plugin sisteminin birebir karşılığını sunmuyor. Dolayısıyla Sentry, özel loader'lar, custom Sass işlemleri veya farklı Webpack plugin'lerine bağımlı büyük projelerde migration öncesinde bu entegrasyonların ayrıca kontrol edilmesi gerekiyor.

Ben olsam burada doğrudan "Turbopack geldi, Webpack'i siliyorum" yaklaşımı yerine önce iki bundler ile build karşılaştırması yapardım.

params, searchParams, cookies() ve headers() Artık Tamamen Async

Next.js 15 aslında bizi bu değişikliğe hazırlamıştı.

params, searchParams, cookies(), headers() ve draftMode() gibi request-time API'leri Next.js 15 ile asynchronous hâle geldi. Ancak geriye dönük uyumluluk amacıyla senkron kullanım geçici olarak çalışmaya devam ediyordu.

Next.js 16 ile bu tolerans sona erdi.

Senkron erişim artık tamamen kaldırıldı.

Örneğin eskiden şöyle bir kullanım görebiliyorduk:

export default function Page({
  params,
}: {
  params: { slug: string }
}) {
  const { slug } = params

  return <div>{slug}</div>
}

Next.js 16 ile yaklaşım şu şekilde olmalı:

export default async function Page({
  params,
}: {
  params: Promise<{ slug: string }>
}) {
  const { slug } = await params

  return <div>{slug}</div>
}

Aynı durum cookies() için de geçerli.

Eski kullanım:

import { cookies } from 'next/headers'

const cookieStore = cookies()
const token = cookieStore.get('token')

Yeni kullanım:

import { cookies } from 'next/headers'

const cookieStore = await cookies()
const token = cookieStore.get('token')

Özellikle büyük App Router projelerinde migration sonrası ilk arayacağım şeylerden biri bu olur.

Çünkü sadece page.tsx dosyaları değil; layout'lar, Route Handler'lar, generateMetadata, Open Graph image route'ları ve benzeri alanlarda da params kullanımı bulunabiliyor.

Next.js bunun için ayrıca:

npx next typegen

komutuyla PageProps, LayoutProps ve RouteContext gibi type helper'ları üretebiliyor.

middleware.ts Yerini proxy.ts'ye Bırakıyor

Bir diğer dikkat çekici değişiklik isimlendirme tarafında.

Next.js 16 ile middleware.ts convention'ı deprecated edildi ve yerine proxy.ts geldi. Amaç, bu katmanın Express tarzı genel bir middleware olmadığını, uygulamanın önündeki network boundary üzerinde çalıştığını daha net anlatmak.

Eskiden:

// middleware.ts

export function middleware(request: NextRequest) {
  // ...
}

Yeni yapıda:

// proxy.ts

export function proxy(request: NextRequest) {
  // ...
}

Migration için ayrı bir codemod da bulunuyor:

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

Burada sadece dosya adı değişmiyor. Export edilen middleware fonksiyonunun da proxy olarak değiştirilmesi öneriliyor.

Daha kritik nokta ise runtime.

proxy.ts Node.js runtime üzerinde çalışıyor ve runtime manuel olarak değiştirilemiyor. Edge runtime'a bağımlı mevcut Middleware implementasyonlarında bu nedenle geçiş ayrıca değerlendirilmek zorunda.

Authentication, locale yönlendirmeleri, rewrite veya authorization kontrollerini Middleware içerisinde yoğun kullanan projelerde bu bölümü özellikle test etmek gerekiyor.

next lint Artık Yok

Bana göre küçük görünen ama CI pipeline'larını kolayca kırabilecek değişikliklerden biri de bu.

Next.js 16 ile:

next lint

komutu kaldırıldı.

Aynı zamanda next build artık otomatik olarak lint çalıştırmıyor. Next.js lint sürecini framework build'inden ayırarak doğrudan ESLint CLI kullanımına bırakıyor.

Bu nedenle package.json içinde şöyle bir script varsa:

{
  "scripts": {
    "lint": "next lint"
  }
}

bunu örneğin:

{
  "scripts": {
    "lint": "eslint ."
  }
}

şeklinde değiştirmek gerekiyor.

Migration codemod'u bu dönüşüm konusunda da yardımcı olabiliyor.

Özellikle CI/CD tarafında build öncesinde npm run lint çalıştırılıyorsa bunu migration checklist'ine mutlaka eklemek lazım.

next/image Varsayılanları Değişti

Next.js 16 image optimization tarafında da bazı varsayılanları değiştirdi.

Örneğin images.minimumCacheTTL varsayılan değeri 60 saniyeden 4 saate çıkarıldı. Ayrıca image quality tarafında önceki geniş kalite aralığı yerine varsayılan olarak yalnızca [75] kullanılıyor.

Projede şu tarz kullanımlar varsa:

<Image
  src="/product.jpg"
  width={800}
  height={600}
  quality={100}
  alt="Product"
/>

ve quality={100} davranışının korunması isteniyorsa bunu config içerisinde açıkça belirtmek gerekebilir:

const nextConfig = {
  images: {
    qualities: [50, 75, 100],
  },
}

export default nextConfig

Bir başka breaking change ise local image URL'lerinde query string kullanımı.

Örneğin:

<Image
  src="/assets/product.jpg?v=2"
  width={500}
  height={500}
  alt="Product"
/>

gibi bir kullanımınız varsa artık uygun images.localPatterns configuration'ı tanımlamanız gerekebilir. Bu değişikliğin arkasında local image enumeration saldırılarını engelleme amacı bulunuyor.

E-ticaret veya CMS tabanlı projelerde image URL yapıları dinamik olabildiği için migration sırasında bu kısmı gözden kaçırmamak önemli.

Cache Components ile Caching Daha Açık Hâle Geliyor

Next.js'in son birkaç major sürümünde en kafa karıştırıcı konulardan biri caching oldu.

"Bu fetch neden cache'lendi?", "Bu route neden static oldu?", "Revalidation neden hemen görünmedi?" gibi sorular App Router kullanan hemen herkesin en az bir kere karşısına çıktı.

Next.js 16 ile bu model daha explicit bir yapıya doğru taşınıyor.

Cache Components özelliği:

const nextConfig = {
  cacheComponents: true,
}

export default nextConfig

ile aktif edilebiliyor ve "use cache" directive'i üzerinden hangi component veya fonksiyonun cache'leneceğini daha açık şekilde kontrol etmeyi sağlıyor. Eski experimental.ppr yaklaşımı da Cache Components modeline taşındı.

Burada önemli bir nokta var:

Next.js 16'ya geçmek için Cache Components kullanmak zorunda değilsiniz.

Ben migration sırasında caching mimarisini aynı commit içerisinde baştan yazmak yerine önce framework migration'ını stabil hâle getirip Cache Components geçişini ayrı bir çalışma olarak ele almayı daha güvenli buluyorum.

Çünkü major version migration ile caching mimarisi değişikliğini aynı anda yapmak bir problem çıktığında kaynağını bulmayı zorlaştırıyor.

revalidateTag() Değişti, updateTag() Geldi

Caching tarafında API seviyesinde de önemli değişiklikler bulunuyor.

revalidateTag() için ikinci bir cacheLife profile parametresi kullanımı artık önerilen yaklaşım:

import { revalidateTag } from 'next/cache'

revalidateTag('blog-posts', 'max')

Bu kullanım stale-while-revalidate mantığıyla mevcut cache'i stale olarak işaretliyor ve yeni içeriğin arka planda alınmasını sağlıyor.

Tek parametreli kullanım ise deprecated durumda.

Next.js 16 ayrıca updateTag() API'sini getiriyor.

'use server'

import { updateTag } from 'next/cache'

export async function updateProfile() {
  // database update

  updateTag('user-profile')
}

updateTag(), özellikle kullanıcının bir veriyi değiştirdikten hemen sonra güncel hâlini görmesi gereken senaryolar için tasarlanmış durumda. API yalnızca Server Actions içerisinden kullanılabiliyor.

Kısaca ben ayrımı şöyle düşünüyorum:

Blog, katalog veya dokümantasyon gibi birkaç saniyelik gecikmenin sorun olmadığı içeriklerde revalidateTag(); kullanıcının kendi yaptığı değişikliği hemen görmesi gereken işlemlerde ise updateTag().

React Compiler Artık Stable, Ama Açmak Zorunda Değiliz

Next.js 16 ile React Compiler desteği stable hâle geldi.

React Compiler component'leri otomatik olarak memoize ederek gereksiz render'ları azaltmayı hedefliyor. Ancak özellik varsayılan olarak açık değil.

Aktif etmek için:

const nextConfig = {
  reactCompiler: true,
}

export default nextConfig

ve ilgili compiler paketini yüklemek gerekiyor:

npm install -D babel-plugin-react-compiler

Burada migration sırasında yine aynı yaklaşımı tercih ederim:

Önce Next.js 16 migration'ını tamamla, application behavior'ını doğrula, ardından React Compiler'ı ayrı bir optimizasyon adımı olarak değerlendir.

Çünkü React Compiler build pipeline'ına ek iş yükü getiriyor ve Next.js dokümantasyonu da development ve production build sürelerinin artabileceğini belirtiyor.

Next.js 16 Migration Sonrası Neleri Test Etmeliyiz?

Kod compile oluyor diye migration tamamlanmış sayılmaz.

Ben production'a çıkmadan önce özellikle şu alanları kontrol ederdim:

  •  Node.js, TypeScript, React ve Next.js sürümleri desteklenen seviyede mi?
  •  Development ve production build Turbopack ile sorunsuz çalışıyor mu?
  •  Custom Webpack configuration varsa Turbopack karşılığı kontrol edildi mi?
  •  params, searchParams, cookies(), headers() ve draftMode() senkron kullanımları temizlendi mi?
  •  middleware.ts kullanılan projelerde proxy.ts migration'ı kontrol edildi mi?
  •  Authentication, redirect, rewrite ve locale yönlendirmeleri çalışıyor mu?
  •  next lint kullanan script ve CI pipeline'ları güncellendi mi?
  •  next/image quality, cache ve local URL davranışları test edildi mi?
  •  ISR, cache invalidation ve Server Action sonrasındaki veri güncellemeleri beklenen şekilde çalışıyor mu?
  •  Dynamic route'lar ve generateMetadata fonksiyonları test edildi mi?
  •  Production build sonrası kritik sayfalar Lighthouse ve gerçek kullanıcı akışlarıyla kontrol edildi mi?

Bunun yanında migration'ı doğrudan production branch üzerinde yapmak yerine ayrı bir branch açıp mevcut Next.js 15 build'iyle karşılaştırmak ciddi zaman kazandırıyor.

Next.js 16 Geçişinde Nasıl Bir Yol İzlemeli?

Yeni bir major sürüme geçmek tek başına bir hedef olmamalı. Aktif olarak geliştirilen ve uzun süre kullanılmaya devam edecek bir Next.js projesinde güncel major sürüme yaklaşmak; güvenlik güncellemeleri, framework geliştirmeleri ve ekosistem desteği açısından önemli avantajlar sağlayabilir.

Ancak custom Webpack plugin’leri, Edge Middleware bağımlılığı veya framework’ün eski davranışlarına sıkı şekilde bağlı büyük bir production uygulamasında migration’ın plansız yapılması gereksiz risk oluşturabilir.

Bu nedenle major version migration’larını sıradan bir dependency güncellemesi yerine küçük bir teknik proje gibi ele almak daha sağlıklı bir yaklaşım.

Next.js 16 ilk bakışta Turbopack, React Compiler ve Cache Components gibi yeni özelliklerle öne çıkıyor. Fakat mevcut bir projeyi migrate ederken asıl dikkat edilmesi gereken noktalar breaking change’ler.

Turbopack’in varsayılan hâle gelmesi build pipeline’ını, async Request API’leri App Router kodunu, proxy.ts değişikliği request katmanını, ESLint değişiklikleri CI/CD süreçlerini ve yeni caching API’leri veri güncelleme stratejisini doğrudan etkileyebiliyor.

Bu yüzden geçiş sırasında izlenebilecek en güvenli sıra oldukça basit:

Önce uyumluluk, sonra migration, ardından optimizasyon.

İlk olarak dependency’leri ve çalışma ortamını güncellemek, ardından breaking change’leri gidermek ve mevcut uygulama davranışını doğrulamak gerekiyor. Turbopack, Cache Components ve React Compiler gibi yeni özellikler ise migration tamamlandıktan sonra kontrollü şekilde devreye alınabilir.

Çünkü Next.js 16’ya geçmek ile Next.js 16’nın sunduğu tüm yeni özellikleri aynı anda kullanmaya başlamak aynı şey değil.

Next.js’in sunduğu codemod ve upgrade araçları sayesinde doğru sırayla ilerlediğinizde Next.js 15’ten 16’ya geçiş düşündüğünüz kadar sancılı olmak zorunda değil.

Ölçeklenebilir, performanslı ve güncel teknolojiler üzerine kurulu bir web uygulaması geliştirmek veya mevcut projenizin teknik altyapısını modernize etmek istiyorsanız Detartech’in web geliştirme çözümleriyle projenizi uçtan uca ele alabilirsiniz.

Bir projeniz mi var?

Bu yazıda bahsettiğimiz teknolojileri projenizde hayata geçirelim.

Ücretsiz Keşif Görüşmesi İste