Deep Dive: server.js
An exhaustive architectural review of dinou/core/server.js, the framework's main Express server orchestrator.
Path:./dinou/core/server.js
Role: Parent Node.js process. Responsible for starting the Express server, handling wildcard page routing and static asset delivery, executing Server Components to generate the RSC Flight payload, piping the Flight stream to the SSR subprocess, exposing endpoints to execute client-invoked Server Functions (Server Actions), and managing the dynamic transpilation hooks (Babel register, CSS modules require, and Dev HMR cache evictions).
š” Overview
The server.js file is the root entry point of the ejected web server. It runs as a CommonJS (CJS) process in Node.js executed with the --conditions=react-server flag. During startup, it bootstraps the runtime environment by overriding Node's module resolution for React, registering custom path aliases, establishing compilation hooks for JSX/TSX, CSS Modules, and static assets, and setting up file watchers for Hot Module Replacement (HMR). During runtime, it serves static assets, reads and writes cookies and headers, executes the page components to generate the binary RSC payload, and pipes this payload to the HTML SSR subprocess.
server.js File Structure & Lifecycle
Below is a visual map outlining the lifecycle phases and core duties of the ejected server.js file:
š¦ 1. Module Resolution Hack
React Server Components (RSC) require a specialized build of React (react.react-server.js) that excludes client-only hooks like useState and useEffect to ensure pure server-side execution.
Because standard CommonJS require("react") calls default to loading React's client-side build in Node.js, Dinou intercepts the module resolver by overriding Module._resolveFilename to force the loading of server-specific files (like react.react-server.js and react-dom.react-server.js) when files are loaded via require():
const Module = require("module");
const originalResolveFilename = Module._resolveFilename;
Module._resolveFilename = function (request, parent, isMain, options) {
if (!isWebpack) { // Webpack handles its own resolver manifests
if (request === "react") return reactServerPath;
if (request === "react-dom") return reactDomServerPath;
if (request === "react/jsx-runtime") return reactJsxRuntimePath;
if (request === "react/jsx-dev-runtime") return reactJsxDevRuntimePath;
}
return originalResolveFilename.call(this, request, parent, isMain, options);
};Why this is critical:
- Prevents Duplicate React Builds: Ensures Node.js doesn't load both the client and server builds of React at the same time, which would corrupt React's internal state and cause crashes during rendering.
- Delegation in Webpack Mode: When bundling with Webpack (
isWebpack = true), Dinou skips this manual override because it callswebpackRegister()(fromreact-server-dom-webpack/node-register). This official React helper automatically configures Node.js to resolve thereact-serverbuilds and map Client Components using Webpack's manifest.
āļø 2. On-the-fly Transpilation
Node.js cannot natively parse TypeScript (.ts/.tsx) or JSX syntax. Instead of requiring you to pre-compile your server code into a build directory before starting Node, Dinou registers @babel/register at process startup.
This hook intercepts synchronous CommonJS require() calls, transpiling TypeScript, JSX brackets, and ES Modules (import/export) in memory on-the-fly whenever a file is loaded:
const babelRegister = require("@babel/register");
babelRegister({
ignore: [/node_modules[\/](?!dinou)/], // Transpile app files & ejected core files
presets: [
["@babel/preset-react", { runtime: "automatic" }],
"@babel/preset-typescript",
],
plugins: ["@babel/transform-modules-commonjs"],
extensions: [".js", ".jsx", ".ts", ".tsx"],
});Babel Register vs. ESM Loader (Why both exist)
Dinou employs two complementary JIT transpilation mechanisms because Node.js separates CommonJS loading (require()) from ES Module loading (import()):
@babel/register(CommonJS Scope): Hooks into Node's synchronousrequire()pipeline. It is initialized at the top of both Node processes (server.jsandrender-html.js) to handle CommonJSrequire()calls for TypeScript/JSX files, CSS modules, and asset hooks.babel-esm-loader.js(ESM Scope): Loaded via Node's--import ./dinou/core/register-loader.mjsstartup flag in both processes. It intercepts dynamicimport()calls loaded asynchronously inside Node's native ES Module pipeline, powering React Server Components (RSC) and mapping Client Component references onto the Flight stream.
The Critical Role of the ESM Loader in RSC: When executing Server Components, Node loads files natively as ES Modules. If it imports a component marked with "use client", the ESM Loader intercepts the request, discards the client-only JS body, and registers a client reference stub (via registerClientReference) to map the component onto the Flight stream. This prevents Node from executing browser-specific code (like useState) that would crash the server.
šØ 3. Assets & Styles Loading
To allow components to import non-JS assets directly, the server installs require extension overrides:
- CSS Modules Hook (
css-require-hook.js): Intercepts.cssimports, compiles class selectors on-the-fly using PostCSS, generates deterministic hashed names viacreateScopedName.js, and returns a JSON dictionary mapping the original keys to the hashed classnames. - Asset Loader Hook (
asset-require-hook.js): Intercepts media files (using extensions fromasset-extensions.js), calculates an asset hash, copies it, and returns the static public URL prefix string (e.g.,"/assets/logo.a1b2c3.png").
š 4. Dev HMR Engine & Manifest-Driven Cache Eviction
During development, when you edit components or toggle the "use client" directive, Dinou automatically updates Node.js's in-memory cache without needing a server restart.
What is the Client Manifest?
The client manifest is a JSON metadata map (react-client-manifest.json) generated by the bundler (esbuild, Rollup, or Webpack) that lists all components marked with "use client":
{
"file:///C:/Users/.../src/components/Counter.tsx": {
"id": "/assets/Counter.js",
"chunks": ["/assets/Counter.js"],
"name": "Counter"
}
}1. Manifest Watching & Boundary Transitions
The server uses chokidar to watch the manifest file. When you add or remove "use client" in a file, the component transitions between a Server Component and a Client Component, causing the bundler to update the manifest.
When Chokidar detects a manifest change, server.js diffs the new manifest keys against the previous ones to identify which files changed boundaries and immediately invalidates their cache.
2. Recursive Cache Eviction (clearRequireCache)
Node.js permanently caches modules loaded via require() in require.cache. Deleting only the modified child file from require.cache is not enough because parent layouts and pages in src/ still retain references to the old module in memory.
function clearRequireCache(modulePath, visited = new Set()) {
try {
const resolved = require.resolve(modulePath);
if (visited.has(resolved)) return;
visited.add(resolved);
if (require.cache[resolved]) {
delete require.cache[resolved]; // Remove from Node's cache
// Recursively evict parents in src/ so updates propagate upwards
const parents = getParents(resolved);
for (const parent of parents) {
if (parent.startsWith(path.resolve(process.cwd(), "src"))) {
clearRequireCache(parent, visited);
}
}
}
} catch (err) {}
}clearRequireCache removes the modified file from Node's cache and uses getParents() to recursively evict all parent modules inside src/. On the next HTTP request, Node re-evaluates the entire component hierarchy with fresh code.
3. I/O Race Condition Prevention
Because file system change events can trigger while the bundler is still writing to disk, server.js wraps manifest reads in retry mechanisms (loadManifestWithRetry and readJSONWithRetry using Atomics.wait). This prevents JSON.parse crashes caused by reading empty or incomplete files.
š”ļø 5. Context State & Cookie Injection
Dinou links Express request and response scopes to React Server Component trees using Node's AsyncLocalStorage (configured in request-context.js).
Why does Dinou use three distinct context wrappers?
A single unified context object cannot satisfy the conflicting networking, security, and process isolation constraints present during a request's lifecycle. Dinou splits request states into three environment-specific containers:
| Context Wrapper | Execution Thread | Request Phase | Redirection Method | Cookie Mutations | Design Constraint |
|---|---|---|---|---|---|
getContext | Master Server (Express) | GET /____rsc_payload (Soft SPA navigation) | Intercepts redirect; writes custom x-rsc-redirect header. | Writes traditional Set-Cookie headers. | Prevents standard 302 redirects from breaking AJAX fetch routers. |
getContextForServerFunctionEndpoint | Master Server (Express) | POST /____server_function (Server Functions) | Throws dinou-internal-redirect to abort execution mid-stream. | Hybrid: Mid-stream cookie writes append command packets. Blocks HttpOnly. | Handles cookie updates and redirection signals inside active Flight stream channels. |
contextForChild | Child Render Process (Fork) | GET / (Initial load / Hard reload) | Blocked (No res object available). | Blocked (No res object available). | Serializes request headers across IPC. Enforces strict sandbox isolation. |
Architectural Flow Mapping:
The server provisions request contexts through three distinct wrappers:
A. Standard Request Context (getContext)
Executed during standard page requests. This wrapper intercepts calls to Express's native response methods using a custom security guard helper, safeResCall:
const safeResCall = (methodName, ...args) => {
if (hasRedirected) return;
// 1. Prevent ERR_HTTP_HEADERS_SENT Node.js server crashes
if (res.headersSent) {
if (methodName === "redirect" && req.path.includes("____rsc_payload")) return;
console.log(`[Dinou] res.${methodName} called but headers already sent. Ignoring.`);
return; // Exit silently
}
if (methodName === "redirect") {
hasRedirected = true;
let url = args.length === 2 ? args[1] : args[0];
let status = args.length === 2 ? args[0] : 302;
// 2. Open-Redirect Vulnerability Filter
const resolvedUrl = resolveRelativeUrl(url, req.path);
let finalUrl = "/";
if (typeof resolvedUrl === "string" && resolvedUrl.startsWith("/") && !resolvedUrl.startsWith("//")) {
finalUrl = resolvedUrl;
} else {
console.warn(`[Dinou Security] Blocked unsafe redirect to: ${url}`);
}
// 3. RSC Router Redirect Handling
if (req.path.includes("____rsc_payload")) {
res.setHeader("x-rsc-redirect", finalUrl);
res.status(200).end();
return;
}
res.redirect.apply(res, [status, finalUrl]);
return;
}
return res[methodName].apply(res, args);
};
// 4. Return the consolidated mock request/response context
const context = {
req: {
cookies: { ...req.cookies },
headers: {
"user-agent": req.headers["user-agent"],
cookie: req.headers["cookie"],
referer: req.headers["referer"],
host: req.headers["host"],
authorization: req.headers["authorization"],
"accept-language": req.headers["accept-language"],
"x-forwarded-for": req.headers["x-forwarded-for"],
forwarded: req.headers["forwarded"],
"content-type": req.headers["content-type"],
origin: req.headers["origin"],
},
query: { ...req.query },
path: req.path,
method: req.method,
},
res: {
status: (code) => safeResCall("status", code),
setHeader: (name, value) => safeResCall("setHeader", name, value),
clearCookie: (name, options) => safeResCall("clearCookie", name, options),
cookie: (name, value, options) => safeResCall("cookie", name, value, options),
redirect: (...args) => safeResCall("redirect", ...args),
},
};
return context;- Header Protection (Node Anti-Crash Guard): Writing headers after a response stream has started throws a fatal Node.js exception (
ERR_HTTP_HEADERS_SENT) that can crash the server process. ThesafeResCallhelper intercepts response mutations (likecookieorstatus) and exits silently if headers have already been sent. - Open-Redirect Mitigation: Validates target URLs to ensure they are relative paths (starting with a single slash
/) and do not contain protocol specifiers, preventing phishing redirects to external host domains. - RSC Router Sync: If the client navigates via a soft routing SPA transition (requesting a
____rsc_payloadpath) and a server component triggers a redirect, the server intercepts this redirect. Instead of sending a standard302status code (which the browser'sfetchAPI would follow transparently without updating the client-side SPA route), the server sends the target URL in a customx-rsc-redirectheader and responds with a200 OK.
B. Server Function Context (getContextForServerFunctionEndpoint)
Server Functions run inside POST request endpoints, where the server may already be streaming updates back to the browser. Under this setup, Dinou provisions context using a custom endpoint-specific wrapper:
function getContextForServerFunctionEndpoint(req, res) {
const context = {
req: {
cookies: { ...req.cookies },
headers: {
"user-agent": req.headers["user-agent"],
cookie: req.headers["cookie"],
referer: req.headers["referer"],
host: req.headers["host"],
authorization: req.headers["authorization"],
"accept-language": req.headers["accept-language"],
"x-forwarded-for": req.headers["x-forwarded-for"],
forwarded: req.headers["forwarded"],
"content-type": req.headers["content-type"],
origin: req.headers["origin"],
},
query: { ...req.query },
path: req.path,
method: req.method,
},
res: {
redirect: (urlOrStatus, url) => {
const rawUrl = url || urlOrStatus;
const referer = req.headers["referer"];
let refererPath = "/";
if (referer) {
try {
refererPath = new URL(referer).pathname;
} catch (e) {}
}
const resolvedUrl = resolveRelativeUrl(rawUrl, refererPath);
let finalUrl = "/";
if (typeof resolvedUrl === "string" && resolvedUrl.startsWith("/") && !resolvedUrl.startsWith("//")) {
finalUrl = resolvedUrl;
} else {
console.warn(`[Dinou Security] Blocked unsafe server function redirect to: ${rawUrl}`);
}
// Throw an exception to halt normal execution and trigger the redirect loop
throw {
$$type: "dinou-internal-redirect",
url: finalUrl,
};
},
status: (code) => {
if (!res.headersSent) res.status(code);
},
setHeader: (n, v) => {
if (!res.headersSent) res.setHeader(n, v);
},
cookie: (name, value, options) => {
// Scenario A: Headers not sent yet. Use native Express cookie setter.
if (!res.headersSent) {
res.setHeader("Content-Type", "text/x-component");
res.cookie(name, value, options);
return;
}
// Scenario B: Streaming active (Headers already flushed).
// Block HttpOnly because client-side JavaScript cannot write HttpOnly cookies.
if (options && options.httpOnly) {
console.error(`[Dinou Error] Cannot set HttpOnly cookie '${name}'... streaming active.`);
return;
}
// Inject cookie mutation command directly into the active flight stream
let cookieStr = `${name}=${encodeURIComponent(value)}`;
if (options) {
if (options.path) cookieStr += `; path=${options.path}`;
if (options.domain) cookieStr += `; domain=${options.domain}`;
if (options.maxAge) cookieStr += `; max-age=${options.maxAge}`;
if (options.expires) cookieStr += `; expires=${new Date(options.expires).toUTCString()}`;
if (options.secure) cookieStr += `; secure`;
if (options.sameSite) cookieStr += `; samesite=${options.sameSite}`;
}
res.write(`D:{"type":"cookie","cookie":${JSON.stringify(cookieStr)}}\n`);
},
clearCookie: (name, options) => {
if (!res.headersSent) {
res.setHeader("Content-Type", "text/x-component");
res.clearCookie(name, options);
return;
}
let cookieStr = `${name}=; Max-Age=0`;
const path = options?.path || "/";
cookieStr += `; path=${path}`;
if (options) {
if (options.domain) cookieStr += `; domain=${options.domain}`;
if (options.secure) cookieStr += `; secure`;
if (options.sameSite) cookieStr += `; samesite=${options.sameSite}`;
}
cookieStr += ";";
res.write(`D:{"type":"cookie","cookie":${JSON.stringify(cookieStr)}}\n`);
}
}
};
return context;
}1. Controlled Redirection & Exception Handling Loop
Because Server Functions run during POST calls that return streams, a standard HTTP 302 status cannot be written mid-response. Instead, the res.redirect implementation aborts further execution by throwing a dinou-internal-redirect object:
redirect: (urlOrStatus, url) => {
const rawUrl = url || urlOrStatus;
const resolvedUrl = resolveRelativeUrl(rawUrl, refererPath);
let finalUrl = resolvedUrl.startsWith("/") ? resolvedUrl : "/";
// Throw an exception to halt normal execution and trigger the redirect loop
throw {
$$type: "dinou-internal-redirect",
url: finalUrl,
};
}This exception is caught directly by the POST handler try-catch block inside POST /____server_function____:
try {
result = await requestStorage.run(context, async () => await fn(...args));
} catch (err) {
if (err && err.$$type === "dinou-internal-redirect") {
const safeUrl = JSON.stringify(err.url);
if (!res.headersSent) {
// Scenario A: Headers not sent yet. Return a direct JSON redirect payload.
res.setHeader("Content-Type", "application/json");
res.setHeader("X-Dinou-Redirect", err.url);
return res.status(200).json({ redirect: err.url });
} else {
// Scenario B: Headers already sent (active stream).
// Append a custom redirect instruction to the stream and close the connection.
res.write(`D:{"type":"redirect","url":${safeUrl}}\n`);
res.end();
return;
}
}
throw err; // bubble up normal exceptions
}2. Hybrid Cookie & Expiration Manager
The cookie setter implements a dual-mode behavior depending on the connection state:
cookie: (name, value, options) => {
// Scenario A: Headers not sent yet. Use native Express cookie setter.
if (!res.headersSent) {
res.setHeader("Content-Type", "text/x-component");
res.cookie(name, value, options);
return;
}
// Scenario B: Streaming active (Headers already flushed).
// Block HttpOnly because client-side JavaScript cannot write HttpOnly cookies.
if (options && options.httpOnly) {
console.error(`[Dinou Error] Cannot set HttpOnly cookie '${name}'... streaming active.`);
return;
}
// Inject cookie mutation command directly into the active flight stream
let cookieStr = `${name}=${encodeURIComponent(value)}`;
if (options) {
if (options.path) cookieStr += `; path=${options.path}`;
if (options.domain) cookieStr += `; domain=${options.domain}`;
if (options.maxAge) cookieStr += `; max-age=${options.maxAge}`;
if (options.expires) cookieStr += `; expires=${new Date(options.expires).toUTCString()}`;
if (options.secure) cookieStr += `; secure`;
if (options.sameSite) cookieStr += `; samesite=${options.sameSite}`;
}
res.write(`D:{"type":"cookie","cookie":${JSON.stringify(cookieStr)}}\n`);
}Cookie Creation Mechanics:
- Scenario A (Headers not sent): Utilizes Express's native
res.cookiemethod. It explicitly injects theContent-Type: text/x-componentheader (which represents React's RSC Flight stream contract) to initialize the network pipe before writing the cookie to the HTTP response header payload. - Scenario B (Streaming active): When response headers have already been flushed to the browser, standard HTTP header injection is no longer possible. To bypass this, Dinou manually serializes cookie attributes (including
domain,path,secure, andsameSite) into a standard formatted cookie string, wraps it inside a JSON structure, and streams it down the open HTTP channel usingres.write(). The browser runtime intercepts this special text packet and writes the cookie programmatically. - HttpOnly Isolation Security Guard: Browsers restrict access to
HttpOnlycookies to prevent Cross-Site Scripting (XSS) document hijacking. Because Scenario B relies on browser-side JavaScript to parse the stream and write cookies to the document, settingHttpOnlycookies is blocked once streaming starts. Dinou logs a console error to warn developers if this occurs.
Similarly, clearing cookies dynamically mid-stream uses a custom script injection command with Max-Age=0:
clearCookie: (name, options) => {
if (!res.headersSent) {
res.setHeader("Content-Type", "text/x-component");
res.clearCookie(name, options);
return;
}
let cookieStr = `${name}=; Max-Age=0`;
const path = options?.path || "/";
cookieStr += `; path=${path}`;
if (options) {
if (options.domain) cookieStr += `; domain=${options.domain}`;
if (options.secure) cookieStr += `; secure`;
if (options.sameSite) cookieStr += `; samesite=${options.sameSite}`;
}
cookieStr += ";";
res.write(`D:{"type":"cookie","cookie":${JSON.stringify(cookieStr)}}\n`);
}Cookie Deletion Mechanics:
- Scenario A (Headers not sent): Calls Express's native
res.clearCookiemethod, which appends a deletion header instructing the browser to discard the cookie. - Scenario B (Streaming active): Because headers cannot be modified mid-stream, Dinou simulates cookie deletion by setting
Max-Age=0. This formats a custom cookie command string that forces the cookie to expire immediately, instructing the browser to remove it.
C. Wildcard Child Context (contextForChild)
For initial loads or hard refreshes, rendering is delegated to a child thread. Because complex Node.js Express sockets cannot be sent directly over IPC (Inter-Process Communication), Dinou builds a serialized context:
const contextForChild = {
req: {
query: { ...req.query },
cookies: { ...req.cookies },
headers: {
"user-agent": req.headers["user-agent"],
cookie: req.headers["cookie"],
referer: req.headers["referer"],
host: req.headers["host"],
authorization: req.headers["authorization"],
"accept-language": req.headers["accept-language"],
"x-forwarded-for": req.headers["x-forwarded-for"],
forwarded: req.headers["forwarded"],
"content-type": req.headers["content-type"],
origin: req.headers["origin"],
},
path: req.path,
method: req.method,
}
};This cloned metadata is sent to the child process (render-html.js) during compilation, allowing Server Components to access cookies, authorization headers, and browser user-agents during server rendering.
This container is passed as an argument to the child process renderer function (renderAppToHtml) inside the wildcard router:
const appHtmlStream = renderAppToHtml(
reqPath,
JSON.stringify({ ...req.query }),
contextForChild, // Cloned context injected here
res,
capturedStatus,
isDynamic,
isPathBlocked
);Security Sandboxing & the omission of res: The response helper (res) is excluded from the child process context. This prevents the child rendering process from modifying cookies, headers, or redirects. All server state mutations are handled by the main server thread, keeping rendering logic decoupled from data mutation endpoints.
š 6. Routing & RSC Endpoints
Dinou's core server orchestrates two central endpoints inside core/server.js to handle user routing navigations and trigger Server Functions.
A. Serving RSC Payloads (serveRSCPayload)
Triggered on page navigations. In Dinou, the client-side SPA router intercepts link clicks and fetches RSC Flight payloads (React element trees) instead of initiating full HTML page requests. To ensure cache consistency and support Stale-While-Revalidate (SWR) patterns, Dinou exposes five distinct RSC routing endpoints:
| Endpoint Route | serveRSCPayload Flags | Target Payload | Caller & Client Role |
|---|---|---|---|
/____rsc_payload____/* | isOld: false, isStatic: false | Latest cache file (rsc.rsc) or dynamic SSR on-the-fly. | Standard client-side SPA router. Resolves pages during routing transitions. |
/____rsc_payload_old____/* | isOld: true, isStatic: false | Fallback cache file (rsc._old.rsc) or dynamic SSR. | Client hydration router. Triggered if a page is regenerating in background to match the old HTML. |
/____rsc_payload_static____/* | isOld: false, isStatic: true | Only cached static assets (rsc.rsc). Dynamic rendering is blocked. | Client-side router. Fetches static files directly without triggering server-side compilers. |
/____rsc_payload_old_static____/* | isOld: true, isStatic: true | Only cached backup assets (rsc._old.rsc). Dynamic rendering is blocked. | Client-side router. Fetches old static backup assets directly during active background builds. |
/____rsc_payload_error____/* (POST) | Not processed via serveRSCPayload | Error boundary view stream (getErrorJSX). | Client-side router. Invoked when client-side React rendering fails, returning an error UI stream. |
RSC Payload Execution Mapping:
How serveRSCPayload executes parameters:
The serveRSCPayload function uses the isOld and isStatic flags to compute the target file path and restrict rendering paths:
async function serveRSCPayload(req, res, isOld = false, isStatic = false) {
try {
// 1. Strip the matching routing prefix from req.path to resolve the raw route path
const reqPath = (
req.path.endsWith("/") ? req.path : req.path + "/"
).replace(
isOld
? isStatic
? "/____rsc_payload_old_static____"
: "/____rsc_payload_old____"
: isStatic
? "/____rsc_payload_static____"
: "/____rsc_payload____",
"",
);
// 2. Serve static cached file if path is not dynamic or if static only is requested
if ((!isDevelopment && !dynamicState.value) || isStatic) {
let currentGeneratedAt = null;
try {
const metadataPath = path.join("dist2", reqPath, "metadata.json");
if (existsSync(metadataPath)) {
const metaObj = JSON.parse(readFileSync(metadataPath, "utf8"));
currentGeneratedAt = metaObj.generatedAt || null;
}
} catch (e) {}
// Fallback triggers for Stale-While-Revalidate:
const useOld =
isOld ||
regenerating.has(reqPath) ||
(req.query.buildId &&
currentGeneratedAt &&
req.query.buildId !== String(currentGeneratedAt));
// Resolve the target payload file name
const payloadPath = path.resolve(
"dist2",
reqPath.replace(/^//, ""),
useOld ? "rsc._old.rsc" : "rsc.rsc",
);
// Serve file sychronously...
}
}
}1. Pre-compiled Static Cache (SSG / ISR) & Hydration Signals
To determine whether a request can be served directly from disk or requires dynamic server execution, serveRSCPayload evaluates the following condition:
if ((!isDevelopment && !dynamicState.value) || isStatic) { ... }The Role of isStatic & The One-Time Hydration Signal
When a user performs a full page load (Document Request) for a static SSG or ISR page, server.js serves the pre-rendered index.html file from disk and injects a one-time hydration script into the <head>:
<script>window.__DINOU_USE_STATIC__=true;</script>- First Hydration Fetch: During initial React client hydration, the router in
client.jsxdetectswindow.__DINOU_USE_STATIC__ === trueand issues a request to/____rsc_payload_static____/(which setsisStatic = truein Express). - Guaranteed Hydration Matching: Setting
isStatic = trueforcesserveRSCPayloadto bypass dynamic rendering checks and serve the exact pre-compiledrsc.rscpayload from disk, guaranteeing 100% hydration alignment with the served HTML. - Immediate Signal Reset: Immediately after initiating the fetch,
client.jsxresetswindow.__DINOU_USE_STATIC__ = false. This ensures that subsequent client-side SPA navigations (via<Link>) hit the standard/____rsc_payload____endpoint (isStatic = false), allowing the server to dynamically evaluate each new route.
The isDynamic Map & Dynamic Bailouts
The server maintains a global Map const isDynamic = new Map() to track route execution modes:
- Bailout Tracking: During build-time pre-rendering or ISR revalidation (via
buildStaticPages,generatingISG, orrevalidating), if a page invokes dynamic APIs (likecookies(),headers(), or declaresexport const dynamic = "force-dynamic"), Dinou setsdynamicState.value = true. - Standard Endpoint Evaluation (
isStatic = false): On SPA navigations to/____rsc_payload____, the server checks!dynamicState.value:- If
false(SSG/ISR route): The server reads the cachedrsc.rscfile directly from disk. - If
true(Dynamic route): The server bypasses disk cache and executes the dynamic SSR pipeline in real time.
- If
const useOld =
isOld ||
regenerating.has(reqPath) ||
(req.query.buildId &&
currentGeneratedAt &&
req.query.buildId !== String(currentGeneratedAt));
const payloadPath = path.resolve(
"dist2",
reqPath.replace(/^//, ""),
useOld ? "rsc._old.rsc" : "rsc.rsc"
);Stale-While-Revalidate Fallback: If the requested build ID does not match the generated date, or if a background compilation task is already running (regenerating.has(reqPath)), the server automatically streams the backup file (rsc._old.rsc) to prevent blocking the client.
2. Parameter & Route Validation
For dynamic pages, the server imports the route configuration module (page_functions) to validate parameters before rendering:
if (validateParamsFn) {
const isValid = await validateParamsFn(dynamicParams);
if (!isValid) isPathBlocked = true; // Returns 404
}
if (!isPathBlocked && allowISGValue === false) {
// Check if current dynamic route exists inside getStaticPaths() whitelist
const isPathAllowed = staticPathsSet.has(serializedQuery);
if (!isPathAllowed) isPathBlocked = true;
}3. Dynamic RSC Serialization
If the route is valid, the server runs the request inside the async storage context and streams the RSC Flight payload using React's renderToPipeableStream:
await requestStorage.run(context, async () => {
const jsx = await getJSX(reqPath, { ...req.query }, isNotFound, isDevelopment, isPathBlocked);
const manifest = isDevelopment ? loadManifestFromDisk() : cachedClientManifest;
const { pipe } = renderToPipeableStream(jsx, manifest);
pipe(res); // Stream Flight binary stream directly to client
});B. Executing Error Payloads (POST /____rsc_payload_error____)
Unlike standard rendering paths, the error endpoint is a POST route that does not invoke serveRSCPayload. Instead, it acts as an asynchronous Error Boundary renderer.
1. Rationale & Client Calling Flow
When a runtime exception occurs in client-side React code during dynamic routing or hydration, the browser's SPA runtime catches the exception. To prevent a blank screen, it posts the serialized exception stack back to the server:
- Trigger: React Client Error Boundary catching a render crash.
- Destination:
POST /____rsc_payload_error____/[route]with a body of{ error: { message, stack, name } }. - Output: A binary Flight stream representing the error visual fallback tree (which renders local
error.tsxtemplates if defined).
Error Boundary Payload Mapping:
2. Server-Side Execution Handler
The server intercepts the error, runs it inside the AsyncLocalStorage request scope, and compiles the fallback layout using getErrorJSX:
app.post(/^/____rsc_payload_error____/.*/?$/, async (req, res) => {
try {
// 1. Strip routing prefix to isolate page path
const reqPath = (
req.path.endsWith("/") ? req.path : req.path + "/"
).replace("/____rsc_payload_error____", "");
const context = getContext(req, res);
await requestStorage.run(context, async () => {
// 2. Resolve error JSX layout (searching for error.tsx templates)
const jsx = await getErrorJSX(
reqPath,
{ ...req.query },
req.body.error,
isDevelopment,
);
// 3. Serialize and stream error tree using React 19 pipeable streams
const manifest = isDevelopment ? loadManifestFromDisk() : cachedClientManifest;
const { pipe } = isWebpack
? renderToPipeableStream(jsx, manifest)
: renderToPipeableStream(jsx, pathToFileURL(process.cwd()).href + "/");
pipe(res);
});
} catch (error) {
console.error("Error rendering RSC:", error);
res.status(500).send("Internal Server Error");
}
});C. Wildcard Initial Load Handler (app.get(/^\/.*\/?$/))
This regex wildcard endpoint captures all standard browser GET requests (such as entering a URL directly or performing a hard refresh). Since these requests expect a fully rendered HTML page instead of an RSC Flight stream, the server handles them differently:
Wildcard Load Execution Mapping:
1. The Cache Gatekeeper Condition (All four flags required)
Before checking for the physical file on disk, the server checks a composite logical gatekeeper:
if (!isDevelopment && !dynamicState.value && pagePath && !isPathBlocked)Each flag is necessary to ensure correct rendering behavior and prevent security or layout bugs:
!isDevelopment: In local development, the user edits files in real-time. If the server served cached static HTML files, changes to React JSX wouldn't be reflected without rebuilds. Disabling caching in development ensures dynamic compilation is triggered on every reload.!dynamicState.value: Differentiates static/ISR pages from dynamic routes. Dynamic routes require fresh headers, cookies, or search parameters and cannot be cached as static index.html pages. Serving a static file here would bypass dynamic session state logic.pagePath: Confirms that the incoming request URL matches an actual React Server Component page file (e.g.,page.tsx) in thesrc/directory. If missing (like for missing files or static routes without matching page files), caching is skipped to prevent serving index pages for 404 responses.!isPathBlocked: Set by route-parameter validators (validateParams). If a user requests a page with invalid parameters and the validator blocks the route, bypassing this flag could serve static cached page structures to unauthorized users instead of returning a 404.
2. Pre-rendered HTML Cache & Hydration Hooks
If all four gatekeeper flags pass, the server reads the index page from the dist2/ folder:
const fileToRead = htmlPathOld || htmlPath;
if (existsSync(fileToRead) && !dynamicState.value) {
res.setHeader("Content-Type", "text/html");
let htmlContent = readFileSync(fileToRead, "utf8");
// Inject browser flags to direct SPA hydration
let scripts = `<script>window.__DINOU_USE_STATIC__=true;</script>`;
if (htmlPathOld) {
scripts += `<script>window.__DINOU_USE_OLD_RSC__=true;</script>`;
}
if (buildId) {
scripts += `<script>window.__DINOU_BUILD_ID__="${buildId}";</script>`;
}
htmlContent = htmlContent.replace("</head>", `${scripts}</head>`);
return res.send(htmlContent);
}Hydration Script Injection: Before sending the cached HTML file, the server injects script tags into the <head> to configure hydration options:
window.__DINOU_USE_STATIC__ = true: Instructs the client-side SPA router to retrieve its initial Flight payload from pre-built static files instead of initiating dynamic SSR requests.window.__DINOU_USE_OLD_RSC__ = true: During background ISR compilations, this directs the client to load the corresponding backup payload (rsc._old.rsc) to prevent cache mismatch errors.window.__DINOU_BUILD_ID__ = buildId: Syncs active build version timestamps to prevent runtime caching inconsistencies between the browser and server.
3. Dynamic SSR Pipeline with Concurrency Limiter
If the page is dynamic, not yet cached, or fails the gatekeeper checks, the server performs dynamic Server-Side Rendering (SSR). This rendering is managed by a process limiter:
processLimiter.run(async () => {
const appHtmlStream = renderAppToHtml(reqPath, JSON.stringify({ ...req.query }), contextForChild, res);
res.setHeader("Content-Type", "text/html");
appHtmlStream.pipe(res);
// Background Cache Build (Fire and Forget)
res.on("finish", () => {
if (!isDevelopment && res.statusCode === 200 && req.method === "GET" && isReady) {
generatingISG(reqPath, dynamicState); // Recompile page in background
}
});
// Concurrency Slot Release Hook
await new Promise((resolve) => {
appHtmlStream.on("end", resolve);
appHtmlStream.on("error", (error) => {
console.error("Stream error:", error);
if (!res.headersSent) res.status(500).send("Internal Server Error");
resolve();
});
res.on("close", resolve); // Release slot if user cancels request or closes tab
});
});- Process Limiter Slot Release Hook: The process limiter restricts concurrent page rendering requests to protect CPU resources. To prevent resource leaks, the wrapper holds the concurrency slot active using a Promise. It resolves and releases the slot only when the stream ends (
end), encounters an error (error), or the client cancels the connection (close). - Background ISG Generation: When the response stream completes (
res.on("finish")), if the request was successful, the server starts a background compilation task (generatingISG()) to render and cache the page on disk for subsequent visits.
D. Executing Server Functions (POST /____server_function____)
This endpoint processes client-side Server Functions. It includes built-in security features to protect server endpoints:
1. Origin & Anti-CSRF Verification
The server inspects header values to verify that request sources match host domains, and validates custom headers to prevent cross-site request forgery:
if (!isDevelopment && origin && !origin.includes(host)) {
return res.status(403).json({ error: "Invalid Origin" });
}
if (req.headers["x-server-function-call"] !== "1") {
return res.status(403).json({ error: "Missing security header" });
}2. Path Resolution & Directory Guard Verification
To handle requests from multiple operating systems and protect the file system, Dinou executes a strict path normalization and sandbox resolution pipeline inside the POST route:
let relativePath;
// A. Check if the URL is a relative reference (e.g. file:///src/...)
// If so, extract it directly without using fileURLToPath (which throws on Windows without a drive letter)
const isRelativeSrc = fileUrl.startsWith("file:///src/") || fileUrl.startsWith("file:///src\");
if (isRelativeSrc) {
relativePath = fileUrl.replace(/^file:///?/, "").trim();
} else {
// B. Convert absolute file:// URIs to localized system path formats
const resolvedPath = fileURLToPath(fileUrl);
relativePath = resolvedPath;
const normalizedCwd = normalizePathCase(process.cwd());
const normalizedResolved = normalizePathCase(resolvedPath);
if (normalizedResolved.startsWith(normalizedCwd)) {
relativePath = path.relative(normalizedCwd, normalizedResolved);
} else {
relativePath = relativePath.replace(/^[\/]+/, "");
}
}
// C. Anti-Directory-Traversal Guard Check
const normalizedRelative = relativePath.replace(/\/g, "/");
if (
normalizedRelative.startsWith("/") ||
normalizedRelative.includes("..") ||
normalizedRelative.includes(":")
) {
return res
.status(400)
.json({ error: "Invalid path: no absolute, traversal, or drive letter allowed" });
}
// D. Restrict to 'src/' folder: prepend 'src/' if missing, and resolve absolutePath
if (!relativePath.startsWith("src/") && !relativePath.startsWith("src\")) {
relativePath = path.join("src", relativePath);
}
const absolutePath = path.resolve(process.cwd(), relativePath);
// E. Verify that absolutePath is strictly inside 'src/'
const srcDir = path.resolve(process.cwd(), "src");
if (!absolutePath.startsWith(srcDir + path.sep)) {
return res.status(403).json({ error: "Access denied: file outside src directory" });
}Mechanics & Rationale:
- Windows
fileURLToPathBypass (A & B): Native Node.jsfileURLToPaththrows a fatal error on Windows (TypeError: Unique drive letter expected) when parsed with relative URIs likefile:///src/.... Dinou bypasses this by matchingisRelativeSrcand manually scraping thefile://protocol prefix to yield a clean path. - Path Case Normalization: Operating systems handle drive letters differently (e.g.
c:\vsC:\). Dinou runsnormalizePathCaseover paths to prevent compilation mismatches in Windows. - Anti-Directory-Traversal Guard (C): Verifies that the path does not start with root slashes, does not contain drive colons (
:), and does not include dot-dot sequences (..) to block path traversal attempts. - Sandbox Enforcement (D & E): Pre-pends the
src/directory and verifies that the resolved path points strictly inside the project's source directory, returning403 Forbiddenif it attempts to point to external folders.
In production, the server validates the function ID against the whitelist manifest generated during the build step:
allowedExports = serverFunctionsManifest[normalizedRelative.replace(/\\/g, "/")];
if (!allowedExports || !allowedExports.includes(exportName)) {
return res.status(400).json({ error: "Invalid export name" });
}3. Dynamic Import & Execution Pipeline
If the server function is verified, the server dynamically imports the target code module and isolates the target function (either default or named export) before executing it:
// Dynamically load target module
const mod = await importModule(absolutePath);
const fn = exportName === "default" ? mod.default : mod[exportName];
if (typeof fn !== "function") {
return res.status(400).json({ error: "Export is not a function" });
}
// Execute function inside requestStorage context
try {
result = await requestStorage.run(context, async () => await fn(...args));
} catch (err) {
if (err && err.$$type === "dinou-internal-redirect") {
if (!res.headersSent) {
// Scenario A: Headers not sent yet. Return a direct JSON redirect payload.
res.setHeader("Content-Type", "application/json");
res.setHeader("X-Dinou-Redirect", err.url);
return res.json({ redirect: err.url });
} else {
// Scenario B: Headers already sent (active stream).
// Append a custom redirect instruction to the stream and close the connection.
res.write(`D:{"type":"redirect","url":${JSON.stringify(err.url)}}\n`);
res.end();
return;
}
}
throw err; // bubble up other exceptions
}š”ļø 7. Bot Mitigation Shield
Dinou features an embedded request shield. Dynamic static generation (ISG/ISR) forks child compilation processes which consumes server resources. Bots probing for common exploits (e.g., searching for PHP pages or env files) can cause unnecessary CPU spikes.
To protect your server, server.js tests requests against a bot list:
const botGarbagePatterns = [
/.php$/i,
/.env$/i,
/.git/i,
/wp-admin/i,
/.sql$/i,
];
app.use((req, res, next) => {
const isGarbage = botGarbagePatterns.some((pattern) => pattern.test(req.path));
if (isGarbage) {
return res.status(404).send("Not Found"); // Deny instantly
}
next();
});š 8. Server Startup Sequence
At the very end of server.js, an asynchronous self-executing function (async () => { ... })() coordinates the HTTP socket bindings and background static compilations:
const http = require("http");
(async () => {
try {
const server = http.createServer(app);
// 1. Anti-Zombie Port Safety Check
server.on("error", (error) => {
if (error.code === "EADDRINUSE") {
console.error(`\nā FATAL ERROR: Port ${port} is already in use!`);
} else {
console.error("ā [Server Error]:", error);
}
process.exit(1);
});
// 2. Open HTTP Listener Sockets
await new Promise((resolve) => {
server.listen(port, () => {
console.log(`\nš Dinou Server is ready on http://localhost:${port}`);
resolve();
});
});
// 3. Environment Specific Tasks
if (!isDevelopment) {
generateStatic()
.then(() => {
isReady = true; // Mark as ready after SSG compilation succeeds
})
.catch((err) => {
isReady = true; // Fallback to dynamic execution
});
}
} catch (error) {
process.exit(1);
}
})();The Architectural Role of the isReady State
Dinou declares a global lifecycle boolean let isReady = isDevelopment;. Although it might seem unused at first glance, it serves two critical purposes:
- Preventing Disk File System Contention (ISG vs SSG): In production (
!isDevelopment), the server firesgenerateStatic()at startup to pre-build all static pages to disk. If an incoming client requests a dynamic route that triggers Incremental Static Generation (ISG/ISR) at the same time, Node.js would attempt to write, rename, and rewrite those same static files in parallel.
To prevent EBUSY/EPERM file locking conflicts on disk,isReadyacts as a gatekeeper. By remainingfalseduring the initial build, Dinou disables background revalidations (ISG) on matching wildcard GET routes until the initial compilation completes. - Testing Integration & Ready Signaling: Dinou exposes a diagnostic endpoint:
/__DINOU_STATUS_PLAYWRIGHT__. Automated testing runners (such as Playwright) need a reliable signal to know when the server has finished its initial compilation before launching E2E UI tests. The endpoint queries:isReady: isDevelopment ? isManifestReady() : isReady
It returns a status response containingisReady: trueonly when all static components and client manifests have been written successfully.
š ļø Common Customization Recipes
Here are a few common ways developers modify this file after ejecting:
You can install standard Express middleware (such as helmet or cors) and register them directly with app.use().
Add standard Express API endpoints (e.g., app.get("/api/health", ...)) before the wildcard RSC route handler.
Extend asset-extensions.js or add custom require overrides to compile alternative styles or templates on-the-fly.