Skip to content

feat: add Remix source API compatibility facades - #160

Closed
ScriptedAlchemy wants to merge 3 commits into
mainfrom
feat/remix-api-compat
Closed

ScriptedAlchemy wants to merge 3 commits into
mainfrom
feat/remix-api-compat

Conversation

@ScriptedAlchemy

Copy link
Copy Markdown
Collaborator

Summary

  • add opt-in remixCompat exact aliases for @remix-run/react, @remix-run/node, and react-router-dom6
  • publish typed ESM/CJS compat/remix-react and compat/remix-node facades backed by the application single React Router runtime
  • provide json as a real JSON Response, and map defer to React Router data so RR single-fetch owns promise streaming
  • preserve useLoaderData<typeof loader>/useActionData<typeof action> inference for the compatibility return types
  • map RemixBrowser to HydratedRouter and RemixServer to ServerRouter, with an explicit warning that abortDelay must be implemented by aborting the entry-server render stream

Supported boundary

This is source-level compatibility for supported root exports, not a legacy Remix runtime. It intentionally does not support package deep imports, private __remixContext/deferred protocol APIs, installGlobals, legacy upload APIs, Remix config/build conventions, RSC mode, or simultaneous router runtimes. TypeScript consumers use the documented exact paths entries because bundler aliases do not affect tsc.

Verification

  • pnpm build
  • pnpm typecheck
  • pnpm exec rstest run tests/index.test.ts tests/remix-compat.test.ts (54 passed)
  • pnpm test:package-interop
  • pnpm exec playwright test --config tests/react-router-framework/integration/playwright.config.ts tests/react-router-framework/integration/remix-compat-test.ts --workers=1 --retries=0 --reporter=line (real build, SSR, RemixServer/RemixBrowser, hydration, JSON action, document/navigation deferred streaming, resolved/rejected promises, status/headers)
  • npm pack --dry-run --json (ESM/CJS/types compatibility artifacts included)
  • pnpm format:check

The complete pnpm test run reaches 841 passing tests but reproduces 13 pre-existing tests/route-imports.test.ts resolver failures plus a benchmark fixture intentional missing dist/index.js error; these reproduce without this change and are unrelated to the compatibility surface.

@pkg-pr-new

pkg-pr-new Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

pnpm add https://pkg.pr.new/rsbuild-plugin-react-router@efce6cf

commit: efce6cf

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Benchmark results

Case Base Head Delta
build-256-ssr 2111.2 ms 2173.5 ms +3.0%
dev-48-ssr 953.7 ms 949.0 ms -0.5%

@codspeed

codspeed Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Merging this PR will not alter performance

1 warning

⚠️ 1 benchmark is dominated by system calls

System calls cannot be simulated consistently and are left out of the measure. The reported value understates the real cost. Switch to the Walltime instrument to measure them.

Learn more about system calls

See affected benchmarks

✅ 1 untouched benchmark
⏩ 2 skipped benchmarks1


Comparing feat/remix-api-compat (efce6cf) with main (a09dd6a)

Open in CodSpeed

Footnotes

  1. 2 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

@ScriptedAlchemy

Copy link
Copy Markdown
Collaborator Author

Follow-up fix pushed in f4db610: SerializeFrom now unwraps mixed response unions distributively, JSON responses model JSON serialization (Date, toJSON, omitted/optional undefined, array nulls), while defer/plain values retain React Router turbo-stream serialization. Compat mode now aliases both react-router-dom and react-router-dom6 to the app RR runtime. The documented TypeScript path setup now uses runtime-safe local re-export modules instead of .d.ts targets, and the framework integration test builds with those actual tsconfig mappings.

@ScriptedAlchemy

Copy link
Copy Markdown
Collaborator Author

Closing: the Remix 2 / React Router 6 support for TTArk will live as a TTArk-owned package in its monorepo instead of in this plugin. Keeping the branch for reference.

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