Next.js 15 is out! What's new and what broke?

The release of Next.js 15 marks a significant milestone for web developers who rely on this powerful framework to build modern web applications. Next.js 15 brings a host of new features, improvements, and some breaking changes that developers need to be aware of.

In this article, we'll explore everything you need to know about Next.js 15. We will answer key questions such as:

  • What are the major new features in Next.js 15?

  • Are there any breaking changes?

  • How does one upgrade to Next.js 15?

  • What improvements can developers expect?

  • What are the potential pitfalls or issues to watch out for?

Whether you're considering upgrading your existing Next.js project or starting a new one, this comprehensive guide will equip you with the knowledge you need to make informed decisions.

Major New Features

Support for React 19

One of the most anticipated features in Next.js 15 is support for React 19. This integration brings several benefits, including improved performance and new capabilities that React 19 offers. However, it's important to note that Next.js 15 retains backward compatibility with React 18, ensuring a smooth transition for projects that are not yet ready to upgrade to React 19.

More details on React 19 can be found in Vercel's What's new in React 19 guide. For a more detailed upgrade guide, see React's official React 19 RC Upgrade Guide

Enhanced CLI and Codemods

Next.js 15 introduces new tools and commands to facilitate the upgrade process. The updated CLI includes the npx @next/codemod@canary upgrade command, which automates upgrades to the latest stable or prerelease versions of Next.js and React. This feature is designed to save developers time and reduce the risk of human error during the upgrade process.

Turbopack Dev (Stable)

Turbopack Dev has reached stability in Next.js 15, offering significant performance improvements during development. This includes faster builds and Hot Module Replacement (HMR) updates.

Turbopack offers a significantly faster development experience:

  • 76.7% faster local server startup.

  • 96.3% faster code updates with Fast Refresh.

  • 45.8% faster initial route compilation without caching.

More details can be found in the Turbopack Dev announcement.

Static Route Indicator

The Static Route Indicator is a new feature that enhances the development experience by clearly distinguishing between static and dynamic routes. This visual aid helps developers understand the behavior of their application's routes and optimize their performance accordingly.

Enhanced Forms (next/form)

Next.js 15 brings significant improvements to form handling with the new next/form module.

The new <Form> component extends the standard <form> with features like prefetching, client-side navigation, and progressive enhancement.

Example:

import { Form } from 'next/form';

<Form action="/search">
  <input name="query" />
  <button type="submit">Submit</button>
</Form>

While these improvements aim to provide a smoother and more efficient user experience when handling forms in Next.js applications, Lee Rob has also mentioned in the Next.js 15 RC 2 Video that developers may not want to use this form everywhere. The use case is mostly for when you are navigating to a route that has an updated URL search params.

In his words:

If you are just going to pass it to a function for the action, you probably don't need to use next/form

Executing Code After Response

The new unstable_after API allows scheduling of tasks after the response has been streamed, useful for logging, analytics, and synchronization tasks.

Example:

import { unstable_after as after } from 'next/server';

after(() => {
  // Perform some logging
});

Remember to enable this experimental feature in next.config.ts:

const nextConfig = {
  experimental: {
    after: true,
  },
};
 
export default nextConfig;

New Observability APIs (instrumentation.js)

Next.js 15 introduces new observability APIs, including instrumentation.js, which provides lifecycle observability for applications. This API supports integration with popular observability tools like OpenTelemetry and Sentry, allowing developers to gain deeper insights into their application's performance and behavior.

More details on instrumentation can be found in the Next.js 15 Release Blog Post

TypeScript Support

TypeScript support continues to improve in Next.js 15, with the addition of support for next.config.ts. This allows developers to write their Next.js configuration files in TypeScript, leveraging the benefits of type checking and autocompletion.

Breaking Changes

Async Request APIs

One of the breaking changes in Next.js 15 is the transition to asynchronous request APIs. APIs such as cookies, headers, and draftMode are now asynchronous, requiring developers to update their code accordingly. Here's an example of how to handle cookies with the new asynchronous API:

// Before
const cookieStore = cookies();
const token = cookieStore.get('token');

// After
const cookieStore = await cookies();
const token = cookieStore.get('token');

Similarly, the headers and draftMode APIs have been updated to async. These changes are aimed at improving performance and scalability by leveraging asynchronous operations.

Caching Semantics

Next.js 15 brings updates to the default caching behavior, particularly for fetch requests and route handlers. By default, fetch requests are now configured with a no-store cache option unless explicitly specified otherwise. This means that developers will need to set caching options explicitly when making fetch requests if they want to improve performance with caching mechanisms. Here's an example:

// Before
const response = await fetch('/api/data');

// After
const response = await fetch('/api/data', { cache: 'force-cache' });

Runtime Configuration

The runtime configuration in Next.js 15 sees the removal of the experimental-edge keyword, which has been replaced simply by edge. For developers using edge functions, this change necessitates an update to their configuration files. A provided codemod can assist in automating this process.

