Skip to main content
doc0blade47/next.jsdocumentation home
Sign in

Overview

Last updated Oct 12, 2026100% grounded
Relevant source files

The following files were used as context for generating this wiki page:

Subsystem Architecture Foundation

Next.js orchestrates its architecture through a structured ecosystem comprising programmatic server entry points like Server Architecture and Development Server, public export facades, dual runtime routing compilation targets across Node and Edge environments, and dedicated client-side application bootstrap topologies.

Sources: packages/next/src/build/index.ts:188-190

These subsystems rely on repository-level compilation tasks and build asset transformations managed via taskfile orchestration, alongside cross-cutting build manifest integration that governs runtime dispatch contracts Build Pipeline, Turbopack Engine, and Webpack Configuration. Sources: packages/next/src/server/base-server.ts:30-41, packages/next/taskfile.js:2433-2436

Programmatic server entry points

Custom Server API and Deprecations

The public programmatic server entry point is provided via packages/next/src/server/next.ts, exporting the NextServer class alongside configuration options, handler signatures, and bundler choices Server Architecture, Development Server. Custom server implementations initialize an instance of NextServer to invoke lifecycle methods such as prepare(), getRequestHandler(), getUpgradeHandler(), and close() CLI Commands.

export type NextServerOptions = Omit<
  ServerOptions | DevServerOptions,
  // This is assigned in this server abstraction.
  'conf' | 'compileMode'
> &
  Partial<Pick<ServerOptions | DevServerOptions, 'conf'>>
 
export type NextBundlerOptions = {
  /** @deprecated Use `turbopack` instead */
  turbo?: boolean
  /** Selects Turbopack as the bundler */
  turbopack?: boolean
  /** Selects Webpack as the bundler */
  webpack?: boolean
}
 
export type RequestHandler = (
  req: IncomingMessage,
  res: ServerResponse,
  parsedUrl?: NextUrlWithParsedQuery | undefined
) => Promise<void>
 
export type UpgradeHandler = (
  req: IncomingMessage,
  socket: Duplex,
  head: Buffer
) => Promise<void>

Sources: packages/next/src/server/next.ts:43-69

The NextServer class implements NextWrapperServer, exposing standard HTTP request dispatching methods alongside legacy custom server operations that trigger formal warnings when invoked.

Method NameCategoryStatusMigration Guidance / Description
getRequestHandler()Core Request RoutingActiveReturns a RequestHandler for IncomingMessage and ServerResponse.
getUpgradeHandler()Core WebSocket UpgradeActiveReturns an UpgradeHandler for upgrading network sockets.
prepare()Server LifecycleActiveAsynchronously compiles and initializes application server fields.
close()Server LifecycleActiveShuts down the underlying server instance and underlying caches.
setAssetPrefix()ConfigurationDeprecatedConfigure assetPrefix in next.config.js instead.
logError()LoggingDeprecatedPlease use application logging instead.
logErrorWithOriginalStack()LoggingDeprecatedPlease use application logging instead.
revalidate()Cache ManagementDeprecatedPlease use documented application revalidation APIs instead.
render()RenderingDeprecatedPlease use app.getRequestHandler() with an adjusted parsed URL instead.
renderToHTML()RenderingDeprecatedPlease use app.getRequestHandler() with an adjusted parsed URL instead.
renderError()RenderingDeprecatedPlease use app.getRequestHandler() with an adjusted parsed URL instead.
renderErrorToHTML()RenderingDeprecatedPlease use app.getRequestHandler() with an adjusted parsed URL instead.
render404()RenderingDeprecatedPlease use app.getRequestHandler() with an adjusted parsed URL instead.

Sources: packages/next/src/server/next.ts:112-176

type DeprecatedCustomServerMethod =
  | 'setAssetPrefix'
  | 'logError'
  | 'logErrorWithOriginalStack'
  | 'revalidate'
  | 'render'
  | 'renderToHTML'
  | 'renderError'
  | 'renderErrorToHTML'
  | 'render404'
 
const DEPRECATED_CUSTOM_SERVER_METHOD_GUIDANCE: Record<
  DeprecatedCustomServerMethod,
  string
> = {
  setAssetPrefix: 'Please configure `assetPrefix` in `next.config.js` instead.',
  logError: 'Please use application logging instead.',
  logErrorWithOriginalStack: 'Please use application logging instead.',
  revalidate: 'Please use documented application revalidation APIs instead.',
  render:
    'Please use `app.getRequestHandler()` with an adjusted parsed URL instead.',
  renderToHTML:
    'Please use `app.getRequestHandler()` with an adjusted parsed URL instead.',
  renderError:
    'Please use `app.getRequestHandler()` with an adjusted parsed URL instead.',
  renderErrorToHTML:
    'Please use `app.getRequestHandler()` with an adjusted parsed URL instead.',
  render404:
    'Please use `app.getRequestHandler()` with an adjusted parsed URL instead.',
}
 
