Version 15
Upgrade your Next.js Application from Version 14 to 15.
Upgrading from 14 to 15
To update to Next.js version 15, you can use the upgrade
codemod:
If you prefer to do it manually, ensure that you're installing the latest Next & React versions:
Good to know:
- If you see a peer dependencies warning, you may need to update
react
andreact-dom
to the suggested versions, or you use the--force
or--legacy-peer-deps
flag to ignore the warning. This won't be necessary once both Next.js 15 and React 19 are stable.
React 19
- The minimum versions of
react
andreact-dom
is now 19. useFormState
has been replaced byuseActionState
. TheuseFormState
hook is still available in React 19, but it is deprecated and will be removed in a future release.useActionState
is recommended and includes additional properties like reading thepending
state directly. Learn more.useFormStatus
now includes additional keys likedata
,method
, andaction
. If you are not using React 19, only thepending
key is available. Learn more.- Read more in the React 19 upgrade guide.
Good to know: If you are using TypeScript, ensure you also upgrade @types/react
and @types/react-dom
to their latest versions.
Async Request APIs (Breaking change)
Previously synchronous Dynamic APIs that rely on runtime information are now asynchronous:
cookies
headers
draftMode
params
inlayout.js
,page.js
,route.js
,default.js
,opengraph-image
,twitter-image
,icon
, andapple-icon
.searchParams
inpage.js
To ease the burden of migration, a codemod is available to automate the process and the APIs can temporarily be accessed synchronously.
cookies
Recommended Async Usage
Temporary Synchronous Usage
headers
Recommended Async Usage
Temporary Synchronous Usage
draftMode
Recommended Async Usage
Temporary Synchronous Usage
params
& searchParams
Asynchronous Layout
Synchronous Layout
Asynchronous Page
Synchronous Page
Route Handlers
runtime
configuration (Breaking change)
The runtime
segment configuration previously supported a value of experimental-edge
in addition to edge
. Both configurations refer to the same thing, and to simplify the options, we will now error if experimental-edge
is used. To fix this, update your runtime
configuration to edge
. A codemod is available to automatically do this.
fetch
requests
fetch
requests are no longer cached by default.
To opt specific fetch
requests into caching, you can pass the cache: 'force-cache'
option.
To opt all fetch
requests in a layout or page into caching, you can use the export const fetchCache = 'default-cache'
segment config option. If individual fetch
requests specify a cache
option, that will be used instead.
Route Handlers
GET
functions in Route Handlers are no longer cached by default. To opt GET
methods into caching, you can use a route config option such as export const dynamic = 'force-static'
in your Route Handler file.
Client-side Router Cache
When navigating between pages via <Link>
or useRouter
, page segments are no longer reused from the client-side router cache. However, they are still reused during browser backward and forward navigation and for shared layouts.
To opt page segments into caching, you can use the staleTimes
config option:
Layouts and loading states are still cached and reused on navigation.
next/font
The @next/font
package has been removed in favor of the built-in next/font
. A codemod is available to safely and automatically rename your imports.
bundlePagesRouterDependencies
experimental.bundlePagesExternals
is now stable and renamed to bundlePagesRouterDependencies
.
serverExternalPackages
experimental.serverComponentsExternalPackages
is now stable and renamed to serverExternalPackages
.
Speed Insights
Auto instrumentation for Speed Insights was removed in Next.js 15.
To continue using Speed Insights, follow the Vercel Speed Insights Quickstart guide.
NextRequest
Geolocation
The geo
and ip
properties on NextRequest
have been removed as these values are provided by your hosting provider. A codemod is available to automate this migration.
If you are using Vercel, you can alternatively use the geolocation
and ipAddress
functions from @vercel/functions
instead: