Problem
A new Node compilation can reevaluate unchanged server modules before Hot Data Revalidation (HDR) refreshes route loader data. Requested: retain an evaluated build when compatible, while still committing the matching browser manifest and acknowledging HDR for the accepted compilation.
Published rsbuild-plugin-react-router 0.8.1 evaluates server builds when the Node compilation changes. evaluateServerBuilds calls loadBundle for each entry. Rsbuild 2.2.9 caches by Stats and entry, so a new compilation creates a fresh runner on first load.
Local implementation and contract
An unpublished source candidate adds:
pluginReactRouter({ unstableDevServerBuildCache: true })
It retains the accepted build only when all non-debug-map runtime outputs, membership and loading layout remain unchanged after complete successful emission. Changed unloaded JavaScript and same-name JSON/WASM changes take fresh evaluation. Unknown metadata, failures and superseded generations invalidate reuse. The option defaults off and applies only to classic development. Published 0.8.1 does not include it; the local package still carries that version.
Module state and initialization-time reads persist across same-output edits, including registered dependencies. Read changing data per request, encode it into output, or restart development to reset. Source-map-only changes need not refresh existing VM debugging state. This is an explicit state-lifetime policy.
Every accepted generation still receives a new manifest-pinned envelope and advances Node identity before notifications. Existing dependency snapshots and compiler-pairing checks remain. The cache reads compiler metadata, not asset contents; its observer still has measurable overhead.
Reproduction and source patches
Download the source-only reproduction and setup instructions. Run node public-repro-package.mjs ./router-cache-repro, then follow its README. The package contains three patches against published commit dc11d26292f014a62276eb7dddf9c16e7b5faa47: separate CSS-manifest prerequisites, the single-development-entry prerequisite, then the typed seven-file cache implementation. All three reproduce the candidate's 82 source files exactly. Its README gives source-build commands and pinned dependencies; fresh dependency installation remains untested, and the fixture has no transitive lockfile.
The fixture uses Node 24.19.0, Rsbuild 2.2.8, Rspack 2.2.6 and React Router 7.18.1. Omitted/enabled controls cover 20 stages each: singleton continuity, intentionally retained registered-input values, same-name emitted JSON changes with identical JavaScript, changed loaders/CSS/renderer, unloaded imports, output removal, post-emission failure and superseded evaluation. WebSocket receipts check committed manifest identity and manifest-before-HDR order. Results and package hashes accompany this tiny compiler/SSR test; it has no browser or performance claim.
Remaining boundary
Rsbuild #8496 contains the executed public reproduction of the broader consumed-output request: preserve eager modules when only an unloaded chunk changes, while ensuring future imports are fresh. That requires runner-level support; this Router candidate rejects that case.
A separate application diagnostic recorded the entry actually passed to the VM changing from 65,400,789 to 65,400,850 bytes on a component edit. Restoration restored those bytes. Neither unchanged-output policy can skip that edit at the current bundle boundary. This diagnostic is not a timing sample and lacks a final process record.
The local application lane on Rsbuild 2.2.9 / Rspack 2.2.7 reused two CSS generations and evaluated two component generations. Two clean samples establish no speedup. All 15 original application development tests passed, including lazy navigation, JS/CSS HMR, streamed SSR, reload and checkout; exact source/config/package restoration was independently checked. This uses local patches, not released-package behavior. Known fixture 404s and a nonce-only hydration warning remain. Production/RSC, multi-entry/client and broader concurrency coverage remain separate.
Problem
A new Node compilation can reevaluate unchanged server modules before Hot Data Revalidation (HDR) refreshes route loader data. Requested: retain an evaluated build when compatible, while still committing the matching browser manifest and acknowledging HDR for the accepted compilation.
Published rsbuild-plugin-react-router 0.8.1 evaluates server builds when the Node compilation changes.
evaluateServerBuildscallsloadBundlefor each entry. Rsbuild 2.2.9 caches by Stats and entry, so a new compilation creates a fresh runner on first load.Local implementation and contract
An unpublished source candidate adds:
It retains the accepted build only when all non-debug-map runtime outputs, membership and loading layout remain unchanged after complete successful emission. Changed unloaded JavaScript and same-name JSON/WASM changes take fresh evaluation. Unknown metadata, failures and superseded generations invalidate reuse. The option defaults off and applies only to classic development. Published 0.8.1 does not include it; the local package still carries that version.
Module state and initialization-time reads persist across same-output edits, including registered dependencies. Read changing data per request, encode it into output, or restart development to reset. Source-map-only changes need not refresh existing VM debugging state. This is an explicit state-lifetime policy.
Every accepted generation still receives a new manifest-pinned envelope and advances Node identity before notifications. Existing dependency snapshots and compiler-pairing checks remain. The cache reads compiler metadata, not asset contents; its observer still has measurable overhead.
Reproduction and source patches
Download the source-only reproduction and setup instructions. Run
node public-repro-package.mjs ./router-cache-repro, then follow its README. The package contains three patches against published commitdc11d26292f014a62276eb7dddf9c16e7b5faa47: separate CSS-manifest prerequisites, the single-development-entry prerequisite, then the typed seven-file cache implementation. All three reproduce the candidate's 82 source files exactly. Its README gives source-build commands and pinned dependencies; fresh dependency installation remains untested, and the fixture has no transitive lockfile.The fixture uses Node 24.19.0, Rsbuild 2.2.8, Rspack 2.2.6 and React Router 7.18.1. Omitted/enabled controls cover 20 stages each: singleton continuity, intentionally retained registered-input values, same-name emitted JSON changes with identical JavaScript, changed loaders/CSS/renderer, unloaded imports, output removal, post-emission failure and superseded evaluation. WebSocket receipts check committed manifest identity and manifest-before-HDR order. Results and package hashes accompany this tiny compiler/SSR test; it has no browser or performance claim.
Remaining boundary
Rsbuild #8496 contains the executed public reproduction of the broader consumed-output request: preserve eager modules when only an unloaded chunk changes, while ensuring future imports are fresh. That requires runner-level support; this Router candidate rejects that case.
A separate application diagnostic recorded the entry actually passed to the VM changing from 65,400,789 to 65,400,850 bytes on a component edit. Restoration restored those bytes. Neither unchanged-output policy can skip that edit at the current bundle boundary. This diagnostic is not a timing sample and lacks a final process record.
The local application lane on Rsbuild 2.2.9 / Rspack 2.2.7 reused two CSS generations and evaluated two component generations. Two clean samples establish no speedup. All 15 original application development tests passed, including lazy navigation, JS/CSS HMR, streamed SSR, reload and checkout; exact source/config/package restoration was independently checked. This uses local patches, not released-package behavior. Known fixture 404s and a nonce-only hydration warning remain. Production/RSC, multi-entry/client and broader concurrency coverage remain separate.