function warnDeprecatedCustomServerMethod(
  method: DeprecatedCustomServerMethod
) {
  log.warnOnce(
    `The \`app.${method}()\` method is deprecated in custom servers. ${DEPRECATED_CUSTOM_SERVER_METHOD_GUIDANCE[method]}`
  )
}

Sources: packages/next/src/server/next.ts:73-110

Warning

Invoking legacy methods like app.render() or app.revalidate() on a custom server instance logs a runtime warning via log.warnOnce, indicating that developers should switch to app.getRequestHandler() or native application revalidation utilities Request Lifecycle. Sources: packages/next/src/server/next.ts:104-110

interface NextWrapperServer {
  // NOTE: the methods/properties here are the public API for custom servers.
  // Consider backwards compatibilty when changing something here!
 
  options: NextServerOptions
  hostname: string | undefined
  port: number | undefined
 
  getRequestHandler(): RequestHandler
  prepare(serverFields?: ServerFields): Promise<void>
  /** @deprecated Configure `assetPrefix` in `next.config.js` instead. */
  setAssetPrefix(assetPrefix: string): void
  close(): Promise<void>
 
  // used internally
  getUpgradeHandler(): UpgradeHandler
 
  // legacy methods that we left exposed in the past
 
  /** @deprecated Use application logging instead. */
  logError(...args: Parameters<NextNodeServer['logError']>): void
 
  /** @deprecated Use documented application revalidation APIs instead. */
  revalidate(
    ...args: Parameters<NextNodeServer['revalidate']>
  ): ReturnType<NextNodeServer['revalidate']>
 
  /** @deprecated Use application logging instead. */
  logErrorWithOriginalStack(err: unknown, type: string): void
 
  /**
   * @deprecated Use `app.getRequestHandler()` with an adjusted parsed URL instead.
   */
  render(
    ...args: Parameters<NextNodeServer['render']>
  ): ReturnType<NextNodeServer['render']>
 
  /**
   * @deprecated Use `app.getRequestHandler()` with an adjusted parsed URL instead.
   */
  renderToHTML(
    ...args: Parameters<NextNodeServer['renderToHTML']>
  ): ReturnType<NextNodeServer['renderToHTML']>
 
  /**
   * @deprecated Use `app.getRequestHandler()` with an adjusted parsed URL instead.
   */
  renderError(
    ...args: Parameters<NextNodeServer['renderError']>
  ): ReturnType<NextNodeServer['renderError']>
 
  /**
   * @deprecated Use `app.getRequestHandler()` with an adjusted parsed URL instead.
   */
  renderErrorToHTML(
    ...args: Parameters<NextNodeServer['renderErrorToHTML']>
  ): ReturnType<NextNodeServer['renderErrorToHTML']>
 
  /**
   * @deprecated Use `app.getRequestHandler()` with an adjusted parsed URL instead.
   */
  render404(
    ...args: Parameters<NextNodeServer['render404']>
  ): ReturnType<NextNodeServer['render404']>
}

Sources: packages/next/src/server/next.ts:112-176

Public module export facade

Package Entrypoints and Re-exports

The next package export structure maps top-level JavaScript files and API modules to their respective compiled targets within the dist/ directory. These entry points provide stable external interfaces for client scripts, legacy routers, app renderers, and server-side web APIs.

"script.js",
"script.d.ts",
"server.js",
"server.d.ts",
"head.js",
"head.d.ts",
"image.js",
"image.d.ts",
"image-optimizer-transform.js",
"image-optimizer-transform.d.ts",
"link.js",
"link.d.ts",
"offline.js",
"offline.d.ts",
"form.js",
"form.d.ts",
"router.js",
"router.d.ts",

Sources: packages/next/package.json:34-51

The table below maps the root package entry files to their underlying compiled output modules.

Root Entry FileTarget Module PathPurpose
script.js./dist/client/scriptExternal script loading and optimization facade
router.js./dist/client/routerLegacy client-side Pages router bindings
app.js./dist/pages/_appBase application component for the Pages router
packages/next/src/api/router.ts../client/routerRe-export facade for client router bindings
packages/next/src/api/server.ts../server/web/exports/indexRe-export facade for web server primitives and helpers
packages/next/src/api/navigation.react-server.ts../client/components/navigation.react-serverReact Server Component navigation primitives

Sources: packages/next/script.js:1-1, packages/next/router.js:1-1, packages/next/app.js:1-1, packages/next/src/api/router.ts:1-2, packages/next/src/api/server.ts:1-1, packages/next/src/api/navigation.react-server.ts:1-1

module.exports = require('./dist/client/script')

Sources: packages/next/script.js:1-1

module.exports = require('./dist/client/router')

Sources: packages/next/router.js:1-1

module.exports = require('./dist/pages/_app')

Sources: packages/next/app.js:1-1

export { default } from '../client/router'
export * from '../client/router'

Sources: packages/next/src/api/router.ts:1-2

export * from '../server/web/exports/index'

Sources: packages/next/src/api/server.ts:1-1

export * from '../client/components/navigation.react-server'

Sources: packages/next/src/api/navigation.react-server.ts:1-1

Note

