Thursday, April 11th 2024
Next.js 14.2
Posted byNext.js 14.2 includes development, production, and caching improvements.
- Turbopack for Development (Release Candidate): 99.8% tests passing for
next dev --turbo
. - Build and Production Improvements: Reduced build memory usage and CSS optimizations.
- Caching Improvements: Configurable invalidation periods with
staleTimes
. - Error DX Improvements: Better hydration mismatch errors and design updates.
Upgrade today or get started with:
npx create-next-app@latest
Turbopack for Development (Release Candidate)
Over the past few months, we’ve been working on improving local development performance with Turbopack. In version 14.2, the Turbopack Release Candidate is now available for local development:
- 99.8% of integrations tests are now passing.
- We’ve verified the top 300
npm
packages used in Next.js applications can compile with Turbopack. - All Next.js examples work with Turbopack.
- We’ve integrated Lightning CSS, a fast CSS bundler and minifier, written in Rust.
We’ve been extensively dogfooding Turbopack with Vercel’s applications. For example, with vercel.com
, a large Next.js app, we've seen:
- Up to 76.7% faster local server startup.
- Up to 96.3% faster code updates with Fast Refresh.
- Up to 45.8% faster initial route compile without caching (Turbopack does not have disk caching yet).
Turbopack continues to be opt-in and you can try it out with:
next dev --turbo
We will now be focusing on improving memory usage, implementing persistent caching, and next build --turbo
.
- Memory Usage - We’ve built low-level tools for investigating memory usage. You can now generate traces that include both performance metrics and broad memory usage information. These traces allows us to investigate performance and memory usage without needing access to your application’s source code.
- Persistent Caching - We’re also exploring the best architecture options, and we’re expecting to share more details in a future release.
next build
- While Turbopack is not available for builds yet, 74.7% of tests are already passing. You can follow the progress at areweturboyet.com/build.
To see a list of supported and unsupported features in Turbopack, please refer to our documentation.
Build and Production Improvements
In addition to bundling improvements with Turbopack, we’ve worked to improve overall build and production performance for all Next.js applications (both Pages and App Router).
Tree-shaking
We identified an optimization for the boundary between Server and Client Components that allows for tree-shaking unused exports. For example, importing a single Icon
component from a file that has "use client"
no longer includes all the other icons from that package. This can largely reduce the production JavaScript bundle size.
Testing this optimization on a popular library like react-aria-components
reduced the final bundle size by -51.3%.
Note: This optimization does not currently work with barrel files. In the meantime, you can use the
optimizePackageImports
config option:next.config.tsmodule.exports = { experimental: { optimizePackageImports: ['package-name'], }, };
Build Memory Usage
For extremely large-scale Next.js applications, we noticed out-of-memory crashes (OOMs) during production builds. After investigating user reports and reproductions, we identified the root issue was over-bundling and minification (Next.js created fewer, larger JavaScript files with duplication). We’ve refactored the bundling logic and optimized the compiler for these cases.
Our early tests show that on a minimal Next.js app, memory usage and cache file size decreased from 2.2GB to under 190MB on average.
To make it easier to debug memory performance, we’ve introduced a --experimental-debug-memory-usage
flag to next build
. Learn more in our documentation.
CSS
We updated how CSS is optimized during production Next.js builds by chunking CSS to avoid conflicting styles when you navigate between pages.
The order and merging of CSS chunks are now defined by the import order. For example, base-button.module.css
will be ordered before page.module.css
:
import styles from './base-button.module.css';
export function BaseButton() {
return <button className={styles.primary} />;
}
import { BaseButton } from './base-button';
import styles from './page.module.css';
export function Page() {
return <BaseButton className={styles.primary} />;
}
To maintain the correct CSS order, we recommend:
- Using CSS Modules over global styles.
- Only import a CSS Module in a single JS/TS file.
- If using global class names, import the global styles in the same JS/TS too.
We don’t expect this change to negatively impact the majority of applications. However, if you see any unexpected styles when upgrading, please review your CSS import order as per the recommendations in our documentation.
Caching Improvements
Caching is a critical part of building fast and reliable web applications. When performing mutations, both users and developers expect the cache to be updated to reflect the latest changes. We've been exploring how to improve the Next.js caching experience in the App Router.
staleTimes
(Experimental)
The Client-side Router Cache is a caching layer designed to provide a fast navigation experience by caching visited and prefetched routes on the client.
Based on community feedback, we’ve added an experimental staleTimes
option to allow the client-side router cache invalidation period to be configured.
By default, prefetched routes (using the <Link>
component without the prefetch
prop) will be cached for 30 seconds, and if the prefetch
prop is set to true
, 5 minutes. You can overwrite these default values by defining custom revalidation times in next.config.js
:
const nextConfig = {
experimental: {
staleTimes: {
dynamic: 30,
static: 180,
},
},
};
module.exports = nextConfig;
staleTimes
aims to improve the current experience of users who want more control over caching heuristics, but it is not intended to be the complete solution. In upcoming releases, we will focus on improving the overall caching semantics and providing more flexible solutions.
Learn more about staleTimes
in our documentation.
Parallel and Intercepting Routes
We are continuing to iterate on on Parallel and Intercepting Routes, now improving the integration with the Client-side Router Cache.
- Parallel and Intercepting routes that invoke Server Actions with
revalidatePath
orrevalidateTag
will revalidate the cache and refresh the visible slots while maintaining the user’s current view. - Similarly, calling
router.refresh
now correctly refreshes visible slots, maintaining the current view.
Errors DX Improvements
In version 14.1, we started working on improving the readability of error messages and stack traces when running next dev
. This work has continued into 14.2 to now include better error messages, overlay design improvements for both App Router and Pages Router, light and dark mode support, and clearer dev
and build
logs.
For example, React Hydration errors are a common source of confusion in our community. While we made improvements to help users pinpoint the source of hydration mismatches (see below), we're working with the React team to improve the underlying error messages and show the file name where the error occurred.
Before:
After:
React 19
In February, the React team announced the upcoming release of React 19. To prepare for React 19, we're working on integrating the latest features and improvements into Next.js, and plan on releasing a major version to orchestrate these changes.
New features like Actions and their related hooks, which have been available within Next.js from the React canary channel, will now all be available for all React applications (including client-only applications). We're excited to see wider adoption of these features in the React ecosystem.
Other Improvements
- [Docs] New documentation on Video Optimization (PR).
- [Docs] New documentation on
instrumentation.ts
(PR) - [Feature] New
overrideSrc
prop fornext/image
(PR). - [Feature] New
revalidateReason
argument togetStaticProps
(PR). - [Improvement] Refactored streaming logic, reducing the time to stream pages in production (PR).
- [Improvement] Support for nested Server Actions (PR).
- [Improvement] Support for localization in generated Sitemaps (PR).
- [Improvement] Visual improvements to dev and build logs (PR)
- [Improvement] Skew protection is stable on Vercel (Docs).
- [Improvement] Make
useSelectedLayoutSegment
compatible with the Pages Router (PR). - [Improvement] Skip
metadataBase
warnings when absolute URLs don’t need to be resolved (PR). - [Improvement] Fix Server Actions not submitting without JavaScript enabled when deployed to Vercel (PR)
- [Improvement] Fix error about a Server Action not being found in the actions manifest if triggered after navigating away from referring page, or if used inside of an inactive parallel route segment (PR)
- [Improvement] Fix CSS imports in components loaded by
next/dynamic
(PR). - [Improvement] Warn when animated image is missing
unoptimized
prop (PR). - [Improvement] Show an error message if
images.loaderFile
doesn't export a default function (PR)
Community
Next.js now has over 1 million monthly active developers. We're grateful for the community's support and contributions. Join the conversation on GitHub Discussions, Reddit, and Discord.
Contributors
Next.js is the result of the combined work of over 3,000 individual developers, industry partners like Google and Meta, and our core team at Vercel. This release was brought to you by:
- The Next.js team: Andrew, Balazs, Ethan, Janka, Jiachi, Jimmy, JJ, Josh, Sam, Sebastian, Sebbie, Shu, Steven, Tim, Wyatt, and Zack.
- The Turbopack team: Donny, Leah, Maia, OJ, Tobias, and Will.
- Next.js Docs: Delba, Steph, Michael, Anthony, and Lee.
Huge thanks to @taishikato, @JesseKoldewijn, @Evavic44, @feugy, @liamlaverty, @dvoytenko, @SukkaW, @wbinnssmith, @rishabhpoddar, @better-salmon, @ziyafenn, @A7med3bdulBaset, @jasonuc, @yossydev, @Prachi-meon, @InfiniteCodeMonkeys, @ForsakenHarmony, @miketimmerman, @kwonoj, @williamli, @gnoff, @jsteele-stripe, @chungweileong94, @WITS, @sogoagain, @junioryono, @eisafaqiri, @yannbolliger, @aramikuto, @rocketman-21, @kenji-webdev, @michaelpeterswa, @Dannymx, @vpaflah, @zeevo, @chrisweb, @stefangeneralao, @tknickman, @Kikobeats, @ubinatus, @code-haseeb, @hmmChase, @byhow, @DanielRivers, @wojtekmaj, @paramoshkinandrew, @OMikkel, @theitaliandev, @oliviertassinari, @Ishaan2053, @Sandeep-Mani, @alyahmedaly, @Lezzio, @devjiwonchoi, @juliusmarminge, @szmazhr, @eddiejaoude, @itz-Me-Pj, @AndersDJohnson, @gentamura, @tills13, @dijonmusters, @SaiGanesh21, @vordgi, @ryota-murakami, @tszhong0411, @officialrajdeepsingh, @alexpuertasr, @AkifumiSato, @Jonas-PFX, @icyJoseph, @florian-lp, @pbzona, @erfanium, @remcohaszing, @bernardobelchior, @willashe, @kevinmitch14, @smakosh, @mnjongerius, @asobirov, @theoholl, @suu3, @ArianHamdi, @adrianha, @Sina-Abf, @kuzeykose, @meenie, @nphmuller, @javivelasco, @belgattitude, @Svetoslav99, @johnslemmer, @colbyfayock, @mehranmf31, @m-nakamura145, @ryo8000, @aryaemami59, @bestlyg, @jinsoul75, @petrovmiroslav, @nattui, @zhuyedev, @dongwonnn, @nhducit, @flotwig, @Schmavery, @abhinaypandey02, @rvetere, @coffeecupjapan, @cjimmy, @Soheiljafarnejad, @jantimon, @zengspr, @wesbos, @neomad1337, @MaxLeiter, and @devr77 for helping!