docs/pro/react-server-components/rspack-compatibility.md
Status: Experimental — the generator scaffolds the native Rspack plugin and the proven runtime path, but the end-to-end gate is not yet wired into this repo's CI. See issue #3488.
This page documents the compatibility status of Rspack with React on Rails Pro's React Server Components (RSC) implementation.
React on Rails Pro's RSC implementation uses a three-bundle architecture (client, server, RSC).
The generator supports Rspack — when assets_bundler: rspack is detected in shakapacker.yml, all RSC config files are created in config/rspack/ instead of config/webpack/, and the server/client configs are scaffolded with the native RSCRspackPlugin instead of RSCWebpackPlugin.
The RSC implementation depends on the react-on-rails-rsc npm package, which provides bundler-specific manifest plugins plus a shared loader:
react-on-rails-rsc/WebpackPlugin) — generates client/server component manifest files under webpack.react-on-rails-rsc/RspackPlugin) — the rspack-native equivalent (RSCRspackPlugin). It emits the same manifest JSON schema using only standard rspack public APIs, so the RSC runtime resolves client references identically. Exported by stable react-on-rails-rsc 19.2.1 and later on the 19.2.x package line.react-on-rails-rsc/WebpackLoader) — transforms 'use client' files into client reference proxies in the RSC bundle. Works under both webpack and rspack.Generated RSC apps on React on Rails Pro 17 use React 19.2.x: react@~19.2.7
and react-dom@~19.2.7. React 19.0.x is no longer a supported Pro RSC runtime
line in v17 because the generator, peer metadata, and node-renderer startup check
now target the coordinated React 19.2.7 / react-on-rails-rsc 19.2.1 package
line.
The React on Rails Pro 17 generator pins stable [email protected]
for both webpack and rspack projects. Keep React, React DOM, and
react-on-rails-rsc upgraded as a coordinated set.
| Component | Rspack Compatible | Notes |
|---|---|---|
RSC bundle config (rscWebpackConfig.js) | Yes | Does not use WebpackPlugin; only uses loader + resolve settings |
WebpackLoader (react-on-rails-rsc/WebpackLoader) | Yes | Standard loader interface (this.resourcePath, source transform) |
conditionNames: ['react-server', '...'] | Yes | Rspack supports conditional exports resolution |
| React server file aliases | Yes | Rspack supports exact aliases that keep React's RSC dispatcher shared |
resolve.alias (react-dom/server: false) | Yes | Rspack supports alias to false |
LimitChunkCountPlugin | Yes | Generated configs use bundler-agnostic bundler.optimize.LimitChunkCountPlugin |
| Loader chain (SWC + Babel) | Yes | Generated config handles both function and Array rule.use styles |
Manifest plugin (RSCRspackPlugin) | Yes | Native rspack plugin; emits the same manifest schema (see below) |
WebpackPlugin (react-on-rails-rsc/WebpackPlugin) | Not used on rspack | Replaced by RSCRspackPlugin under rspack; remains the webpack-only plugin |
Three-bundle build (RSC_BUNDLE_ONLY, SERVER_BUNDLE_ONLY) | Yes | Environment variable routing is bundler-agnostic |
RSCRspackPluginThe manifest plugin is the critical compatibility question. It generates
react-client-manifest.json and react-server-client-manifest.json, which map client
component file paths to their chunk IDs and bundle filenames. Without these manifests, the
RSC runtime cannot resolve 'use client' component references during streaming.
Under webpack, this is RSCWebpackPlugin, which wraps React's
react-server-dom-webpack/plugin and depends on webpack-internal APIs
(webpack/lib/dependencies/*, webpack.AsyncDependenciesBlock,
compilation.chunkGraph, the processAssets/thisCompilation/make hooks, etc.).
Under rspack, the generator instead scaffolds the native RSCRspackPlugin
(react-on-rails-rsc/RspackPlugin). Rather than rely on Rspack's webpack-compatibility
layer for those internal APIs, the native plugin emits the same manifest JSON schema
using only standard rspack public APIs. It discovers 'use client' modules with a tagging
loader, injects them as named async chunks, and walks compilation.chunkGroups at
processAssets. Because the output schema is identical, the RSC runtime
(buildServerRenderer / buildClientRenderer) works unchanged regardless of bundler. The
two plugins share the same { isServer, clientReferences } options.
[!NOTE] Why native instead of the webpack plugin under Rspack's compat layer? A controlled A/B on a real app showed the webpack-plugin path producing valid-looking manifests that still failed ~7/11 RSC routes at runtime under Rspack, while the native
RSCRspackPluginrendered and hydrated every route. The native plugin is therefore the supported Rspack path. The remaining work to drop the "experimental" label — wiring the demo route-hydration gate into this repo's CI — is tracked in issue #3488 (superseding the abandoned manifest-helper approach in PR #3385).
The RSC bundle config (rscWebpackConfig.js) calls serverWebpackConfig(true),
which skips adding the manifest plugin (RSCRspackPlugin under rspack,
RSCWebpackPlugin under webpack). The RSC bundle only uses:
'use client' files into client reference proxiesconditionNames: ['react-server', '...'] to resolve React's server entry pointsreact-dom/server from the RSC bundleThe manifest plugin is only added to the server and client bundles.
To test RSC with Rspack in your project:
assets_bundler: rspack is set in config/shakapacker.ymlrails generate react_on_rails:rscconfig/rspack/rsc-bundle.js in the outputreact-client-manifest.json and react-server-client-manifest.json (from RSCRspackPlugin)React on Rails does not use Rspack's experimental native RSC system:
As of Rspack v2, Rspack ships its own built-in RSC
support (driven by builtin:swc-loader and
rspackExperiments.reactServerComponents). React on Rails Pro does not use that
experimental path. Its RSC integration is built on the react-on-rails-rsc package:
manifest generation uses the native RSCRspackPlugin (standard rspack public APIs,
not Rspack's webpack-compatibility layer), while the RSC bundle still uses the
react-server-dom-webpack loader and runtime.
The RSC bundle still uses the react-server-dom-webpack loader: Only the
manifest plugin is bundler-native. The RSC bundle transforms 'use client' files with
react-on-rails-rsc/WebpackLoader (which wraps React's react-server-dom-webpack
node loader) under both bundlers. This loader is compatible with rspack.
No official React Rspack support: The React team has not officially tested or
endorsed the react-server-dom-webpack runtime with Rspack. The native
RSCRspackPlugin is maintained by ShakaCode in react-on-rails-rsc.