The top-level root modules delegate execution directly to compiled artifacts inside dist/, establishing strict boundary contracts between consumer-facing imports and internal compiler layouts. Sources: packages/next/package.json:11-16

"files": [
  "AGENTS.md",
  "analyze",
  "dist",
  "app.js",
  "app.d.ts",
]

Sources: packages/next/package.json:11-16

Dual runtime routing compilation targets

Compiled Route Module Dispatch

Next.js unifies server routing execution across Node.js and the Edge Runtime by dynamically resolving route module implementations through environment-conditioned wrapper modules. Compiled route modules for pages (packages/next/src/server/route-modules/pages/module.compiled.js), app pages (packages/next/src/server/route-modules/app-page/module.compiled.js), and app routes (packages/next/src/server/route-modules/app-route/module.compiled.js) inspect process.env.NEXT_RUNTIME at runtime or build time. When process.env.NEXT_RUNTIME === 'edge', these modules bypass Node-specific bundles and require the base edge route module directly from next/dist/server/route-modules/.../module.js. When running under Node.js, they branch across process.env.NODE_ENV, process.env.TURBOPACK, and experimental feature flags like process.env.__NEXT_EXPERIMENTAL_REACT to load the appropriate pre-compiled runtime artifact.

if (process.env.NEXT_RUNTIME === 'edge') {
  module.exports = require('next/dist/server/route-modules/pages/module.js')
} else {
  if (process.env.NODE_ENV === 'development') {
    if (process.env.TURBOPACK) {
      module.exports = require('next/dist/compiled/next-server/pages-turbo.runtime.dev.js')
    } else {
      module.exports = require('next/dist/compiled/next-server/pages.runtime.dev.js')
    }
  } else {
    if (process.env.TURBOPACK) {
      module.exports = require('next/dist/compiled/next-server/pages-turbo.runtime.prod.js')
    } else {
      module.exports = require('next/dist/compiled/next-server/pages.runtime.prod.js')
    }
  }
}

Sources: packages/next/src/server/route-modules/pages/module.compiled.js:1-17

if (process.env.NEXT_RUNTIME === 'edge') {
  module.exports = require('next/dist/server/route-modules/app-page/module.js')
} else {
  if (process.env.__NEXT_EXPERIMENTAL_REACT) {
    if (process.env.NODE_ENV === 'development') {
      if (process.env.TURBOPACK) {
        module.exports = require('next/dist/compiled/next-server/app-page-turbo-experimental.runtime.dev.js')
      } else {
        module.exports = require('next/dist/compiled/next-server/app-page-experimental.runtime.dev.js')
      }
    } else {
      if (process.env.TURBOPACK) {
        module.exports = require('next/dist/compiled/next-server/app-page-turbo-experimental.runtime.prod.js')
      } else {
        module.exports = require('next/dist/compiled/next-server/app-page-experimental.runtime.prod.js')
      }
    }
  } else {
    if (process.env.NODE_ENV === 'development') {
      if (process.env.TURBOPACK) {
        module.exports = require('next/dist/compiled/next-server/app-page-turbo.runtime.dev.js')
      } else {
        module.exports = require('next/dist/compiled/next-server/app-page.runtime.dev.js')
      }
    } else {
      if (process.env.TURBOPACK) {
        module.exports = require('next/dist/compiled/next-server/app-page-turbo.runtime.prod.js')
      } else {
        module.exports = require('next/dist/compiled/next-server/app-page.runtime.prod.js')
      }
    }
  }
}

Sources: packages/next/src/server/route-modules/app-page/module.compiled.js:1-33

The table below maps the runtime environment conditions and flag combinations in app-page/module.compiled.js and app-route/module.compiled.js to their respective loaded production and development runtime bundles.

NEXT_RUNTIME__NEXT_EXPERIMENTAL_REACTNODE_ENVTURBOPACKTarget Runtime Bundle Module
edgeanyanyanynext/dist/server/route-modules/app-page/module.js (or app-route/module.js)
node (default)truedevelopmenttruenext/dist/compiled/next-server/app-page-turbo-experimental.runtime.dev.js
node (default)truedevelopmentfalsenext/dist/compiled/next-server/app-page-experimental.runtime.dev.js
node (default)trueproductiontruenext/dist/compiled/next-server/app-page-turbo-experimental.runtime.prod.js
node (default)trueproductionfalsenext/dist/compiled/next-server/app-page-experimental.runtime.prod.js
node (default)falsedevelopmenttruenext/dist/compiled/next-server/app-page-turbo.runtime.dev.js
node (default)falsedevelopmentfalsenext/dist/compiled/next-server/app-page.runtime.dev.js
node (default)falseproductiontruenext/dist/compiled/next-server/app-page-turbo.runtime.prod.js
node (default)falseproductionfalsenext/dist/compiled/next-server/app-page.runtime.prod.js

Sources: packages/next/src/server/route-modules/app-page/module.compiled.js:1-33

