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.
The cache applies only when all runtime output is unchanged. If a component edit changes an already evaluated server entry, it must reevaluate; this proposal does not supply finer-grained server HMR or skip that work. The fixture measures correctness, including changed loader/CSS/renderer fallbacks, and does not demonstrate an application performance improvement.
Production/RSC, multiple-entry/client and broader concurrent-runtime behavior remain outside the public fixture's coverage.
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.
The cache applies only when all runtime output is unchanged. If a component edit changes an already evaluated server entry, it must reevaluate; this proposal does not supply finer-grained server HMR or skip that work. The fixture measures correctness, including changed loader/CSS/renderer fallbacks, and does not demonstrate an application performance improvement.
Production/RSC, multiple-entry/client and broader concurrent-runtime behavior remain outside the public fixture's coverage.