Architecture Overview
Server Runtime
Rendering Pipeline
Client Navigation
Caching and Export
Development Tools
Build and Configuration
Ecosystem Packages
Testing Infrastructure
How It Works
The following files were used as context for generating this wiki page:
The Edge Sandbox Context subsystem provides a controlled virtual machine execution environment for running Edge Runtime functions, middleware, and API routes within Next.js. Because Edge functions execute in a restricted environment modeled on standard Web APIs rather than full Node.js server environments, Next.js implements a specialized module context loader and V8-backed runtime using next/dist/compiled/edge-runtime. This setup bridges user code with isolated global bindings, simulated environment variables, polyfilled Node.js built-in modules, and resource cleanup managers.
To maintain strict security boundaries and API limitations, the sandbox implements controlled stubbing for unsupported Node.js features and intercepts global execution states. When developers import unsupported modules (such as fs or net), proxy wrappers dynamically throw unsupported API errors.
Furthermore, the sandbox hooks into error stack formatting, runtime error inspection, and development overlays to ensure that execution traces inside the edge context map correctly back to source code locations.
The sandbox architecture caches initialized module contexts to avoid repeated compilation overhead across incoming requests. Module contexts are stored globally in moduleContexts (a Map<string, ModuleContext>) and pendingModuleCaches (a Map<string, Promise<ModuleContext>>). A ModuleContext interface combines the compiled EdgeRuntime instance, a map of loaded paths, and a set of warned evaluations.
When file changes or hot-reloads occur, clearModuleContext(path: string) inspects active and pending module caches. If a cached module context contains the modified file path, the entry is evicted, and associated timer resources managed by intervalsManager and timeoutsManager are purged via .removeAll().
Similarly, clearAllModuleContexts() resets all active timers and clears both caches completely.
Edge runtime functions do not have direct access to the host Node.js process object. To provide seamless compatibility with standard environment access patterns, Next.js constructs a specialized process polyfill using createProcessPolyfill(env).
The polyfill merges process.env with injected custom environments via buildEnvironmentVariablesFrom(injectedEnvironments), explicitly appending NEXT_RUNTIME: 'edge'.
For all other properties on the native process object (excluding env), Object.defineProperty is used to intercept property access. If user code attempts to invoke a property that is a function (e.g., process.nextTick or process.cwd()), a getter throws an unsupported API error referencing process.${key}.
Properties can also be dynamically overridden by assigning values to processPolyfill.
When user code running inside the Edge Sandbox imports or invokes forbidden Node.js APIs or built-in modules, Next.js enforces strict restrictions via throwUnsupportedAPIError and __import_unsupported.
Sources: packages/next/src/server/web/sandbox/context.ts:129-135, packages/next/src/server/web/globals.ts:57-61
The __import_unsupported function returns a specialized Proxy object. Any attempt to access properties (other than .then), construct instances, or invoke the proxy function triggers an immediate error citing the unsupported Node.js module name.
Similarly, addStub attaches property getters to the EdgeRuntime context that invoke throwUnsupportedAPIError(name) when accessed.
Caution
Importing restricted Node.js core modules (such as fs, net, or child_process) in Edge runtime files will throw an error at runtime unless guarded by conditional environment checks.
The execution lifecycle of an Edge handler is orchestrated by the run function in sandbox.ts, wrapped with withTaggedErrors in development mode to decorate errors with edge-server compiler tags.
Sources: packages/next/src/server/web/sandbox/sandbox.ts:49-70, packages/next/src/server/web/sandbox/sandbox.ts:111-163
The execution sequence proceeds through the following steps:
getRuntimeContext(params) retrieves or initializes the module context, exposes shared caches (__incrementalCache, __serverComponentsHmrCache, NEXT_CLIENT_ASSET_SUFFIX), and evaluates requested module paths into the V8 context.runtime.context._ENTRIES.['HEAD', 'GET'].edgeSandboxNextRequestContext and requestStore asynchronous local storage providers, mapping headers and setting up request metadata.To ensure stack traces originating inside the Edge sandbox or Node.js server environments provide accurate source maps and developer-friendly formatting, Next.js implements error inspection patching via packages/next/src/server/patch-error-inspect.ts.
The error inspection subsystem overrides Error.prepareStackTrace with prepareUnsourcemappedStackTrace and attaches custom inspection symbols (nodejs.util.inspect.custom for Node.js environments and edge-runtime.inspect.custom for edge-lite runtimes).
During error serialization or inspection, parseAndSourceMap extracts error.stack, strips internal React stack frames past react_stack_bottom_frame or react-stack-bottom-frame, and parses stack frames.
It resolves sourcemapped frames using getSourcemappedFrameIfPossible against cached source maps, filters anonymous sandwich frames, and rebuilds formatted stacks.
Development errors and console logs captured within edge and server runtimes are forwarded to the client browser or development overlay via packages/next/src/next-devtools/userspace/app/forward-logs.ts and use-error-handler.ts.
Sources: packages/next/src/next-devtools/userspace/app/forward-logs.ts:88-130, packages/next/src/next-devtools/userspace/app/errors/use-error-handler.ts:22-46
The logging subsystem maintains a logQueue that batches log entries (any-logged-error, console, formatted-error) and schedules non-blocking transmission (scheduleLogSend) using requestAnimationFrame and setTimeout (afterThisFrame).
When unhandled errors or rejections occur, forwardUnhandledError captures uncaught errors, extracts owner stacks using getErrorStackWithOwnerStack (backed by React owner stack tracing in stitched-error.ts), and queues log entries with source type designations.
Additionally, handleConsoleError intercepts console error arguments, parses environment names, wraps errors using createConsoleError, and dispatches them asynchronously through microtask queues.
The sandbox provides explicit polyfills for supported Node.js core modules through NativeModuleMap, granting safe subset access to standard APIs.
Supported modules mapped in NativeModuleMap include 'node:buffer', 'node:events', and 'node:async_hooks'.
Additionally, WebAssembly bindings associated with edge functions are compiled asynchronously into WebAssembly.Module instances via loadWasm, reading asset files from disk and mapping them by binding name.