if (process.env.NEXT_RUNTIME === 'edge') {
  module.exports = require('next/dist/server/route-modules/app-route/module.js')
} else {
  if (process.env.__NEXT_EXPERIMENTAL_REACT) {
    if (process.env.NODE_ENV === 'development') {
      if (process.env.TURBOPACK) {
        module.exports = require('next/dist/compiled/next-server/app-route-turbo-experimental.runtime.dev.js')
      } else {
        module.exports = require('next/dist/compiled/next-server/app-route-experimental.runtime.dev.js')
      }
    } else {
      if (process.env.TURBOPACK) {
        module.exports = require('next/dist/compiled/next-server/app-route-turbo-experimental.runtime.prod.js')
      } else {
        module.exports = require('next/dist/compiled/next-server/app-route-experimental.runtime.prod.js')
      }
    }
  } else {
    if (process.env.NODE_ENV === 'development') {
      if (process.env.TURBOPACK) {
        module.exports = require('next/dist/compiled/next-server/app-route-turbo.runtime.dev.js')
      } else {
        module.exports = require('next/dist/compiled/next-server/app-route.runtime.dev.js')
      }
    } else {
      if (process.env.TURBOPACK) {
        module.exports = require('next/dist/compiled/next-server/app-route-turbo.runtime.prod.js')
      } else {
        module.exports = require('next/dist/compiled/next-server/app-route.runtime.prod.js')
      }
    }
  }
}

Sources: packages/next/src/server/route-modules/app-route/module.compiled.js:1-33

Warning

Compiling code for NEXT_RUNTIME === 'edge' strips Node.js built-in modules (fs, path, crypto, etc.). Attempting to import Node-only APIs inside modules resolved via edge compiled targets triggers bundling and runtime sandbox faults. Sources: packages/next/src/server/route-modules/pages/module.compiled.js:1-3

Edge SSR Templates

Edge server-side rendering is orchestrated via code generation templates such as packages/next/src/build/templates/edge-ssr.ts. This template initializes global web APIs by importing ../../server/web/globals, wraps incoming requests using adapter and WebNextRequest, and instantiates component modules for userland pages, error pages, and optional 500 pages (userland500Page). Each module instance is bound to a Pages route module (RouteModule) supplied with compiled component options (pageRouteModuleOptions, errorRouteModuleOptions, user500RouteModuleOptions), project paths (distDir, relativeProjectDir), and layout wrappers (App, Document).

import '../../server/web/globals'
import {
  adapter,
  type EdgeHandler,
  type NextRequestHint,
} from '../../server/web/adapter'
import { IncrementalCache } from '../../server/lib/incremental-cache'
import * as cacheHandlers from '../../server/use-cache/handlers'
 
import Document from 'VAR_MODULE_DOCUMENT'
import * as appMod from 'VAR_MODULE_APP'
import * as userlandPage from 'VAR_USERLAND'
import * as userlandErrorPage from 'VAR_MODULE_GLOBAL_ERROR'
 
declare const userland500Page: any
declare const incrementalCacheHandler: any
// OPTIONAL_IMPORT:* as userland500Page
// OPTIONAL_IMPORT:incrementalCacheHandler
 
import RouteModule, {
  type PagesRouteHandlerContext,
} from '../../server/route-modules/pages/module'
import { WebNextRequest, WebNextResponse } from '../../server/base-http/web'
 
import type { NextFetchEvent } from '../../server/web/spec-extension/fetch-event'
import type RenderResult from '../../server/render-result'
import type { RenderResultMetadata } from '../../server/render-result'
import {
  getTracer,
  SpanKind,
  SpanStatusCode,
  type Span,
} from '../../server/lib/trace/tracer'
import { BaseServerSpan } from '../../server/lib/trace/constants'
import { HTML_CONTENT_TYPE_HEADER } from '../../lib/constants'
import type { RequestMeta } from '../../server/request-meta'
import { toNodeOutgoingHttpHeaders } from '../../server/web/utils'
 
// injected by the loader afterwards.
declare const pageRouteModuleOptions: any
declare const errorRouteModuleOptions: any
declare const user500RouteModuleOptions: any
// INJECT:pageRouteModuleOptions
// INJECT:errorRouteModuleOptions
// INJECT:user500RouteModuleOptions
// INJECT_RAW:cacheHandlerImports
 
const pageMod = {
  ...userlandPage,
  routeModule: new RouteModule({
    ...pageRouteModuleOptions,
    components: {
      App: appMod.default,
      Document,
    },
    userland: userlandPage,
    distDir: process.env.__NEXT_RELATIVE_DIST_DIR || '',
    relativeProjectDir: process.env.__NEXT_RELATIVE_PROJECT_DIR || '',
  }),
}
 
const errorMod = {
  ...userlandErrorPage,
  routeModule: new RouteModule({
    ...errorRouteModuleOptions,
    components: {
      App: appMod.default,
      Document,
    },
    userland: userlandErrorPage,
    distDir: process.env.__NEXT_RELATIVE_DIST_DIR || '',
    relativeProjectDir: process.env.__NEXT_RELATIVE_PROJECT_DIR || '',
  }),
}
 
