next build phases and process
When you run next build, it moves through six phases: (1) Setup loads environment variables (.env files), validates next.config, and generates a build ID. (2) Route discovery scans app/ and pages/ directories for routes and detects root-level convention files like proxy and instrumentation, generating TypeScript route definitions. (3) Compilation bundles client, server, and edge code with Turbopack or webpack, transpiles TypeScript and JSX, tree-shakes unused code, optimizes CSS and fonts, and runs type checking in parallel. (4) Static analysis classifies each route for prerendering versus on-demand rendering, collects generateStaticParams output, and checks for prerender-blocking errors. (5) Prerendering prerenders static pages and PPR shells to HTML and generates RSC payloads for client-side navigation. (6) Output writes the build to .next/, and for output: 'standalone' bundles only runtime files, for output: 'export' generates a full static site, and prints the route table.
Jenkins Pipeline cache configuration
In Jenkins Pipeline, use the Job Cacher plugin's arbitraryFileCache to cache .next/cache with cacheValidityDecidingFile set to 'next-lock.cache'. Create the next-lock.cache file using writeFile with content set to $GIT_COMMIT before running the next build step to ensure cache validity across commits.
Azure Pipelines cache configuration
In Azure Pipelines, use the Cache@2 task with key set to 'next | $(Agent.OS) | yarn.lock' and path set to '$(System.DefaultWorkingDirectory)/.next/cache'. Add this task prior to the next build step to persist Next.js build cache.
Next.js cache location and purpose
Next.js saves a cache to .next/cache that is shared between builds to improve build performance.
CI cache persistence requirement
To take advantage of Next.js caching in Continuous Integration environments, the CI workflow must be configured to persist the .next/cache directory between builds. If not configured correctly, a No Cache Detected error may occur.
Vercel CI caching
Next.js caching is automatically configured on Vercel. No manual configuration is required.
CircleCI cache configuration
In CircleCI, add .next/cache to the save_cache step paths in .circleci/config.yml alongside node_modules to persist Next.js build cache between builds.
Travis CI cache configuration
In Travis CI, add .next/cache to the cache directories section in .travis.yml alongside node_modules and $HOME/.cache/yarn to persist Next.js build cache.
GitLab CI cache configuration
In GitLab CI, add .next/cache/ to the cache paths section in .gitlab-ci.yml with cache key set to ${CI_COMMIT_REF_SLUG} to persist Next.js build cache between builds.
Netlify CI caching
For Netlify CI, use Netlify Plugins with @netlify/plugin-nextjs to configure Next.js build caching.
AWS CodeBuild cache configuration
In AWS CodeBuild, add cache paths to buildspec.yml including node_modules/**/* for faster package installation and .next/cache/**/* for faster application rebuilds.
GitHub Actions cache configuration
In GitHub Actions, use actions/cache@v4 with path set to ~/.npm and ${{ github.workspace }}/.next/cache. Set the cache key to ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }} and restore-keys to ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}- to enable intelligent cache restoration.
Heroku cache configuration
In Heroku, add a cacheDirectories array to the top-level package.json with value [".next/cache"] to enable custom caching for Next.js builds.
Bitbucket Pipelines cache configuration
In Bitbucket Pipelines, define a cache named nextcache with path .next/cache in the definitions section at the top level, then reference it in the caches section of the pipeline step alongside the node cache.
Server Component changes cause full page re-render
Changes to Server Components cause the entire page to re-render locally in order to show the new changes, which includes fetching new data for the component.
next dev compiles routes on-demand
The development process with `next dev` compiles routes in your application as you open or navigate to them. This enables you to start the dev server without waiting for every route in your application to compile, which is both faster and uses less memory.
Production build applies optimizations not needed for dev
Running a production build with `next build` applies other optimizations, like minifying files and creating content hashes, which are not needed for local development.
Turbopack is the default bundler for Next.js development
Turbopack is now the default bundler for Next.js development and provides significant performance improvements over webpack.
Opt in to Webpack instead of Turbopack
To use Webpack instead of Turbopack during development, run `npm run dev -- --webpack` (npm), `pnpm dev --webpack` (pnpm), `yarn dev --webpack` (yarn), or `bun run dev --webpack` (bun).
Import only specific icons from icon libraries
Libraries like `@material-ui/icons`, `@phosphor-icons/react`, or `react-icons` can import thousands of icons, even if you only use a few. Instead of importing from the main package, import directly from specific files. For example, use `import { TriangleIcon } from '@phosphor-icons/react/dist/csr/Triangle'` instead of `import { TriangleIcon } from '@phosphor-icons/react'`.
Avoid importing multiple icon sets from react-icons
Libraries like `react-icons` includes many different icon sets (pi, md, tb, cg, etc.). Importing all of these combined will be tens of thousands of modules that the compiler has to handle, even if you only use a single import from each. Choose one set and stick with that set.
Barrel files can slow down builds
Barrel files are files that export many items from other files. They can slow down builds because the compiler has to parse them to find if there are side-effects in the module scope by using the import. Try to import directly from specific files when possible.
Optimize package imports in next.config.js
Next.js can automatically optimize imports for certain packages that utilize barrel files. Add them to your `next.config.js` using `experimental.optimizePackageImports` array with the package names to optimize. Turbopack automatically analyzes imports and optimizes them without requiring this configuration.
serverComponentsHmrCache experimental option
The experimental `serverComponentsHmrCache` option allows you to cache `fetch` responses in Server Components across Hot Module Replacement (HMR) refreshes in local development. This results in faster responses and reduced costs for billed API calls.
Docker has slower HMR on Mac and Windows
If you're using Docker for development on Mac or Windows, you may experience significantly slower performance compared to running Next.js locally. Docker's filesystem access on Mac and Windows can cause Hot Module Replacement (HMR) to take seconds or even minutes, while the same application runs with fast HMR when developed locally. This performance difference is due to how Docker handles filesystem operations outside of Linux environments.
Use local development instead of Docker during development
For the best development experience, use local development (`npm run dev` or `pnpm dev`) instead of Docker during development. Reserve Docker for production deployments and testing production builds. If you must use Docker for development, consider using Docker on a Linux machine or VM.
experimental.webpackMemoryOptimizations reduces peak memory
Starting in v15.0.0, you can add experimental.webpackMemoryOptimizations: true to your next.config.js file to change Webpack behavior that reduces maximum memory usage but may increase compilation times by a slight amount. This feature is experimental and considered low-risk.
Preloading entries trades initial memory for faster response times
When the Next.js server starts, it preloads each page's JavaScript modules into memory at startup rather than at request time. This optimization allows for faster response times, in exchange for a larger initial memory footprint. To disable this optimization, set the experimental.preloadEntriesOnStart flag to false in next.config.ts or next.config.mjs. Next.js does not unload these JavaScript modules, meaning that even with this optimization disabled, the memory footprint of your Next.js server will eventually be the same if all pages are eventually requested.
Disable preloadEntriesOnStart example
```ts filename="next.config.ts" switcher
import type { NextConfig } from 'next'
const config: NextConfig = {
experimental: {
preloadEntriesOnStart: false,
},
}
export default config
```
```js filename="next.config.mjs" switcher
/** @type {import('next').NextConfig} */
const config = {
experimental: {
preloadEntriesOnStart: false,
},
}
export default config
```
This example disables preloading of page JavaScript modules on server startup to reduce initial memory footprint.
Disable source maps to reduce memory
Generating source maps consumes extra memory during the build process. You can disable source map generation by adding productionBrowserSourceMaps: false and experimental.serverSourceMaps: false to your Next.js configuration. If you consistently encounter memory issues during the prerender phase of next build (after Generating static pages), you can try disabling source maps in that phase by adding enablePrerenderSourceMaps: false to your Next.js configuration. Some plugins may turn on source maps and may require custom configuration to disable.
Webpack build worker reduces memory during builds
The Webpack build worker allows you to run Webpack compilations inside a separate Node.js worker which will decrease memory usage of your application during builds. This option is enabled by default if your application does not have a custom Webpack configuration starting in v14.1.0. If you are using an older version of Next.js or you have a custom Webpack configuration, you can enable this option by setting experimental.webpackBuildWorker: true inside your next.config.js. This feature may not be compatible with all custom Webpack plugins.
Reduce dependencies to lower memory usage
Applications with a large number of dependencies consume more memory. Use the Bundle Analyzer to investigate large dependencies in your application that may be removable to improve performance and memory usage.
Edge runtime memory issue fixed in v14.1.3
Next.js v14.1.3 fixed a memory issue when using the Edge runtime. You should update to this version or later if you are experiencing memory issues with Edge runtime.
Disable Webpack cache to reduce memory
The Webpack cache saves generated Webpack modules in memory and/or to disk to improve the speed of builds, but it also increases the memory usage of your application to store the cached data. You can disable this behavior by adding a custom Webpack configuration that sets config.cache to Object.freeze({ type: 'memory' }) when not in dev mode.
Disable webpack cache example
```js filename="next.config.mjs"
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (
config,
{ buildId, dev, isServer, defaultLoaders, nextRuntime, webpack }
) => {
if (config.cache && !dev) {
config.cache = Object.freeze({
type: 'memory',
})
}
// Important: return the modified config
return config
},
}
export default nextConfig
```
This example disables Webpack cache to reduce memory usage during production builds.
Disable TypeScript type checking to reduce memory
Typechecking may require a lot of memory, especially in large projects. When the build produces out-of-memory issues during the Running TypeScript step, you can disable static analysis during builds by setting typescript.ignoreBuildErrors: true in next.config.js. However, this may produce faulty deploys due to type errors. It is strongly recommended only promoting builds to production after static analysis has completed.
Disable TypeScript errors in production example
```js filename="next.config.mjs"
/** @type {import('next').NextConfig} */
const nextConfig = {
typescript: {
// !! WARN !!
// Dangerously allow production builds to successfully complete even if
// your project has type errors.
// !! WARN !!
ignoreBuildErrors: true,
},
}
export default nextConfig
```
This example disables TypeScript error checking during builds to reduce memory usage.
Run next build to catch build errors locally
next build should be run to build the application locally and catch any build errors before going to production.
Run next start to measure production performance
next start should be run to measure the performance of a Next.js application in a production-like environment.
Build cache consistency across containers
Next.js generates an ID during next build to identify which version of your application is being served. When running multiple containers, the same build should be used to boot up multiple containers. If rebuilding for each stage of your environment, you need to generate a consistent build ID using the generateBuildId command in next.config.js.
generateBuildId configuration example
Example of generating a consistent build ID in next.config.js:
```jsx
module.exports = {
generateBuildId: async () => {
return process.env.GIT_HASH
},
}
```
This uses the git hash as the build ID, ensuring consistency across containers.
Upgrade command for Next.js 14
To upgrade to Next.js version 14, run npm i next@next-14 react@18 react-dom@18 && npm i eslint-config-next@next-14 -D for npm, yarn add next@next-14 react@18 react-dom@18 && yarn add eslint-config-next@next-14 -D for yarn, pnpm i next@next-14 react@18 react-dom@18 && pnpm i eslint-config-next@next-14 -D for pnpm, or bun add next@next-14 react@18 react-dom@18 && bun add eslint-config-next@next-14 -D for bun.
Minimum Node.js version in Next.js 14
Next.js 14 requires minimum Node.js version 18.17, bumped up from 16.14, because Node.js 16.x has reached end-of-life.
next export command removed in Next.js 14
The next export command has been removed in favor of using output: 'export' configuration option.
ImageResponse import moved from next/server to next/og
The ImageResponse import was moved from next/server to next/og in Next.js 14. A codemod is available to automatically rename these imports.
@next/font package removed in Next.js 14
The @next/font package has been fully removed in favor of the built-in next/font module. A codemod is available to safely rename imports automatically.
WASM target removed for next-swc
The WASM target for next-swc has been removed in Next.js 14.
TypeScript types upgrade for Next.js 14
When upgrading to Next.js 14 with TypeScript, you should also upgrade @types/react and @types/react-dom to their latest versions.
images.qualities default changed from all to [75] in Next.js 16
The default value for images.qualities has changed from allowing all qualities to only [75]. If you need to support multiple quality levels, set images.qualities to an array of desired values like [50, 75, 100]. If a quality prop is not included in the images.qualities array, it will be coerced to the closest value in the array.
Browser support in Next.js 16
Next.js 16 requires Chrome 111+, Edge 111+, Firefox 111+, and Safari 16.4+.
Node.js 20.9+ minimum requirement in Next.js 16
Starting with Next.js 16, the minimum Node.js version is 20.9.0 (LTS). Node.js 18 is no longer supported.
Turbopack is default and stable in Next.js 16
Starting with Next.js 16, Turbopack is stable and used by default with 'next dev' and 'next build'. The '--turbopack' flag is no longer necessary. You can remove it from package.json scripts. If you have a custom webpack configuration, the build will fail by default to prevent misconfiguration. You can opt out with the '--webpack' flag, use Turbopack anyway with '--turbopack', or migrate your webpack config to Turbopack-compatible options.
experimental.turbopack moved to top-level turbopack configuration
In Next.js 15, Turbopack configuration was under experimental.turbopack. In Next.js 16, the configuration has been promoted to a top-level 'turbopack' option in next.config.ts or next.config.js. For example: const nextConfig = { turbopack: { /* options */ } }
Turbopack resolveAlias for Node.js native modules
When client-side code imports files containing Node.js native modules causing 'Module not found' errors, Turbopack offers the 'turbopack.resolveAlias' option to silence the error. For example, to load an empty module when 'fs' is requested for the browser: turbopack: { resolveAlias: { fs: { browser: './empty.ts' } } }. It is preferable to refactor modules so client code does not import from modules using Node.js native modules.
Turbopack Sass node_modules imports without tilde prefix
Turbopack fully supports importing Sass files from node_modules, but does not support the legacy tilde (~) prefix that Webpack supported. Change from '@import "~bootstrap/dist/css/bootstrap.min.css"' to '@import "bootstrap/dist/css/bootstrap.min.css"'. If changing imports is not possible, use turbopack.resolveAlias: { '~*': '*' }
Turbopack File System Caching enabled by default
Turbopack stores compiler artifacts on disk between runs for faster compile times. Filesystem caching is enabled by default for both 'next dev' and 'next build'. See turbopackFileSystemCache configuration to disable or configure it.
Async Request APIs breaking change in Next.js 16
Starting with Next.js 16, synchronous access to Request APIs is fully removed. These APIs can only be accessed asynchronously: cookies, headers, draftMode, params in layout.js/page.js/route.js/default.js/opengraph-image/twitter-image/icon/apple-icon, and searchParams in page.js. Version 15 had temporary synchronous compatibility, but this is now gone.
PageProps, LayoutProps, and RouteContext type helpers for async API migration
Next.js provides type helpers for migrating to async params and searchParams: PageProps, LayoutProps, and RouteContext. Run 'npx next typegen' to automatically generate these globally available type helpers. These enable fully type-safe migration to async API pattern. For example: export default async function Page(props: PageProps<'/blog/[slug]'>) { const { slug } = await props.params; const query = await props.searchParams; }
Async id parameter for image generating functions in Next.js 16
In Next.js 16, the image generation functions in opengraph-image, twitter-image, icon, and apple-icon now receive params and id as promises instead of synchronous values. The generateImageMetadata function continues to receive synchronous params. Example: export default async function Image({ params, id }) { const { slug } = await params; const imageId = await id; }
Async id parameter for sitemap generating functions in Next.js 16
In Next.js 16, the sitemap generating function receives id as a promise instead of synchronously. Example change: export default async function sitemap({ id }) { const resolvedId = await id; const start = Number(resolvedId) * 50000; }