Next.js implements a sophisticated server-side HMR system that coordinates multiple webpack compilers, handles server component updates, and manages complex caching mechanisms. This document provides a comprehensive analysis of the server-side HMR architecture.
graph TB
subgraph "Development Server"
DevServer[Next.js Dev Server]
HotReloader[Hot Reloader Webpack/Turbopack]
OnDemandHandler[On-Demand Entry Handler]
HotMiddleware[WebSocket Hot Middleware]
end
subgraph "Multi-Compiler System"
ClientCompiler[Client Compiler]
ServerCompiler[Server Compiler]
EdgeCompiler[Edge-Server Compiler]
end
subgraph "Cache Management"
RequireCache[Node.js Require Cache]
ModuleContext[Edge Module Context]
ManifestCache[Build Manifest Cache]
end
subgraph "File System"
SourceFiles[Source Files]
PageFiles[Page Components]
ServerComponents[Server Components]
MiddlewareFiles[Middleware/Edge Files]
end
DevServer --> HotReloader
HotReloader --> ClientCompiler
HotReloader --> ServerCompiler
HotReloader --> EdgeCompiler
HotReloader --> OnDemandHandler
HotReloader --> HotMiddleware
ClientCompiler --> RequireCache
ServerCompiler --> RequireCache
EdgeCompiler --> ModuleContext
SourceFiles --> ClientCompiler
PageFiles --> ServerCompiler
ServerComponents --> ServerCompiler
MiddlewareFiles --> EdgeCompiler
RequireCache --> ManifestCache
ModuleContext --> ManifestCache
classDiagram
class HotReloaderWebpack {
<<packages/next/src/server/dev/hot-reloader-webpack.ts>>
-multiCompiler: webpack.MultiCompiler
-clientStats: webpack.Stats
-serverStats: webpack.Stats
-edgeServerStats: webpack.Stats
-hasServerError: boolean
-onDemandEntries: OnDemandEntryHandler
-hotMiddleware: WebpackHotMiddleware
+constructor()
+start()
+run(req, res, parsedUrl)
+onHMR(client)
+send(action)
+ensurePage(options)
+getCompilationErrors()
+invalidate()
+buildFallbackError()
+setHmrServerError()
+clearHmrServerError()
+refreshServerComponents(hash)
+close()
-trackPageChanges()
}
class HotReloaderTurbopack {
<<packages/next/src/server/dev/hot-reloader-turbopack.ts>>
-project: Project
-buildManifests: Map
-subscriptions: Set
-changeSubscriptions: Map
+run(req, res, parsedUrl)
+onHMR(client)
+send(action)
+ensurePage(options)
+getCompilationErrors()
+invalidate()
+start()
+close()
+getVersionInfo()
-handleEntrypointsSubscription()
-subscribeToChanges()
-clearModuleContext(target)
}
class OnDemandEntryHandler {
<<packages/next/src/server/dev/on-demand-entry-handler.ts>>
-entries: Map~string, EntryData~
-lastAccessPages: Set~string~
-doneCallbacks: Map
-pagesDir: string
-appDir: string
+ensurePage(options)
+onHMR(client)
-findPagePathData()
-getEntryKey()
-getEntries()
-getInvalidator()
-disposeInactiveEntries()
-handlePing(page)
}
class WebpackHotMiddleware {
<<packages/next/src/server/dev/hot-middleware.ts>>
-eventStream: EventStream
-clients: Set~WebSocket~
-clientLatestStats: webpack.Stats
-serverLatestStats: webpack.Stats
-edgeServerLatestStats: webpack.Stats
+constructor()
+onClientInvalid()
+onClientDone(stats)
+onServerInvalid()
+onServerDone(stats)
+onEdgeServerInvalid()
+onEdgeServerDone(stats)
+onHMR(client)
+publishStats(action, stats)
+publish(payload)
+close()
}
HotReloaderWebpack --> OnDemandEntryHandler
HotReloaderWebpack --> WebpackHotMiddleware
HotReloaderTurbopack --> WebpackHotMiddleware
sequenceDiagram
participant FS as File System
participant Entry as On-Demand Handler
participant Client as Client Compiler
participant Server as Server Compiler
participant Edge as Edge Compiler
participant HotReloader as Hot Reloader
participant WS as WebSocket Middleware
FS->>Entry: File change detected
Entry->>Entry: Determine affected compilers
alt Client-side change
Entry->>Client: Invalidate client entries
Client->>Client: Compile client bundle
Client->>HotReloader: Client compilation done
end
alt Server component change
Entry->>Server: Invalidate server entries
Server->>Server: Compile server bundle
Server->>HotReloader: Server compilation done
HotReloader->>HotReloader: Clear require cache
HotReloader->>HotReloader: Reset fetch cache
end
alt Edge runtime change
Entry->>Edge: Invalidate edge entries
Edge->>Edge: Compile edge bundle
Edge->>HotReloader: Edge compilation done
HotReloader->>HotReloader: Clear module context
end
HotReloader->>HotReloader: Coordinate compilation results
HotReloader->>WS: Send HMR action
WS->>WS: Broadcast to clients
graph TB
subgraph "Webpack Configuration"
WebpackConfig["webpack-config.ts<br/>packages/next/src/build/<br/>webpack-config.ts"]
DevPlugins["Development Plugins<br/>(conditionally added in dev mode)"]
end
subgraph "Custom HMR Plugins"
RequireCacheHotReloader["NextJsRequireCacheHotReloader<br/>packages/next/src/build/webpack/plugins/<br/>nextjs-require-cache-hot-reloader.ts"]
HMRPlugin["HotModuleReplacementPlugin<br/>(webpack built-in)"]
ReactRefreshPlugin["ReactRefreshWebpackPlugin<br/>packages/react-refresh-utils/<br/>ReactRefreshWebpackPlugin.ts"]
end
subgraph "Cache Management"
RequireHooks["require-hook.ts<br/>packages/next/src/server/<br/>require-hook.ts"]
RequireCache["require-cache.ts<br/>packages/next/src/server/dev/<br/>require-cache.ts"]
ModuleContext["Module Context Manager<br/>packages/next/src/server/web/<br/>sandbox/context.ts"]
end
WebpackConfig --> DevPlugins
DevPlugins --> RequireCacheHotReloader
DevPlugins --> HMRPlugin
DevPlugins --> ReactRefreshPlugin
RequireCacheHotReloader --> RequireCache
RequireCacheHotReloader --> ModuleContext
RequireCache --> RequireHooks
flowchart TD
A[File Change Detected] --> B{Determine Compilation Target}
B -->|Client Only| C[Client Compiler]
B -->|Server Component| D[Server Compiler]
B -->|Edge Runtime| E[Edge Compiler]
B -->|Multi-target| F[Multiple Compilers]
C --> G[Standard Webpack HMR]
D --> H[Server Cache Invalidation]
E --> I[Edge Context Clearing]
F --> J[Coordinated Compilation]
H --> K[Clear Require Cache]
H --> L[Delete Module References]
H --> M[Reset Fetch Cache]
I --> N[Clear Module Context]
I --> O[Reset Timers/Intervals]
I --> P[Remove Context Paths]
K --> Q[NextJsRequireCacheHotReloader]
L --> Q
M --> Q
N --> R[Edge Runtime Sandbox]
O --> R
P --> R
Q --> S[Emit assetEmitted Hook]
Q --> T[Emit afterEmit Hook]
R --> U[Clear Module Contexts]
G --> V[HMR Message Generation]
S --> V
T --> V
U --> V
V --> W[WebSocket Broadcast]
stateDiagram-v2
[*] --> Idle
Idle --> PageRequest : HTTP Request
PageRequest --> CheckEntry : Check if entry exists
CheckEntry --> EntryExists : Entry found
CheckEntry --> CreateEntry : Entry missing
CreateEntry --> AddToWebpack : Add to webpack entries
AddToWebpack --> Compiling : Start compilation
EntryExists --> CheckUpToDate : Verify compilation status
CheckUpToDate --> Serving : Up to date
CheckUpToDate --> Compiling : Needs recompilation
Compiling --> CompilationDone : Compilation finished
CompilationDone --> HasErrors : Check for errors
HasErrors --> ErrorHandling : Errors found
HasErrors --> Serving : No errors
ErrorHandling --> Serving : Fallback to error page
Serving --> Idle : Response sent
Idle --> FileChange : File system change
FileChange --> InvalidateEntry : Mark entries dirty
InvalidateEntry --> Idle : Ready for recompilation
graph TB
subgraph "Compilation Coordination"
A[File Change Detected]
B{Determine Affected Compilers}
C[Client Compilation]
D[Server Compilation]
E[Edge Compilation]
F[Compilation Results]
G{All Compilers Done?}
H[Aggregate Results]
I[Send HMR Message]
end
subgraph "Error Prioritization"
J{Has Server Errors?}
K[Show Server Errors]
L{Has Client Errors?}
M[Show Client Errors]
N{Has Edge Errors?}
O[Show Edge Errors]
P[Success State]
end
A --> B
B --> C
B --> D
B --> E
C --> F
D --> F
E --> F
F --> G
G -->|No| G
G -->|Yes| H
H --> J
J -->|Yes| K
J -->|No| L
L -->|Yes| M
L -->|No| N
N -->|Yes| O
N -->|No| P
K --> I
M --> I
O --> I
P --> I
sequenceDiagram
participant FS as File System Watcher
participant Webpack as Webpack Compiler
participant Tracker as Page Change Tracker
participant Cache as Server Cache
participant HMR as HMR System
participant Client as Browser Client
FS->>Webpack: Server component file changed
Webpack->>Webpack: Compile with RSC layer tracking
Webpack->>Tracker: Emit compilation stats
Tracker->>Tracker: Calculate module hashes
Note over Tracker: Separate client & server layer hashes
Tracker->>Tracker: Compare with previous hashes
alt Server component changed
Tracker->>Cache: Clear server module cache
Cache->>Cache: Delete require cache entries
Cache->>Cache: Reset fetch cache
Tracker->>HMR: Mark as server component change
HMR->>Client: Send SERVER_COMPONENT_CHANGES
Client->>Client: router.hmrRefresh()
else Client component changed
Tracker->>HMR: Mark as client change
HMR->>Client: Send BUILT message
Client->>Client: Apply React Fast Refresh
end
graph TB
subgraph "Webpack Layers"
RSCLayer[reactServerComponents]
SSRLayer[serverSideRendering]
ClientLayer[appPagesBrowser/pagesDirBrowser]
EdgeLayer[pagesDirEdge/apiEdge/middleware]
end
subgraph "Module Resolution"
ServerComponents[Server Components]
ClientComponents[Client Components]
SharedComponents[Shared Components]
EdgeFunctions[Edge Functions]
end
subgraph "Compilation Targets"
ServerBundle[Server Bundle]
ClientBundle[Client Bundle]
EdgeBundle[Edge Bundle]
end
ServerComponents --> RSCLayer
ClientComponents --> ClientLayer
SharedComponents --> SSRLayer
EdgeFunctions --> EdgeLayer
RSCLayer --> ServerBundle
SSRLayer --> ServerBundle
ClientLayer --> ClientBundle
EdgeLayer --> EdgeBundle
graph TB
subgraph "Node.js Runtime"
RequireCache[require.cache]
ModuleChildren[Module.children]
ModuleParent[Module.parent]
end
subgraph "Edge Runtime"
EdgeModuleContext[Module Context Map]
EdgeSandbox[Sandbox Context]
TimersManager[Timers/Intervals Manager]
end
subgraph "Next.js Caches"
ManifestCache[Build Manifest Cache]
FetchCache[Server Fetch Cache]
IncrementalCache[Incremental Cache]
end
subgraph "Cache Invalidation"
DeleteCache[deleteCache]
ClearModuleContext[clearModuleContext]
ResetFetch[resetFetch]
end
RequireCache --> DeleteCache
ModuleChildren --> DeleteCache
ModuleParent --> DeleteCache
EdgeModuleContext --> ClearModuleContext
EdgeSandbox --> ClearModuleContext
TimersManager --> ClearModuleContext
ManifestCache --> DeleteCache
FetchCache --> ResetFetch
IncrementalCache --> DeleteCache
flowchart TD
A[Module Change Detected] --> B{Module Type?}
B -->|Server Component| C[Clear Server Caches]
B -->|Client Component| D[Standard HMR]
B -->|Edge Function| E[Clear Edge Context]
B -->|Shared Module| F[Clear All Caches]
C --> G[Delete from require.cache]
C --> H[Clear manifest cache]
C --> I[Reset server fetch cache]
E --> J[Clear module contexts]
E --> K[Reset timers/intervals]
E --> L[Remove context paths]
F --> G
F --> H
F --> I
F --> J
F --> K
F --> L
G --> M[Update Module References]
H --> N[Rebuild Manifest]
I --> O[Reset Request Cache]
J --> P[Recreate Edge Context]
K --> P
L --> P
M --> Q[Send HMR Update]
N --> Q
O --> Q
P --> Q
graph TB
subgraph "Compilation Events"
A[Client Compilation Done]
B[Server Compilation Done]
C[Edge Compilation Done]
end
subgraph "Change Analysis"
D[Calculate Page Changes]
E[Determine Change Type]
F[Check for Errors]
end
subgraph "Message Types"
G[BUILDING]
H[BUILT]
I[SERVER_COMPONENT_CHANGES]
J[MIDDLEWARE_CHANGES]
K[RELOAD_PAGE]
L[SYNC]
end
subgraph "WebSocket Broadcast"
M[Format Message Payload]
N[Send to All Clients]
O[Handle Client Acknowledgments]
end
A --> D
B --> D
C --> D
D --> E
E --> F
F --> G
F --> H
F --> I
F --> J
F --> K
F --> L
G --> M
H --> M
I --> M
J --> M
K --> M
L --> M
M --> N
N --> O
flowchart TD
A[Compilation Results Available] --> B{Server Compilation Errors?}
B -->|Yes| C[Collect Server Errors]
B -->|No| D{Client Compilation Errors?}
C --> E[Format Server Error Messages]
E --> F[Send RELOAD_PAGE with Server Errors]
D -->|Yes| G[Collect Client Errors]
D -->|No| H{Edge Compilation Errors?}
G --> I[Format Client Error Messages]
I --> J[Send RELOAD_PAGE with Client Errors]
H -->|Yes| K[Collect Edge Errors]
H -->|No| L[No Compilation Errors]
K --> M[Format Edge Error Messages]
M --> N[Send RELOAD_PAGE with Edge Errors]
L --> O{Changes Detected?}
O -->|Server Components| P[Send SERVER_COMPONENT_CHANGES]
O -->|Client Changes| Q[Send BUILT]
O -->|Middleware Changes| R[Send MIDDLEWARE_CHANGES]
O -->|No Changes| S[Send SYNC]
F --> T[Client Handles Error Display]
J --> T
N --> T
P --> U[Client Handles Server Refresh]
Q --> V[Client Handles HMR Update]
R --> W[Client Handles Middleware Restart]
S --> X[Client Syncs State]
File Path | Class/Function | Primary Responsibility |
---|---|---|
/packages/next/src/server/dev/hot-reloader-webpack.ts |
HotReloaderWebpack |
Main HMR orchestrator for webpack builds |
/packages/next/src/server/dev/hot-reloader-turbopack.ts |
createHotReloaderTurbopack() |
Turbopack-specific HMR implementation |
/packages/next/src/server/dev/hot-middleware.ts |
WebpackHotMiddleware |
WebSocket communication layer |
/packages/next/src/server/dev/on-demand-entry-handler.ts |
onDemandEntryHandler() |
Dynamic entry point management |
/packages/next/src/build/webpack/plugins/nextjs-require-cache-hot-reloader.ts |
NextJsRequireCacheHotReloader |
Server-side cache invalidation plugin |
/packages/next/src/server/dev/require-cache.ts |
deleteCache() , deleteFromRequireCache() |
Node.js require cache management |
/packages/next/src/server/require-hook.ts |
Module resolution hooks | Custom require/resolve implementation |
/packages/next/src/server/web/sandbox/context.ts |
clearModuleContext() |
Edge runtime context management |
/packages/next/src/server/dev/hot-reloader-types.ts |
HMR_ACTIONS_SENT_TO_BROWSER |
HMR type definitions and interfaces |
File Path | Class/Function | Primary Responsibility |
---|---|---|
/packages/next/src/build/webpack-config.ts |
webpack configuration | Webpack configuration with HMR plugins |
/packages/next/src/server/lib/dev-bundler-service.ts |
DevBundlerService |
Unified bundler interface |
/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts |
setupDevBundler() |
Development bundler initialization |
/packages/next/src/server/dev/next-dev-server.ts |
NextDevServer |
Development server with HMR integration |
/packages/next/src/shared/lib/constants.ts |
COMPILER_NAMES |
Compiler type definitions |
/packages/next/src/server/dev/middleware-webpack.ts |
getOverlayMiddleware() |
Development middleware functions |
/packages/next/src/server/dev/turbopack-utils.ts |
Turbopack utilities | Route handling and issue processing |
File Path | Class/Function | Primary Responsibility |
---|---|---|
/packages/react-refresh-utils/ReactRefreshWebpackPlugin.ts |
ReactRefreshWebpackPlugin |
Webpack plugin for React Fast Refresh |
/packages/react-refresh-utils/loader.ts |
ReactRefreshLoader |
Webpack loader for React components |
/packages/react-refresh-utils/runtime.ts |
React Refresh globals | Global React Refresh runtime setup |
/packages/react-refresh-utils/internal/helpers.ts |
RefreshHelpers |
React Refresh utility functions |
/packages/react-refresh-utils/internal/ReactRefreshModule.runtime.ts |
Module runtime | Module-level React Refresh integration |
File Path | Class/Function | Primary Responsibility |
---|---|---|
/packages/next/src/client/dev/hot-reloader/app/hot-reloader-app.tsx |
HotReload component |
App Router HMR client |
/packages/next/src/client/dev/hot-reloader/pages/hot-reloader-pages.ts |
connect() function |
Pages Router HMR client |
/packages/next/src/client/dev/hot-reloader/app/use-websocket.ts |
useWebsocket() hook |
WebSocket management for App Router |
/packages/next/src/client/dev/hot-reloader/pages/websocket.ts |
connectHMR() |
WebSocket client for Pages Router |
/packages/next/src/client/dev/hot-middleware-client.ts |
HMR middleware client | Pages Router HMR event handler |
/packages/next/src/client/dev/on-demand-entries-client.ts |
On-demand entries ping | Page activity tracking client |
/packages/next/src/client/dev/hot-reloader/turbopack-hot-reloader-common.ts |
TurbopackHmr class |
Turbopack HMR client integration |
/packages/next/src/client/dev/report-hmr-latency.ts |
reportHmrLatency() |
HMR performance metrics reporting |
File Path | Class/Function | Primary Responsibility |
---|---|---|
/packages/next/src/build/webpack/loaders/next-style-loader/index.ts |
CSS HMR loader | CSS hot reloading with module support |
/packages/next/src/build/webpack/plugins/build-manifest-plugin.ts |
BuildManifestPlugin |
Asset manifest with React Refresh entries |
/packages/next/src/build/entries.ts |
Entry configuration | React Refresh runtime entry points |
/packages/next/src/build/swc/index.ts |
Turbopack integration | HMR events and identifier subscriptions |
- On-demand compilation: Only compile pages when requested
- Incremental builds: Leverage webpack's persistent cache
- Multi-compiler coordination: Optimize compilation order (client before server)
- Entry lifecycle management: Dispose inactive entries to prevent memory leaks
- Granular invalidation: Only clear caches for changed modules
- Context preservation: Maintain edge runtime contexts when possible
- Fetch cache management: Reset server-side fetch cache strategically
- Module reference cleanup: Properly clean parent/child module relationships
- Compilation error prioritization: Show most critical errors first
- Graceful degradation: Continue serving when possible during errors
- Error boundary integration: Provide detailed error information with source maps
- Automatic retry mechanisms: Retry compilation on transient failures
graph TB
subgraph "Entry Points"
DevServer["next dev server<br/>packages/next/src/server/dev/<br/>next-dev-server.ts"]
SetupBundler["setupDevBundler()<br/>packages/next/src/server/lib/<br/>router-utils/setup-dev-bundler.ts"]
end
subgraph "HMR Orchestration Layer"
HotReloaderWebpack["HotReloaderWebpack<br/>packages/next/src/server/dev/<br/>hot-reloader-webpack.ts"]
HotReloaderTurbopack["createHotReloaderTurbopack()<br/>packages/next/src/server/dev/<br/>hot-reloader-turbopack.ts"]
HotMiddleware["WebpackHotMiddleware<br/>packages/next/src/server/dev/<br/>hot-middleware.ts"]
HMRTypes["HMR Types & Actions<br/>packages/next/src/server/dev/<br/>hot-reloader-types.ts"]
end
subgraph "Build Pipeline Integration"
WebpackConfig["webpack-config.ts<br/>packages/next/src/build/<br/>webpack-config.ts"]
RequireCachePlugin["NextJsRequireCacheHotReloader<br/>packages/next/src/build/webpack/plugins/<br/>nextjs-require-cache-hot-reloader.ts"]
ReactRefreshPlugin["ReactRefreshWebpackPlugin<br/>packages/react-refresh-utils/<br/>ReactRefreshWebpackPlugin.ts"]
BuildManifestPlugin["BuildManifestPlugin<br/>packages/next/src/build/webpack/plugins/<br/>build-manifest-plugin.ts"]
end
subgraph "Entry Management"
OnDemandHandler["onDemandEntryHandler()<br/>packages/next/src/server/dev/<br/>on-demand-entry-handler.ts"]
DevBundlerService["DevBundlerService<br/>packages/next/src/server/lib/<br/>dev-bundler-service.ts"]
Entries["Entry Configuration<br/>packages/next/src/build/<br/>entries.ts"]
end
subgraph "Cache Management Layer"
RequireCache["deleteCache() & deleteFromRequireCache()<br/>packages/next/src/server/dev/<br/>require-cache.ts"]
RequireHook["Module Resolution Hooks<br/>packages/next/src/server/<br/>require-hook.ts"]
ModuleContext["clearModuleContext()<br/>packages/next/src/server/web/<br/>sandbox/context.ts"]
SandboxIndex["Sandbox Operations<br/>packages/next/src/server/web/<br/>sandbox/index.ts"]
end
subgraph "Client Communication"
AppHMR["HotReload Component<br/>packages/next/src/client/dev/<br/>hot-reloader/app/hot-reloader-app.tsx"]
PagesHMR["connect() Function<br/>packages/next/src/client/dev/<br/>hot-reloader/pages/hot-reloader-pages.ts"]
UseWebSocket["useWebsocket() Hook<br/>packages/next/src/client/dev/<br/>hot-reloader/app/use-websocket.ts"]
WebSocketClient["connectHMR()<br/>packages/next/src/client/dev/<br/>hot-reloader/pages/websocket.ts"]
HMRMiddlewareClient["HMR Middleware Client<br/>packages/next/src/client/dev/<br/>hot-middleware-client.ts"]
end
subgraph "React Integration"
ReactRefreshLoader["ReactRefreshLoader<br/>packages/react-refresh-utils/<br/>loader.ts"]
ReactRefreshRuntime["React Refresh Runtime<br/>packages/react-refresh-utils/<br/>runtime.ts"]
ReactRefreshHelpers["RefreshHelpers<br/>packages/react-refresh-utils/<br/>internal/helpers.ts"]
ReactModuleRuntime["Module Runtime<br/>packages/react-refresh-utils/<br/>internal/ReactRefreshModule.runtime.ts"]
end
subgraph "Development Utilities"
TurbopackUtils["Turbopack Utilities<br/>packages/next/src/server/dev/<br/>turbopack-utils.ts"]
MiddlewareWebpack["getOverlayMiddleware()<br/>packages/next/src/server/dev/<br/>middleware-webpack.ts"]
OnDemandClient["On-Demand Entries Client<br/>packages/next/src/client/dev/<br/>on-demand-entries-client.ts"]
HMRLatency["reportHmrLatency()<br/>packages/next/src/client/dev/<br/>report-hmr-latency.ts"]
end
%% Entry Point Dependencies
DevServer --> SetupBundler
SetupBundler --> HotReloaderWebpack
SetupBundler --> HotReloaderTurbopack
%% HMR Orchestration Dependencies
HotReloaderWebpack --> HotMiddleware
HotReloaderWebpack --> OnDemandHandler
HotReloaderWebpack --> HMRTypes
HotReloaderTurbopack --> HotMiddleware
HotReloaderTurbopack --> HMRTypes
HotReloaderTurbopack --> TurbopackUtils
%% Build Pipeline Dependencies
HotReloaderWebpack --> WebpackConfig
WebpackConfig --> RequireCachePlugin
WebpackConfig --> ReactRefreshPlugin
WebpackConfig --> BuildManifestPlugin
WebpackConfig --> Entries
%% Entry Management Dependencies
HotReloaderWebpack --> OnDemandHandler
HotReloaderTurbopack --> DevBundlerService
OnDemandHandler --> DevBundlerService
%% Cache Management Dependencies
RequireCachePlugin --> RequireCache
RequireCachePlugin --> ModuleContext
HotReloaderWebpack --> RequireCache
HotReloaderTurbopack --> ModuleContext
RequireCache --> RequireHook
ModuleContext --> SandboxIndex
%% Client Communication Dependencies
HotMiddleware -.WebSocket.-> AppHMR
HotMiddleware -.WebSocket.-> PagesHMR
HotMiddleware -.WebSocket.-> HMRMiddlewareClient
AppHMR --> UseWebSocket
PagesHMR --> WebSocketClient
AppHMR --> HMRLatency
PagesHMR --> HMRLatency
OnDemandHandler -.-> OnDemandClient
%% React Integration Dependencies
ReactRefreshPlugin --> ReactRefreshLoader
ReactRefreshPlugin --> ReactRefreshRuntime
ReactRefreshLoader --> ReactRefreshHelpers
ReactRefreshLoader --> ReactModuleRuntime
ReactRefreshRuntime --> ReactRefreshHelpers
%% Development Utilities Dependencies
DevServer --> MiddlewareWebpack
HotReloaderWebpack --> MiddlewareWebpack
Component | Webpack | Turbopack | Client | Server | Edge | Cache |
---|---|---|---|---|---|---|
HotReloaderWebpack | ✅ Primary | ❌ | ✅ WebSocket | ✅ Primary | ✅ Compiler | ✅ Require |
HotReloaderTurbopack | ❌ | ✅ Primary | ✅ WebSocket | ✅ Primary | ✅ Compiler | ✅ Context |
WebpackHotMiddleware | ✅ Events | ✅ Events | ✅ WebSocket | ✅ Stats | ✅ Stats | ❌ |
OnDemandEntryHandler | ✅ Entries | ❌ | ✅ Ping | ✅ Pages | ✅ Routes | ❌ |
NextJsRequireCacheHotReloader | ✅ Plugin | ❌ | ❌ | ✅ Cache | ✅ Context | ✅ Primary |
ReactRefreshWebpackPlugin | ✅ Plugin | ❌ | ✅ Runtime | ❌ | ❌ | ❌ |
DevBundlerService | ✅ Interface | ✅ Interface | ❌ | ✅ Pages | ✅ Routes | ❌ |
Next.js implements different HMR strategies for App Router and Pages Router, reflecting their architectural differences:
sequenceDiagram
participant Client as App Router Client
participant WS as WebSocket (/_next/webpack-hmr)
participant HMRClient as App HMR Component
participant Router as App Router
participant RSC as Server Components
Client->>WS: Connect via useWebsocket hook
WS->>HMRClient: serverComponentChanges + hash
HMRClient->>HMRClient: Set cookie with hash
HMRClient->>Router: router.hmrRefresh()
Router->>Router: startTransition for smooth update
Router->>RSC: Fetch with isHmrRefresh: true
RSC->>Router: Updated server component tree
Router->>Client: Selective cache invalidation
Note over Client: State preserved, no full reload
Key Characteristics:
- React Hook-based: Uses
useWebsocket()
anduseEffect()
for WebSocket management - Server Component Support: Custom
hmrRefresh()
method for RSC updates - State Preservation: Selective cache invalidation preserves navigation state
- Smooth Transitions: Uses React 18
startTransition()
for better UX - Complex Routing: Handles parallel routes, nested layouts, and slots
sequenceDiagram
participant Client as Pages Router Client
participant WS as WebSocket (/_next/webpack-hmr)
participant HMRClient as Pages HMR Handler
participant Router as Pages Router
participant Module as Module System
Client->>WS: Connect via connectHMR()
WS->>HMRClient: built + hash
HMRClient->>HMRClient: Fetch HMR manifest
HMRClient->>Module: Apply webpack HMR
Module->>Router: Standard module replacement
Router->>Client: Page-level updates
Note over Client: Traditional HMR or full reload
Key Characteristics:
- Imperative Management: Direct WebSocket connection without React hooks
- Traditional HMR: Standard webpack module replacement flow
- Full Reloads: Server component changes trigger
window.location.reload()
- Simpler Architecture: Page-based routing without complex nesting
- Backward Compatibility: Maintains compatibility with older Next.js patterns
Feature | App Router | Pages Router |
---|---|---|
WebSocket Management | React hooks (useWebsocket ) |
Direct connection (connectHMR ) |
Server Components | router.hmrRefresh() with state preservation |
Full page reload |
Routing Updates | ACTION_HMR_REFRESH with selective invalidation |
Standard module replacement |
Error Boundaries | AppDevOverlayErrorBoundary |
Basic error overlay |
State Management | React context integration | Global window object |
Entry Points | Complex with parallel routes/slots | Simple page-to-file mapping |
Next.js server-side HMR is a comprehensive system that:
- Coordinates multiple webpack compilers (client, server, edge) with intelligent synchronization
- Provides specialized server component handling with granular cache invalidation
- Implements sophisticated cache management across Node.js require cache and Edge runtime contexts
- Uses WebSocket communication for real-time development updates
- Optimizes for performance through on-demand compilation and selective invalidation
- Handles complex error scenarios with prioritization and graceful recovery
The system involves 50+ files across multiple packages, with precise integration points:
- 9 core server HMR classes/functions handling orchestration and coordination
- 5 webpack plugins providing cache invalidation and React Fast Refresh
- 8 client-side components managing WebSocket communication and UI updates
- 12 cache management utilities handling Node.js and Edge runtime contexts
- 15+ build system integration points coordinating compilation and asset management
This architecture enables Next.js to provide seamless server-side development experience while maintaining consistency across multiple runtime environments and supporting advanced React features like Server Components.