Next.js 15 Whats new?

Ali Khan
Tensor Labs
Published in
8 min readSep 30, 2024
Next.js

The Next.js 15 Release Candidate (RC) has officially been made available, providing developers with the opportunity to test new features ahead of the stable release. This early version brings a host of updates and experimental features aimed at improving the performance, flexibility, and development experience of Next.js applications.

Key Features in Next.js 15 RC:

React 19 RC Support
Next.js 15 introduces support for the React 19 Release Candidate, including enhancements for handling hydration errors and experimental integration with the React Compiler. These updates aim to streamline component rendering and error management, aligning Next.js closely with the upcoming React 19 version.

Caching Improvements
One of the key changes in Next.js 15 is the adjustment of caching behavior. By default, fetch requests, GET Route Handlers, and client-side navigations will no longer be cached. This shift gives developers more control over caching strategies, ensuring that applications can dynamically fetch fresh data without relying on stale cache by default.

Partial Prerendering
A new experimental feature, Partial Prerendering, has been introduced with a Layout and Page configuration option. This allows developers to incrementally adopt prerendering for specific parts of a page, offering an optimized mix of static and dynamic rendering. This approach can significantly improve performance for applications with complex or frequently changing content.

Next/after API
The new next/after API enables developers to execute code after a response has finished streaming to the client. This feature is designed to handle tasks that don’t block user interaction, such as background processing, logging, or analytics. It offers a more efficient way to manage server-side processes that don’t need to impact the user experience.

Updated create-next-app
The create-next-app CLI has been refreshed with a modernized design. Additionally, a new flag has been introduced to enable Turbopack during local development. Turbopack is designed to significantly speed up the build process, improving the developer experience by reducing waiting times for code changes to take effect.

Bundling External Packages
Next.js 15 also provides new configuration options for bundling external packages within both the App Router and Pages Router. This stable feature allows for greater flexibility in how dependencies are packaged, potentially optimizing build sizes and improving application performance.

These new features in the Next.js 15 RC highlight a strong focus on performance optimization, better error handling, and more control over build processes, positioning it as a powerful tool for modern web development. Developers can now begin testing these updates and prepare for the official stable release.

React 19 RC Support

The Next.js App Router is built on the React canary channel, allowing developers to explore and provide feedback on upcoming React APIs ahead of their official release. With Next.js 15 RC, support for React 19 RC is now available, introducing new capabilities for both client-side and server-side rendering, such as Actions.

React Compiler (Experimental)

The React Compiler, developed by the React team at Meta, is a groundbreaking experimental tool designed to deeply understand your code by interpreting JavaScript semantics and React’s internal rules. This enables the compiler to automatically optimize code, reducing the need for developers to manually implement memoization through hooks like useMemo and useCallback. The result is cleaner, more maintainable code with fewer opportunities for errors.

With Next.js 15, support for the React Compiler has been integrated, giving developers access to these advanced optimizations. To begin using it, you can install the compiler by adding the babel-plugin-react-compiler to your project.

With Next.js 15, support for the React Compiler has been introduced, allowing developers to take advantage of its automatic optimizations.

To get started, simply install the babel-plugin-react-compiler in your project.

npm install babel-plugin-react-compiler

Then, add experimental.reactCompiler option in next.config.js

const nextConfig = {
experimental: {
reactCompiler: true,
},
};
module.exports = nextConfig;

The React Compiler can currently only be utilized in Next.js via a Babel plugin, which may lead to slower build times.

Hydration Error Improvements

Following the advancements made in Next.js 14.1 with enhanced error messages and hydration handling, Next.js 15 introduces further improvements by providing a more detailed hydration error view. Now, when a hydration error occurs, the source code related to the issue is displayed along with suggestions for resolving the problem, offering clearer guidance for developers.

Caching Updates in Next.js 15

When Next.js introduced the App Router, it came with opinionated caching defaults aimed at maximizing performance, with flexibility for developers to opt out when necessary. After gathering feedback from the community, the caching approach has been re-evaluated to better align with use cases like Partial Prerendering (PPR) and third-party libraries utilizing fetch.

With the release of Next.js 15, caching defaults have been updated across key areas. Fetch requests, GET Route Handlers, and Client Router Cache are now uncached by default. If you prefer the previous caching behavior, it’s still possible to opt in.

These changes mark the beginning of ongoing improvements to caching in Next.js, with more updates expected in the official Next.js 15 GA announcement.

Fetch Requests Are No Longer Cached by Default

Next.js leverages the Web fetch API’s cache option to control how server-side requests interact with the framework’s persistent HTTP cache. In previous versions, the force-cache option was the default unless dynamic functions or configurations were specified.

In Next.js 15, the default caching behavior has been changed to no-store. This ensures that fetch requests are no longer cached unless explicitly configured. If caching is still desired, developers can opt-in by:

fetch('https://api.example.com', { cache: 'force-cache' });

