Next.js 15 RC?—?A New Story
Hamza Siddique
MERN Stack Developer @ Desol Int. | AWS | React.js | React Native (Expo) | Next.js | Node.js | Express.js | Nest.js | TypeScript | MERN Stack | Tailwind CSS | GraphQL | Docker (DevOps) | Angular | MEAN Stack
In this article, we will understand which new features are coming to Next.js 15 and which features are improving from previous versions.
The Next.js 15 Release Candidate (RC) is now available, offering an opportunity to test the latest features before the stable release.
New command to install Next.js 15 app
npm install next@rc react@rc react-dom@rc
React 19 RC The Next.js App Router is built on the React canary channel for frameworks, which has allowed developers to use and provide feedback on these new React APIs before the v19 release.
React Compiler (Experimental) The React team at Meta has developed an experimental new compiler for React. This compiler deeply comprehends your code by understanding both plain JavaScript semantics and the Rules of React, enabling it to apply automatic optimizations. Consequently, developers can rely less on manual memoization using APIs like useMemo and useCallback, resulting in code that is simpler, easier to maintain, and less prone to errors.
Next.js 15 now includes support for the React Compiler.
Install babel-plugin-react-compiler:
npm install babel-plugin-react-compiler
Then, add experimental.reactCompiler option in next.config.js:
const nextConfig = {
experimental: {
reactCompiler: true,
},
};
module.exports = nextConfig;
Optionally, you can configure the compiler to run in “opt-in” mode as follows:
const nextConfig = {
experimental: {
reactCompiler: {
compilationMode: 'annotation',
},
},
};
module.exports = nextConfig;
Hydrations Error Improvements
Next.js 14.1 enhanced error messages and addressed hydration errors. Building on these improvements, Next.js 15 introduces a refined hydration error view. Hydration errors now show the source code of the error along with suggestions for resolving the issue.
For instance, here is what a hydration error message looked like in Next.js 14.1:
Next.js 15 RC has improved this to:
Caching Updates Next.js App Router initially launched with opinionated caching defaults aimed at providing optimal performance out of the box, with the flexibility to opt-out if needed. With Next.js 15, it changes the caching default for fetch requests, GET Route Handlers, and the Client Router Cache from cached by default to uncached. If you prefer the previous behavior, you can still opt into caching.
“fetch” Request are no longer cached by defaults In Next.js, the Web fetch API’s cache option configures how a server-side fetch request interacts with the framework’s persistent HTTP cache:
fetch('https://...', { cache: 'force-cache' | 'no-store' });
no-store: Fetches a resource from a remote server on every request and does not update the cache. force-cache: Fetches a resource from the cache (if it exists) or from a remote server and updates the cache.
In Next.js 14, force-cache was the default setting if no cache option was provided, unless a dynamic function or dynamic config option was used.
In Next.js 15, no-store is the default setting if no cache option is provided. This means fetch requests will not be cached by default.
You can still enable caching for fetch requests by:
“GET” Routes handlers are no longer cached by default In Next.js 14, Route Handlers using the GET HTTP method were cached by default, unless they utilized a dynamic function or dynamic config option. In Next.js 15, GET functions are no longer cached by default.
You can still enable caching by using a static route config option, such as
export const dynamic = 'force-static'
Special Route Handlers, like sitemap.ts, opengraph-image.tsx, icon.tsx, and other metadata files, remain static by default unless they use dynamic functions or dynamic config options.
Client Router Cache no longer caches Page components by default In Next.js 14.2.0, developers introduced an experimental staleTimes flag for custom configuration of the Router Cache.
In Next.js 15, while this flag is still accessible, the default behavior has changed: the staleTime for Page segments is now set to 0. This means that during navigation, the client will always reflect the latest data from the active Page component(s). However, several behaviors remain unchanged:
To revert to the previous Client Router Cache behavior, set the following configuration:
领英推荐
const nextConfig = {
experimental: {
staleTimes: {
dynamic: 30,
},
},
};
module.exports = nextConfig;
Incremental Adoption of Partial Prerendering (Experimental) In Next.js 14, developers introduced Partial Prerendering (PPR), an optimization that combines static and dynamic rendering within the same page.
By default, Next.js uses static rendering unless dynamic functions like cookies(), headers(), or uncached data requests are used. These APIs switch the entire route to dynamic rendering. With PPR, you can wrap dynamic UI components in a Suspense boundary. When a new request comes in, Next.js serves a static HTML shell right away, then renders and streams the dynamic parts within the same HTTP request.
To support incremental adoption, we’ve added an experimental_ppr route configuration option that lets you opt specific Layouts and Pages into PPR.
import { Suspense } from "react"
import { StaticComponent, DynamicComponent } from "@/app/ui"
export const experimental_ppr = true
export default function Page() {
return {
<>
<StaticComponent />
<Suspense fallback={...}>
<DynamicComponent />
</Suspense>
</>
};
}
To use the new option, you’ll need to set the experimental.ppr config in your next.config.js file to 'incremental':
const nextConfig = {
experimental: {
ppr: 'incremental',
},
};
module.exports = nextConfig;
Executing code after a response with next/after (Experimental) When processing a user request, the server usually focuses on tasks directly related to generating the response. However, there are often additional tasks like logging, analytics, and synchronizing with external systems that also need to be performed.
These tasks are not directly tied to the response, so the user shouldn’t have to wait for them to complete. Deferring this work until after the response is sent can be challenging because serverless functions stop executing as soon as the response is finished.
To address this, developers have introduced after(), a new experimental API that allows you to schedule tasks to run after the response has finished streaming. This enables secondary tasks to be processed without delaying the primary response.
To use this feature, add experimental.after to your next.config.js file:
const nextConfig = {
experimental: {
after: true,
},
};
module.exports = nextConfig;
Then, import the function in Server Components, Server Actions, Route Handlers, or Middleware.
import { unstable_after as after } from 'next/server';
import { log } from '@/app/utils';
export default function Layout({ children }) {
// Secondary task
after(() => {
log();
});
// Primary task
return <>{children}</>;
}
create-next-app Updates For Next.js 15, developers have updated create-next-app with a new design.
When running create-next-app, there is a new prompt asking if you want to enable Turbopack for local development (defaults to No).
? Would you like to use Turbopack for next dev? … No / Yes
The --turbo flag can be used to enable Turbopack.
npx create-next-app@rc --turbo
To make getting started on a new project even easier, a new --empty flag has been added to the CLI. This will remove any extraneous files and styles, resulting in a minimal "hello world" page.
npx create-next-app@rc --empty
Optimizing bundling of external packages (Stable) Bundling external packages can enhance the initial loading speed of your application. By default, in the App Router, external packages are bundled, and you can exclude specific ones using the new serverExternalPackages configuration option.
In the Pages Router, external packages aren’t bundled by default. However, you can specify a list of packages to bundle using the existing transpilePackages option. With this setup, you have to explicitly list each package.
To streamline configuration between the App and Pages Router, developers are introducing a new option, bundlePagesRouterDependencies. This aligns with the automatic bundling behavior of the App Router by default. You can then utilize serverExternalPackages to exclude specific packages if necessary.
const nextConfig = {
// Automatically bundle external packages in the Pages Router:
bundlePagesRouterDependencies: true,
// Opt specific packages out of bundling for both App and Pages Router:
serverExternalPackages: ['package-name'],
};
module.exports = nextConfig;
Conclusion
In conclusion, Next.js 15 brings a plethora of exciting features and enhancements that promise to elevate the development experience for both newcomers and seasoned developers alike.
Firstly, with support for React 19 RC and the introduction of the experimental React Compiler, developers gain access to cutting-edge tools that aim to simplify code optimization and reduce manual memoization efforts. This not only streamlines development but also enhances the performance and maintainability of React applications.
Next.js 15 also introduces significant improvements in caching mechanisms, with fetch requests, GET Route Handlers, and Client Router Cache now defaulting to uncached behavior. This change offers more control over caching strategies while maintaining flexibility for developers who require caching in specific scenarios.
The addition of features like Partial Prerendering and the after() API further expands the toolkit available to developers. These experimental features empower developers to fine-tune their applications for optimal performance and user experience, all while maintaining flexibility and ease of use.
Moreover, updates to tools like create-next-app streamline project setup and initialization, making it easier than ever to kickstart new projects with Next.js 15. The redesigned interface and new options like Turbopack support provide developers with more choices and flexibility from the outset.
Lastly, enhancements to bundling external packages ensure faster loading speeds and improved performance for Next.js applications. By automating bundling behaviors and providing granular control over package inclusion and exclusion, developers can optimize their applications with ease.
Overall, Next.js 15 represents a significant milestone in the evolution of the framework, offering a comprehensive suite of features and improvements that empower developers to build faster, more efficient, and more scalable web applications. Whether you’re a seasoned pro or just starting out, Next.js 15 has something to offer for everyone in the ever-changing landscape of web development.
Happy Coding?!