Next/font Package Removal

In previous versions of Next.js, the @next/font package was used for custom fonts. With Next.js 15, this package has been removed in favor of the built-in next/font. Developers will need to update their imports accordingly:

// Before
import { Inter } from '@next/font/google';

// After
import { Inter } from 'next/font/google';

Geolocation and IP Address Removal

In Next.js 15, the properties geo and ip have been removed from NextRequest. For developers who need to access these properties, especially those deploying on Vercel, the @vercel/functions package can be used as an alternative:

import { geolocation } from '@vercel/functions';
import { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  const { city } = geolocation(request);
}

Potential Issues and How to Handle Them

Hydration Error Handling

Hydration errors can be a significant source of frustration for developers. In Next.js 15, hydration error messages have been improved to display more detailed information, including the source code and suggestions for resolving the issue. This enhancement aims to make it easier for developers to debug and fix hydration errors quickly.

Client-side Router Cache Changes

Another notable change in Next.js 15 is the update to the client-side router cache. Segments are no longer reused from the client-side router cache during navigation with <Link> or useRouter. To manage caching, developers can use the staleTimes config option to specify cache durations for individual page segments. This allows for more granular cache control:

// next.config.js
module.exports = {
  experimental: {
    staleTimes: {
      dynamic: 30,
      static: 180,
    },
  },
};

Deprecated Features Adjustments

Several features have been deprecated in Next.js 15, requiring developers to adjust their code accordingly. For example, changes in the next/image component may affect how images are handled in applications. Developers should consult the official upgrade guide and take advantage of the provided codemods to automate these adjustments.

Performance and Security Improvements

Incremental and Static Generation Improvements

Next.js 15 introduces enhancements to both incremental and static generation. This includes faster build times and better performance during static generation. By reusing the first render and sharing cache across static generation workers, Next.js 15 aims to reduce build times and improve efficiency.

Server Actions Security

Security improvements in Next.js 15 include the introduction of unguessable, non-deterministic IDs for server actions. These IDs help improve security by making it harder for malicious actors to predict and exploit server action endpoints. Additionally, dead code elimination is performed on unused server actions, further enhancing security by reducing the attack surface.

Migration Steps and Resources

Using Codemods for Automatic Upgrades

To simplify the upgrade process, Next.js 15 provides codemods that automate many of the required changes. Developers can use the following command to upgrade their projects:

npx @next/codemod@canary upgrade latest

This command will handle the majority of breaking changes and updates, making the migration process smoother and less error-prone.

Manual Upgrade Instructions

For developers who prefer to perform the upgrade manually, Next.js 15 offers detailed instructions. Begin by installing the latest Release Candidates (RC) for Next.js, React, and other dependencies:

npm install next@canary react@rc react-dom@rc eslint-config-next@rc

For TypeScript users, it may be necessary to temporarily override React types during the upgrade process.

In package.json:

"pnpm": {
  "overrides": {
    "@types/react": "npm:types-react@19.0.0-rc.1",
    "@types/react-dom": "npm:types-react-dom@19.0.0-rc.1"
  }
}

Additional Resources and References

To assist with the upgrade, a variety of resources and references are available:

Conclusion

Next.js 15 brings a wealth of new features, performance improvements, and some breaking changes that developers need to be mindful of. The support for React 19, enhanced CLI tools, and new observability APIs provide exciting opportunities for building dynamic and high-performance web applications. However, developers should carefully review the breaking changes and adjust their code accordingly to ensure a smooth transition.

We encourage developers to start the upgrade process and explore the new features in Next.js 15. For more detailed information, check out the official Next.js 15 blog and the comprehensive upgrade guides provided by the Next.js team.

Raymond Yeh

Raymond Yeh

Published on 22 October 2024

Get engineers' time back from marketing!

Don't let managing a blog on your site get in the way of your core product.

Wisp empowers your marketing team to create and manage content on your website without consuming more engineering hours.

Get started in few lines of codes.

Choosing a CMS
Related Posts
My Experience Navigating the Next.js 15 Upgrade

My Experience Navigating the Next.js 15 Upgrade

Next.js 15 was released today and I've tried upgrading my project from Next.js 14. Codegen helped to fix 80-90% of the issues but there were issues due to upgrade from React 18 to 19!

Read Full Story
Upgrading to Next.js 15  in 5 Mins using Codemod

Upgrading to Next.js 15 in 5 Mins using Codemod

Upgrade your Next.js project in record time! Discover my step-by-step journey upgrading to Next.js 15,using the official codemode tool. Watch the video too!

Read Full Story
Mental Model for Client/Server Components, Static/Dynamic Route & Caching in Next.js

Mental Model for Client/Server Components, Static/Dynamic Route & Caching in Next.js

Confused about Server Component vs Client Component, Dynamic vs Static Routes & Caching in Next.js? You are not alone. Use this mental model to help you!

Read Full Story