Configuring a specific route to use caching with force-static

export const dynamic = 'force-static';

Using the fetchCache route config option to apply default-cache for all fetch requests in a Layout or Page

export const fetchCache = 'default-cache';

GET Route Handlers Are Now Uncached by Default

Previously, GET Route Handlers were cached by default unless dynamic functions or configurations were used. In Next.js 15, GET requests are no longer cached by default. However, caching can still be enabled by adding a static route config option such as

export const dynamic = 'force-static';

It’s important to note that specific route handlers, like sitemap.ts, opengraph-image.tsx, and icon.tsx, as well as other metadata files, remain static by default unless a dynamic configuration is applied.

Client Router Cache No Longer Caches Page Components by Default

Next.js 14.2 introduced an experimental staleTimes flag to customize the Router Cache configuration. In Next.js 15, the default staleTime for Page segments has been set to 0, meaning that the client will always fetch the latest data when navigating to a new Page component. This change ensures your app stays up-to-date with the most current content during navigation.

Despite this adjustment, some behaviors remain unchanged:

  • Shared layout data is not re-fetched, maintaining support for partial rendering.
  • Back/forward navigation restores cached pages, preserving scroll position.
  • The Loading.js component remains cached for 5 minutes (or the configured value of staleTimes.static).

These caching updates reflect Next.js’ commitment to flexibility and performance, providing developers with greater control while ensuring up-to-date content in their applications.

Introducing Partial Prerendering in Next.js 14: A Step Towards Optimized Rendering

Next.js 14 introduces an exciting new feature called Partial Prerendering (PPR), designed to enhance performance by blending static and dynamic rendering within the same page. This innovative approach allows developers to optimize their applications more effectively, providing the best of both static and dynamic content delivery.

Default Behavior: Static Rendering

Traditionally, Next.js uses static rendering by default. However, certain dynamic functions such as cookies(), headers(), or requests for uncached data automatically convert a route from static to dynamic rendering. This is helpful in cases where dynamic data or per-user customization is needed, but it often means entire pages become fully dynamic even when only a portion of the page requires it.

What Does PPR Change?

With Partial Prerendering, Next.js gives developers more fine-grained control over rendering. You can now wrap dynamic components inside a Suspense boundary, enabling Next.js to handle them separately. When a user requests a page, the server can immediately send a static HTML shell, ensuring fast load times. Meanwhile, the dynamic parts of the page will be rendered and streamed within the same HTTP request, providing a seamless user experience as they load progressively.

This approach balances the performance benefits of static rendering with the flexibility of dynamic content, making it easier to optimize Next.js applications for speed and interactivity.

Conclusion
Partial Prerendering is an experimental but promising feature in Next.js 14, giving developers more control over how content is delivered. By allowing the combination of static and dynamic rendering on a per-component basis, PPR could redefine how we think about optimizing page performance, especially for complex web applications.

Introducing the after() API: Streamlining Background Tasks in Serverless Environments

When processing a user request, a server typically focuses on generating and delivering the response as quickly as possible. However, there are often additional tasks that need to be performed, such as logging, analytics, or synchronizing with external systems. These tasks, while important, aren’t directly tied to the response itself, and users shouldn’t have to wait for them to complete.

In traditional environments, deferring such tasks until after the response is sent is straightforward. But in serverless environments, this poses a challenge — serverless functions typically halt all computation as soon as the response is finalized.

Enter the after() API

The after() API is an experimental feature designed to address this limitation. With after(), developers can schedule tasks to run once the server has finished streaming the response. This enables secondary tasks, like logging or sending analytics data, to be executed after the main response has been delivered to the user. As a result, the user experiences a faster response time without the need to wait for non-essential background operations.

Why It Matters

By allowing post-response processing, after() provides a significant boost to performance in serverless environments. Developers can ensure that critical tasks are prioritized, while secondary tasks are handled asynchronously in the background. This not only improves the overall user experience but also makes serverless applications more efficient.

Conclusion
The introduction of the after() API marks a step forward in optimizing serverless function behavior. It enables developers to handle essential background processes without impacting response times, making serverless computing more versatile and efficient for real-world applications.

Conclusion: What to Expect from Next.js 15 and Beyond

Next.js 15 introduces a range of cutting-edge features aimed at enhancing performance, flexibility, and developer experience. From React 19 RC support and the experimental React Compiler, to significant caching improvements and the innovative Partial Prerendering, this release empowers developers to build faster and more dynamic applications with greater control over rendering strategies.

The introduction of the after() API is another milestone, addressing a key challenge in serverless environments by enabling asynchronous post-response tasks, which streamlines operations without blocking user interactions.

These updates reflect Next.js’ ongoing commitment to performance and optimization, pushing the boundaries of modern web development. Developers are encouraged to explore these features in the Release Candidate and prepare for their integration in the stable release.

--

--