// FIXME: this needs to be made compatible with the template
const error500Mod = userland500Page
  ? {
      ...userland500Page,
      routeModule: new RouteModule({
        ...user500RouteModuleOptions,
        components: {
          App: appMod.default,
          Document,
        },
        userland: userland500Page,
        distDir: process.env.__NEXT_RELATIVE_DIST_DIR || '',
        relativeProjectDir: process.env.__NEXT_RELATIVE_PROJECT_DIR || '',
      }),
    }
  : null

Sources: packages/next/src/build/templates/edge-ssr.ts:1-91

The requestHandler function in edge-ssr.ts parses incoming requests as NextRequestHint objects, constructs WebNextRequest wrappers, and invokes pageRouteModule.prepare() with source pathname definitions (VAR_DEFINITION_PATHNAME) and multizone draft mode flags. If prepareResult evaluates to null or falsy, the handler immediately returns an HTTP 400 Bad Request response.

async function requestHandler(
  req: NextRequestHint,
  _event: NextFetchEvent
): Promise<Response> {
  let srcPage = 'VAR_DEFINITION_PATHNAME'
 
  const relativeUrl = `${req.nextUrl.pathname}${req.nextUrl.search}`
  const baseReq = new WebNextRequest(req)
  const pageRouteModule = pageMod.routeModule as RouteModule
  const prepareResult = await pageRouteModule.prepare(baseReq, null, {
    srcPage,
    multiZoneDraftMode: false,
  })
 
  if (!prepareResult) {
    return new Response('Bad Request', {
      status: 400,
    })
  }

Sources: packages/next/src/build/templates/edge-ssr.ts:95-113

Caution

The optional userland500Page is conditionally instantiated via ternary check against userland500Page truthiness, whereas primary page and error modules are mandatory and statically instantiated upon template evaluation. Sources: packages/next/src/build/templates/edge-ssr.ts:77-91

Client application bootstrap variants

Runtime Initialization Topologies

Browser entry points govern how Next.js mounts application trees, coordinates hot module reloading, and consumes server-rendered Flight payloads across Webpack and Turbopack compiler runtimes. Production builds rely on packages/next/src/client/next.ts, which attaches version, router, and emitter to window.next, invokes initialize({}), and immediately calls hydrate() to attach React component trees to the DOM.

import './register-deployment-id-global'
import './webpack'
import '../lib/require-instrumentation-client'
 
import { initialize, hydrate, version, router, emitter } from './'
 
declare global {
  interface Window {
    next: any
  }
}
 
window.next = {
  version,
  // router is initialized later so it has to be live-binded
  get router() {
    return router
  },
  emitter,
}
 
initialize({})
  .then(() => hydrate())
  .catch(console.error)

Sources: packages/next/src/client/next.ts:1-24

Development entry points introduce hot module replacement middleware. packages/next/src/client/next-dev.ts initializes devClient via initHMR(), passes it to initialize({ devClient }), and resolves asset prefixes before invoking pageBootstrap(assetPrefix).

// TODO: Remove use of `any` type.
import './register-deployment-id-global'
import './webpack'
import { initialize, version, router, emitter } from './'
import initHMR from './dev/hot-middleware-client'
import { pageBootstrap } from './page-bootstrap'
 
window.next = {
  version,
  // router is initialized later so it has to be live-binded
  get router() {
    return router
  },
  emitter,
}
 
const devClient = initHMR()
initialize({ devClient })
  .then(({ assetPrefix }) => {
    return pageBootstrap(assetPrefix)
  })
  .catch((err) => {

Sources: packages/next/src/client/next-dev.ts:1-22

Turbopack environments use specialized entry files that define bundling hooks. packages/next/src/client/next-turbopack.ts sets window.next.turbopack = true, assigns empty dummy implementations for __next_set_public_path__ and __webpack_hash__, and establishes __turbopack_load_page_chunks__ to asynchronously resolve page chunks via __turbopack_load__.

// A client-side entry point for Turbopack builds. Includes logic to load chunks,
// but does not include development-time features like hot module reloading.
 
import './register-deployment-id-global'
import '../lib/require-instrumentation-client'
 
// TODO: Remove use of `any` type.
import { initialize, version, router, emitter, hydrate } from './'
 
window.next = {
  version,
  turbopack: true,
  // router is initialized later so it has to be live-binded
  get router() {
    return router
  },
  emitter,
}
;(self as any).__next_set_public_path__ = () => {}
;(self as any).__webpack_hash__ = ''
 
// for the page loader
declare let __turbopack_load__: any
 
initialize({})
  .then(() => {
    // for the page loader
    ;(self as any).__turbopack_load_page_chunks__ = (
      page: string,
      chunksData: any
    ) => {
      const chunkPromises = chunksData.map((c: unknown) =>
        __turbopack_load__(c)
      )
 
      Promise.all(chunkPromises).catch((err) =>
        console.error('failed to load chunks for page ' + page, err)
      )
    }
 
    return hydrate()
  })

Sources: packages/next/src/client/next-turbopack.ts:1-42

Similarly, development under Turbopack (packages/next/src/client/next-dev-turbopack.ts) combines HMR middleware client connection logic with chunk loading functions and connects to the Turbopack WebSocket message broker using connect().

// TODO: Remove use of `any` type.
import './register-deployment-id-global'
import { initialize, version, router, emitter } from './'
import initHMR from './dev/hot-middleware-client'
 
import { pageBootstrap } from './page-bootstrap'
//@ts-expect-error requires "moduleResolution": "node16" in tsconfig.json and not .ts extension
import { connect } from '@vercel/turbopack-ecmascript-runtime/browser/dev/hmr-client/hmr-client.ts'
import type { TurbopackMessageSentToBrowser } from '../server/dev/hot-reloader-types'
 
window.next = {
  version,
  turbopack: true,
  // router is initialized later so it has to be live-binded
  get router() {
    return router
  },
  emitter,
}
;(self as any).__next_set_public_path__ = () => {}
;(self as any).__webpack_hash__ = ''
 
// for the page loader
declare let __turbopack_load__: any
 
const devClient = initHMR()
initialize({
  devClient,
})
  .then(({ assetPrefix }) => {
    // for the page loader
    ;(self as any).__turbopack_load_page_chunks__ = (
      page: string,
      chunksData: any
    ) => {
      const chunkPromises = chunksData.map((c: unknown) =>
        __turbopack_load__(c)
      )
 
      Promise.all(chunkPromises).catch((err) =>
        console.error('failed to load chunks for page ' + page, err)
      )
    }
 
    connect({
      addMessageListener(cb: (message: TurbopackMessageSentToBrowser) => void) {
        devClient.addTurbopackMessageListener(cb)
      },
      sendMessage: devClient.sendTurbopackMessage,
      onUpdateError: devClient.handleUpdateError,
      chunkUpdateListenersGlobal:
        process.env.__NEXT_TURBOPACK_CHUNK_UPDATE_LISTENERS_GLOBAL!,
    })
 
    return pageBootstrap(assetPrefix)
  })

Sources: packages/next/src/client/next-dev-turbopack.ts:1-56

Bootstrap VariantEntry File PathHMR ClientTurbopack FlagChunk Loader HookHydration Trigger
Production Webpackpackages/next/src/client/next.tsNoundefinedStandard Webpack runtimehydrate()
Development Webpackpackages/next/src/client/next-dev.tsYes (initHMR())undefinedStandard Webpack runtimepageBootstrap(assetPrefix)
Production Turbopackpackages/next/src/client/next-turbopack.tsNotrue__turbopack_load_page_chunks__hydrate()
Development Turbopackpackages/next/src/client/next-dev-turbopack.tsYes (initHMR())true__turbopack_load_page_chunks__pageBootstrap(assetPrefix)

Sources: packages/next/src/client/next.ts:1-24, packages/next/src/client/next-dev.ts:1-22, packages/next/src/client/next-turbopack.ts:1-42, packages/next/src/client/next-dev-turbopack.ts:1-56

App Router Flight Stream Ingestion

The App Router client initializes through packages/next/src/client/app-index.tsx, which processes streamed React Server Component (RSC) payloads from the global window.__next_f array (NextFlight). The runtime defines specific numeric segment identifiers via FlightSegment tuples to decode bootstrap data, text chunks, form state, and base64-encoded binary buffers.

type FlightSegment =
  | [isBootStrap: 0]
  | [isNotBootstrap: 1, responsePartial: string]
  | [isFormState: 2, formState: any]
  | [isBinary: 3, responseBase64Partial: string]
 
type NextFlight = Omit<Array<FlightSegment>, 'push'> & {
  push: (seg: FlightSegment) => void
}
 
declare global {
  // If you're working in a browser environment
  interface Window {
    /**
     * request ID, dev-only
     */
    __next_r?: string
    __next_f: NextFlight
  }
}
 
function nextServerDataCallback(seg: FlightSegment): void {
  if (seg[0] === 0) {
    initialServerDataBuffer = []
  } else if (seg[0] === 1) {
    if (!initialServerDataBuffer)
      throw new Error('Unexpected server data: missing bootstrap script.')
 
    if (initialServerDataWriter) {
      initialServerDataWriter.enqueue(encoder.encode(seg[1]))
    } else {
      initialServerDataBuffer.push(seg[1])
    }
  } else if (seg[0] === 2) {
    initialFormStateData = seg[1]
  } else if (seg[0] === 3) {
    if (!initialServerDataBuffer)
      throw new Error('Unexpected server data: missing bootstrap script.')
 
    // Decode the base64 string back to binary data.
    const binaryString = atob(seg[1])
    const decodedChunk = new Uint8Array(binaryString.length)
    for (var i = 0; i < binaryString.length; i++) {
      decodedChunk[i] = binaryString.charCodeAt(i)
    }
 
    if (initialServerDataWriter) {
      initialServerDataWriter.enqueue(decodedChunk)
    } else {
      initialServerDataBuffer.push(decodedChunk)
    }
  }
}

Sources: packages/next/src/client/app-index.tsx:60-112

Warning

Accessing window.__next_f directly requires immediately draining existing entries and re-assigning the push method to nextServerDataCallback. Failing to clear the global array causes memory leaks, while failing to patch push drops subsequent incremental stream chunks pushed during server rendering streams. Sources: packages/next/src/client/app-index.tsx:176-185

const nextServerDataLoadingGlobal = (self.__next_f = self.__next_f || [])
 
// Consume all buffered chunks and clear the global data array right after to release memory.
// Otherwise it will be retained indefinitely.
nextServerDataLoadingGlobal.forEach(nextServerDataCallback)
nextServerDataLoadingGlobal.length = 0
 
// Patch its push method so subsequent chunks are handled (but not actually pushed to the array).
nextServerDataLoadingGlobal.push = nextServerDataCallback

Sources: packages/next/src/client/app-index.tsx:176-185

When DOMContentLoaded fires or when writers register via nextServerDataRegisterWriter, buffered chunks stream into React's parser. If an instant navigation test fetch (self.__next_instant_test) is active, the inline Flight stream is left open without erroring to prevent React from logging missing data warnings while separate static payloads hydrate.

function nextServerDataRegisterWriter(ctr: ReadableStreamDefaultController) {
  if (initialServerDataBuffer) {
    initialServerDataBuffer.forEach((val) => {
      ctr.enqueue(typeof val === 'string' ? encoder.encode(val) : val)
    })
    if (initialServerDataLoaded && !initialServerDataFlushed) {
      // Instant Navigation Testing API: don't close or error the inline
      // Flight stream. The static shell has no inline Flight data, so the
      // stream is empty. Closing it would cause React to log an error about
      // missing data. Leaving it open lets React treat any holes as
      // "still suspended." Hydration uses the separately fetched RSC payload
      // (self.__next_instant_test), not this stream.
      if (isStreamErrorOrUnfinished(ctr)) {
        if (!instantTestStaticFetch) {
          ctr.error(
            new Error(
              'The connection to the page was unexpectedly closed, possibly due to the stop button being clicked, loss of Wi-Fi, or an unstable internet connection.'
            )
          )
        }
      } else {
        ctr.close()
      }
      initialServerDataFlushed = true
      initialServerDataBuffer = undefined
    }
  }
 
  initialServerDataWriter = ctr
}

Sources: packages/next/src/client/app-index.tsx:127-156

Build asset transformation and taskfile orchestration

Compilation Task Definitions

Repository-level compilation and asset packaging are governed by taskfile specifications and build constants defined across workspace packages. The taskfile orchestrates parallelized compilation blocks, transforming source files through SWC bindings and bundling dependencies for server, client, and edge targets.

export async function next_compile(task, opts) {
  await task.parallel(
    [
      'cli',
      'copy_bundle_analyzer_ui',
      'bin',
      'server',
      'server_esm',
      'api_esm',
      'nextbuild',
      'nextbuildjest',
      'nextbuildstatic',
      'nextbuildstatic_esm',
      'nextbuild_esm',
      'next_devtools_entrypoint',
      'next_devtools_server',
      'next_devtools_server_esm',
      'next_devtools_shared',
      'next_devtools_shared_esm',
      'next_devtools_userspace',
      'next_devtools_userspace_esm',
      'pages',
      'pages_esm',
      'lib',
      'lib_esm',
      'client',
      'client_esm',
      'diagnostics',
      'telemetry',
      'trace',
      'shared',
      'shared_esm',
      'shared_re_exported',
      'shared_re_exported_esm',
      'server_wasm',
      'experimental_testing',
      'experimental_testmode',
    ],
    opts
  )
}

Sources: packages/next/taskfile.js:2433-2473

The taskfile exports specific compilation procedures including bin, cli, lib, server, client, and nextbuild, assigning appropriate SWC Compiler targets and options to each directory.

Task NameSource PatternSWC Target ModeOutput Destination
binsrc/bin/*server (strip extension)dist/bin (mode 0755)
cli`src/cli/**/*.+(jststsx)`
lib`src/lib/**/!(*.test).+(jststsx
server`src/server/**/!(*.test).+(jststsx)`
client`src/client/**/!(*.test*.stories).+(jsts

Sources: packages/next/taskfile.js:2485-2518, packages/next/taskfile.js:2581-2586

Warning

Compilation tasks exclude test files and fixture directories using explicit glob negation patterns like !(*.test) and ignore arrays to prevent build pollution in distribution directories. Sources: packages/next/taskfile.js:2539-2547

.source('src/build/**/*.+(js|ts|tsx)', {
  ignore: [
    '**/fixture/**',
    '**/tests/**',
    '**/jest/**',
    '**/*.test.d.ts',
    '**/*.test.+(js|ts|tsx)',
  ],
})

Sources: packages/next/taskfile.js:2539-2547

Where to go next

I want to…Read
How do you set up, build, and run a minimal Next.js application from source or templates using the repository entry points?Quick Start
What do the directories and packages in this repository represent and how are responsibilities partitioned across the tree?Project Structure
How are packages, build pipelines, dependencies, and internal linkages wired together across the pnpm and Turborepo workspace?Monorepo Workspace
How is the core Next.js HTTP server constructed across BaseServer, NextNodeServer, and base HTTP abstractions?Server Architecture
How does an incoming HTTP request flow through matching, middleware, routing normalizers, and response payload dispatch?Request Lifecycle
How are App Router HTTP method handlers (GET, POST, etc.) and Pages API routes executed and wrapped?Route Handlers
How does Next.js package, isolate, and execute middleware and route handlers within the V8 edge sandbox and Web standard APIs?Edge Runtime
How are server responses, data fetch results, tags, and ISR artifacts cached, retrieved, and invalidated across memory and disk backends?Incremental Cache
How does Next.js isolate request headers, cookies, params, and draft mode state per request using Node.js AsyncLocalStorage?Async Storage
How does the server track dynamic data access, detect un-cached parameters, and trigger Partial Prerendering (PPR) or dynamic bailouts?Dynamic Rendering
How does the App Router construct React Server Component component trees from route segment layouts and pages on the server?App Rendering
How does Next.js serialize React Server Component trees, Flight data streams, client references, and server actions across the wire?RSC Transport
How does the legacy Pages Router render HTML via _document and _app with getStaticProps, getServerSideProps, and getInitialProps?Pages Rendering
How does Next.js manage Node.js readable streams, Web Streams, Uint8Array chunk buffering, and React streaming renders?Stream Handling
How are React Server Actions dispatched, validated with CSRF protection, invoked, and serialized back to the client router?Server Actions
How does Next.js perform compile-time and runtime boundary verification and sample tracking for dynamic vs static code paths?Instant Validation
How does Next.js initialize the browser runtime, mount the root React tree, and register global error handlers?Client Runtime
How does the client-side App Router maintain the component tree, handle link navigations, and coordinate layout rendering?App Router
How do state transitions (navigate, refresh, restore, server actions) update the client-side App Router cache and component tree?Router Reducer
How does the client cache individual route segments, prefetch links, manage back-forward cache (bfcache), and decode RSC responses?Segment Cache
How does next build coordinate compiler stages, type checking, bundle creation, route extraction, and production compilation?Build Pipeline
How does the build pipeline discover files, validate route segments, parse segment configurations, and generate manifest JSONs?Route Discovery
How are static HTML, dynamic route params, ISR fallback pages, and static site export bundles compiled during the build?Static Generation
How are Rust-based SWC bindings installed, configured, and invoked for JavaScript/TypeScript and JSX transformations?SWC Compiler
How does Next.js integrate Turbopack for production compilation, entry point resolution, and manifest loading?Turbopack Engine
How does Next.js construct its multi-target Webpack configurations for client, server, and Edge Runtime targets?Webpack Configuration
How do Next.js internal loaders (next-app-loader, next-flight-loader, next-swc-loader, next-route-loader) transform application source code?Webpack Loaders
How do build manifest, flight manifest, pages manifest, and font manifest Webpack plugins produce runtime manifest tables?Manifest Plugins
How does NextDevServer manage on-demand compilation, route matching, and development request handling?Development Server
How do Webpack and Turbopack hot reloaders propagate file change events over WebSockets to update the running browser application?Hot Reloading
How does the Next.js dev overlay capture, parse, source-map, and display runtime errors, build errors, and code frames?Developer Overlay
How does the developer overlay collect, profile, and render network request waterfall timings and cache status?Request Insights
How do the next dev, next build, next start, next info, and next export CLI command handlers parse arguments and bootstrap execution?CLI Commands
How does next-codemod and the upgrade CLI transform legacy user code to modern Next.js APIs using jscodeshift transforms?Upgrade and Codemods
How are anonymous usage statistics, feature adoption events, and error metrics recorded, flushed, and controlled?Telemetry
How does Next.js instrument build and server spans using OpenTelemetry-compatible tracing infrastructure?Trace Profiling
How does next/image resize, format-convert (AVIF/WebP), optimize, and cache images on demand on the server?Image Optimization
How do next/font/google and next/font/local download, extract fallback metrics, and generate CSS @font-face rules at build time?Font Optimization
How are static and dynamic metadata, OpenGraph tags, sitemaps, robots.txt, and manifests resolved and rendered into HTML head tags?Metadata Generation
How does @next/third-parties optimize loading Google Analytics, Tag Manager, YouTube embeds, and Google Maps?Third Party Libraries
How does the Next.js TypeScript language service plugin enforce segment config types and validate Server/Client component boundaries?TypeScript Plugin
How does the create-next-app scaffolding CLI validate destination directories, select templates, and install dependencies?Create Next App
How does the standalone bundle-analyzer web application parse, layout, diff, and visualize Next.js build module graph treemaps?Bundle Analyzer
How do eslint-plugin-next and internal lint rules detect anti-patterns such as sync scripts, invalid head tags, and unoptimized images?ESLint Rules
How does devlow-bench benchmark Next.js performance across build and dev runs, generate snapshots, and export metrics?Benchmark Harness
How does the @next/routing utility library resolve routes, destinations, and _next/data requests independently of the server?Routing Utility
Was this page helpful?