Skip to content

Derive RSC recovery version from client compatibility graph#1

Closed
agcty wants to merge 1 commit into
codex/rsc-reload-document-recoveryfrom
codex/rsc-compatibility-version
Closed

Derive RSC recovery version from client compatibility graph#1
agcty wants to merge 1 commit into
codex/rsc-reload-document-recoveryfrom
codex/rsc-compatibility-version

Conversation

@agcty
Copy link
Copy Markdown
Owner

@agcty agcty commented May 11, 2026

Stacked on remix-run#15032's conservative versioned RSC recovery baseline.

This follow-up replaces the production random RSC recovery token with a deterministic compatibility hash derived from @vitejs/plugin-rsc's compiler-owned reference metadata instead of route/source scanning. The hash includes:

  • core React/RSC/React Router/Vite runtime package versions
  • Vite base path, because it affects client asset resolution
  • client reference identity plus rendered exports from plugin-rsc's clientReferenceMetaMap
  • server reference identity plus export names from plugin-rsc's serverReferenceMetaMap
  • a build salt only when the RSC bundle uses plugin-rsc's generated server-action encryption key, because that key is not currently exposed through the compiler API

The goal is Jacob-style compatibility recovery: server-only RSC changes and client implementation-only changes can keep the same recovery version, while client/server reference ABI changes still force document recovery. Encrypted server-action builds remain conservative until plugin-rsc exposes stable encryption-key identity or downstream apps provide one through a first-class API.

Validation:

  • pnpm test -- packages/react-router-dev/tests/rsc-compatibility-version-test.ts packages/react-router/tests/rsc/browser-test.ts packages/react-router/tests/rsc/server-test.ts --runInBand
  • pnpm --filter @react-router/dev typecheck
  • pnpm --filter @react-router/dev build
  • pnpm exec eslint packages/react-router-dev/vite/rsc/compatibility-version.ts packages/react-router-dev/vite/rsc/plugin.ts packages/react-router-dev/tests/rsc-compatibility-version-test.ts
  • pnpm changes:validate
  • git diff --check
  • pnpm --filter @react-router/fs-routes build, then pnpm --filter integration-rsc-vite-framework build and verified the emitted server bundle contains a concrete compatibility version with no placeholder remaining

@agcty agcty force-pushed the codex/rsc-compatibility-version branch from 8ce7eee to 8daded1 Compare May 11, 2026 09:52
@agcty
Copy link
Copy Markdown
Owner Author

agcty commented May 11, 2026

Closing this in favor of the lower-level plugin-rsc primitive here:
vitejs/vite-plugin-react#1223

This PR was useful as the exploration path, but after working through the edge cases it became clear that React Router should not reconstruct RSC compatibility from framework-side state. @vitejs/plugin-rsc owns the authoritative build/RSC data: client references, rendered exports, server references, final assets manifest, output bundles, and server-action encryption identity.

The better shape is:

  • plugin-rsc exposes a compiler/build compatibility manifest
  • React Router consumes that manifest and composes it with any React Router-specific deployment or routing state
  • React Router owns the recovery behavior

So the next React Router PR should be an integration with virtual:vite-rsc/compatibility-manifest, not this framework-side derivation.

@agcty agcty closed this May 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant