Skip to content

Update react-router monorepo to v8 - #956

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/major-react-router-monorepo
Open

renovate[bot] wants to merge 1 commit into
mainfrom
renovate/major-react-router-monorepo

Conversation

@renovate

@renovate renovate Bot commented Jun 23, 2026 •

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Confidence
@react-router/dev (source) ^7.12.0 → ^8.0.0 age confidence
@react-router/express (source) ^7.12.0 → ^8.0.0 age confidence
@react-router/node (source) ^7.12.0 → ^8.0.0 age confidence
@react-router/serve (source) ^7.12.0 → ^8.0.0 age confidence
react-router (source) ^7.12.0 → ^8.0.0 age confidence

Release Notes

remix-run/react-router (@​react-router/dev)

v8.4.0

Compare Source

Patch Changes
  • Fix action submissions behind an HTTPS reverse proxy in react-router dev and vite preview by using X-Forwarded-Proto when constructing request.url (#​15466)
    • No React Router configuration is required
    • The URL host continues to come from Host, not X-Forwarded-Host
    • Configure reverse proxies to overwrite client-supplied X-Forwarded-Proto headers
    • Do not expose dev or preview servers publicly
  • Pass development conditions as CLI flags when relaunching the dev process (#​15435)
  • Fix stack trace locations for split route modules when source maps are enabled in the reactRouter Vite plugin (#​15440)
  • Updated dependencies:

v8.3.1

Compare Source

Patch Changes

v8.3.0

Compare Source

Minor Changes
  • Restart react-router dev with --conditions=development when not already configured (#​15291)
Patch Changes
Unstable Changes

⚠️ Unstable features are not recommended for production use

  • Add unstable_rsc/client-version client build version virtual module (#​15318)

  • Support the subResourceIntegrity config option in RSC Framework Mode (#​15321)

Migration guide

No changes are required when using the default RSC SSR entry. If you maintain a custom app/entry.ssr.tsx, import the new virtual module and pass its hashes to React's importMap render option:

+import subResourceIntegrity from "virtual:react-router/unstable_rsc/subresource-integrity";

return renderToReadableStream(<RSCStaticRouter getPayload={getPayload} />, {
  ...options,
  bootstrapScriptContent,
  formState,
+ importMap: subResourceIntegrity
+   ? { integrity: subResourceIntegrity }
+   : undefined,
  signal: request.signal,
});

v8.2.0

Compare Source

Minor Changes
  • Add a Web Streams default server entry for non-Node Framework mode apps (#​15290)
    • Apps using @react-router/node, @react-router/express, or @react-router/serve continue to use the renderToPipeableStream default server entry
    • Apps without those Node server adapter dependencies use a renderToReadableStream default server entry
    • Non-Node apps with their own entry.server.tsx may be able to remove it in favor of the default if it is not doing anything custom
  • Detect nub as a supported package manager when installing framework dependencies (#​15276)
Patch Changes
  • Detect user rolldownOptions config in Vite 8+ (#​15278)
Unstable Changes

⚠️ Unstable features are not recommended for production use

v8.1.0

Compare Source

Patch Changes
  • Fix a regression with the new prerendering plugin where the react-router.config.ts buildEnd hook would run before prerendering was completed (#​15211)
  • Fixed react-router typegen crashes under the Bun runtime when Babel default imports are already unwrapped (#​15214)
  • Replace the deprecated envFile:false Vite config with envDir:false to eliminate a deprecation warning when using vite@​8.1.0+ (#​15230)
  • Only add the "node" Vite server condition for Framework mode apps that declare a Node server adapter dependency (#​15242)
    • This prevents non-Node SSR runtimes from resolving Node-specific package exports by default
  • Updated dependencies:

v8.0.1

Compare Source

Patch Changes

v8.0.0

Compare Source

Major Changes
  • Remove @react-router/dev/vite/cloudflare dev proxy export; use @cloudflare/vite-plugin instead (#​15077)
    • Drops support for wrangler@3 as a peer dependency of @react-router/dev
  • Remove the future.v8_trailingSlashAwareDataRequests flag (#​15100)
    • Trailing slash-aware data request URLs are now the default behavior.
  • Remove future.v8_passThroughRequests flag - the raw incoming request is now always passed through to loader/action. (#​15079)
  • Move future.v8_splitRouteModules to a top-level splitRouteModules config option and change the default behavior to true (#​15086)
    • Set splitRouteModules: false to keep route modules in a single chunk
    • Set splitRouteModules: "enforce" to require all routes to be splittable
  • Update minimum Node version to 22.22.0 (#​14928)
  • Require Vite 7+ and make the Vite Environment API build path mandatory (#​15077)
  • Removed the future.v8_viteEnvironmentApi flag because the Vite Environment API is always enabled (#​15077)
  • Removed the future.unstable_previewServerPrerendering flag and make prerendering with the Vite Environment API the default. (#​15077)
Minor Changes
  • Bump dependencies (#​15080)
    • Bumped @babel/core from ^7.27.7 to ^7.29.7
    • Bumped @babel/generator from ^7.27.5 to ^7.29.7
    • Bumped @babel/parser from ^7.27.7 to ^7.29.7
    • Bumped @babel/plugin-syntax-jsx from ^7.27.1 to ^7.29.7
    • Bumped @babel/preset-typescript from ^7.27.1 to ^7.29.7
    • Bumped @babel/traverse from ^7.27.7 to ^7.29.7
    • Bumped @babel/types from ^7.27.7 to ^7.29.7
    • Bumped dedent from ^1.5.3 to ^1.7.2
    • Bumped jsesc from 3.0.2 to 3.1.0
    • Bumped lodash from ^4.17.21 to ^4.18.1
    • Bumped prettier from ^3.6.2 to ^3.8.3
    • Bumped @remix-run/node-fetch-server from ^0.13.0 to ^0.13.3
    • Bumped react-refresh from ^0.14.0 to ^0.18.0
    • Bumped semver from ^7.3.7 to ^7.8.1
    • Bumped tinyglobby from ^0.2.14 to ^0.2.16
    • Bumped valibot from ^1.2.0 to ^1.4.1
  • Replace cookie and set-cookie-parser with cookie-es (#​15109)
  • Removed the vite-node dependency in favor of Vite's native module runner APIs (#​15104)
Patch Changes
  • Bump dependencies (#​15080)
    • Bumped @babel/core from ^7.29.0 to ^7.29.7
    • Bumped @babel/generator from ^7.29.1 to ^7.29.7
    • Bumped @babel/parser from ^7.29.3 to ^7.29.7
    • Bumped @babel/plugin-syntax-jsx from ^7.28.6 to ^7.29.7
    • Bumped @babel/preset-typescript from ^7.28.5 to ^7.29.7
    • Bumped @babel/traverse from ^7.29.0 to ^7.29.7
    • Bumped @babel/types from ^7.29.0 to ^7.29.7
    • Bumped babel-dead-code-elimination from ^1.0.6 to ^1.0.12
    • Bumped chokidar from ^4.0.0 to ^5.0.0
    • Bumped es-module-lexer from ^1.3.1 to ^2.1.0
    • Bumped exit-hook from 2.2.1 to 5.1.0
    • Bumped isbot from ^5.1.11 to ^5.1.40
    • Bumped p-map from ^7.0.3 to ^7.0.4
    • Bumped pathe from ^1.1.2 to ^2.0.3
    • Bumped pkg-types from ^2.3.0 to ^2.3.1
    • Bumped react-refresh from ^0.14.0 to ^0.18.0
    • Bumped semver from ^7.8.0 to ^7.8.1
    • Bumped tinyglobby from ^0.2.14 to ^0.2.16
    • Bumped valibot from ^1.4.0 to ^1.4.1
  • Fix Windows libuv assertion (!(handle->flags & UV_HANDLE_CLOSING) in src/win/async.c) during prerendering by using node:http instead of fetch for internal prerender requests against the Vite preview server (#​15077)
  • Updated dependencies:
remix-run/react-router (@​react-router/express)

v8.4.0

Compare Source

Patch Changes

v8.3.1

Compare Source

Patch Changes

v8.3.0

Compare Source

Patch Changes

v8.2.0

Compare Source

Patch Changes

v8.1.0

Compare Source

Patch Changes

v8.0.1

Compare Source

Patch Changes

v8.0.0

Compare Source

Major Changes
  • Bump dependencies (#​15106)
    • Bumped express from ^4.19.2 to ^4.22.2
    • Bumped the express peer dependency from ^4.17.1 || ^5 to ^4.22.2 || ^5
    • Bumped @types/express from ^4.17.9 to ^4.17.25
  • Update minimum Node version to 22.22.0 (#​14928)
Patch Changes
remix-run/react-router (@​react-router/node)

v8.4.0

Compare Source

Patch Changes
  • Fix a memory leak in writeReadableStreamToWritable and writeAsyncIterableToWritable that retained memory for the lifetime of a long-running stream (#​15500)
    • Preserve error handling when a producer closes the destination while reading the next chunk
  • Updated dependencies:

v8.3.1

Compare Source

Patch Changes
  • Bump @remix-run/node-fetch-server dependency (#​15447)
  • fix: Prevent client disconnects during streaming from crashing the Node process (#​15324)
  • Updated dependencies:

v8.3.0

Compare Source

Patch Changes

v8.2.0

Compare Source

Patch Changes

v8.1.0

Compare Source

Patch Changes

v8.0.1

Compare Source

Patch Changes

v8.0.0

Compare Source

Major Changes
  • Switch from @mjackson/node-fetch-server to @remix-run/node-fetch-server now that we can directly use ESM-only packages (#​14930)
  • Update minimum Node version to 22.22.0 (#​14928)
Patch Changes
remix-run/react-router (@​react-router/serve)

v8.4.0

Compare Source

Patch Changes

v8.3.1

Compare Source

Patch Changes
  • Bump @remix-run/node-fetch-server dependency (#​15447)
  • Serve /.well-known/* files from the client build directory. Express 5's static middleware ignores every dot-segment path by default, so RFC 8615 well-known URIs — ACME challenges, Android's assetlinks.json, Apple's apple-app-site-association — fell through to the request handler and came back as app-rendered HTML instead of the static file. Other dotfiles remain hidden. (#​15340)
  • Updated dependencies:

v8.3.0

Compare Source

Patch Changes

v8.2.0

Compare Source

Patch Changes

v8.1.0

Compare Source

Patch Changes

v8.0.1

Compare Source

Patch Changes

v8.0.0

Compare Source

Major Changes
  • Switch from @mjackson/node-fetch-server to @remix-run/node-fetch-server now that we can directly use ESM-only packages (#​14930)
  • Update minimum Node version to 22.22.0 (#​14928)
Minor Changes
  • Bump express from 4.21.2 to 5.2.1
Patch Changes
remix-run/react-router (react-router)

v8.4.0

Compare Source

Minor Changes
  • Deprecate the createStaticRouter({ branches }) option (#​15297)
    • createStaticRouter now caches route branches internally, ignores branches, and logs a deprecation warning when the option is provided
    • The deprecated EntryContext.branches property remains available for compatibility but is always an empty array
Patch Changes
  • Prevent stale route discovery during manifest version-mismatch recovery (#​15489)
    • Keep concurrent manifest responses pending while a document reload is in progress
    • Report a discovery error when a previous reload failed to resolve a version mismatch instead of loading a stale route or reloading repeatedly
    • Fail pending requests if a document reload does not complete within five seconds or the document is restored from the back-forward cache, allowing subsequent requests to recover
  • Preserve lazy route module import errors during SPA navigations instead of replacing them with a missing dataStrategy result error (#​15464)
  • Switch to more granular internal router contexts to avoid unnecessary route component re-renders when unrelated data router state changes (#​15376)
    • ⚠️ This contains some breaking changes to exported UNSAFE_ contexts, so please review carefully if you are using those unsafe exports
  • Correctly escape streamed RSC redirect locations in meta tag attributes (#​15491)
  • Avoid unintended document.startViewTransition calls during initial hydration and router.revalidate() calls (#​15484)
  • Fix SingleFetchNoResultError thrown when a fetcher revalidates against a splat route during lazy route discovery (#​15395)
    • Track discovery per fetcher load so revalidation waits for the current load's discovery, even when the fetcher key is reused, while still restarting interrupted loaders after discovery completes
  • Preserve the underlying decode failure as the cause of the Unable to decode turbo-stream response error (#​15450)
Unstable Changes

⚠️ Unstable features are not recommended for production use

  • Add a Data Mode future.unstable_routePatternMatching flag for more efficient route matching powered by @remix-run/route-pattern (#​15298)
    • Add an unstable_validateParams route field to reject invalid parameter values and continue matching
  • Document access control requirements for RSC Server Functions (#​15490)
    • Treat every Server Function as a public endpoint that must perform all of its own access control checks
    • Recommend route actions when access control should be provided by route middleware

v8.3.1

Compare Source

Patch Changes
  • Fix Expected fetcher: <key> error thrown on navigation when a fetcher is aborted during its post-action revalidation (#​15365)
  • Fix lazy route discovery caching a path as discovered when the triggering navigation was aborted after the manifest response settled but before the route tree was patched, which permanently (for the session) shadowed the real route behind a catch-all or produced 404s on every subsequent visit (#​15399)
  • Improve route matching performance for long paths (#​15417)
  • Improve validation of action request origins (#​15419)
  • Fix <ScrollRestoration> leaving history.scrollRestoration set to "auto" after a bfcache restore, which let the browser restore scroll on subsequent history traversals before the destination route had rendered (#​15397)
  • Properly respect the relative option in useSubmit/fetcher.submit when resolivng the action path (#​15400)
  • Add additional URL validation on client side navigations/redirects (#​15445)

v8.3.0

Compare Source

Patch Changes
  • Encode path params in href/generatePath per RFC 3986 path-segment rules instead of encodeURIComponent (#​15310)
    • Characters that are valid literally in a path segment ($ & + , ; = : @ — RFC 3986 pchar) are no longer percent-encoded, so values like a semver build 1.0.0+1 interpolate unchanged instead of becoming 1.0.0%2B1
    • Structural/unsafe characters (/ ? # %, whitespace, non-ASCII) are still escaped exactly as before
  • Use crypto.randomUUID() for createMemorySessionStorage session ids (#​15302)
    • createMemorySessionStorage is only intended for local development and testing - sessions are lost when the server restarts
  • Fix NavLink not applying its pending state when to has a trailing slash (#​15300)
  • Preserve RSC route component metadata so routes with a clientLoader can skip unnecessary server requests once their components have rendered while still fetching missing server-rendered elements (#​15323)
  • Harden RSC CSRF code paths (#​15311)
  • Fix server crash (TypeError: Invalid state: Unable to enqueue) when a request is aborted while the RSC HTML stream has a pending flush (#​15286)
    • Handle cancellation of the injectRSCPayload readable side, clear the pending flush, and cancel the underlying RSC payload stream
Unstable Changes

⚠️ Unstable features are not recommended for production use

  • Detect stale RSC clients during lazy route discovery and reload the destination document (#​15318)
Migration

Apps using the default RSC Framework entry do not need to make any changes. Apps with a custom entry.rsc.tsx should import the generated client version and pass it to unstable_matchRSCServerRequest:

import clientVersion from "virtual:react-router/unstable_rsc/client-version";

return unstable_matchRSCServerRequest({
  // ...
  clientVersion,
});
  • Add CSP nonce support to RSC document rendering (#​15320)

    • Add nonce options to unstable_routeRSCServerRequest and unstable_RSCStaticRouter
    • Forward the nonce to the HTML renderer and apply it to injected RSC payload scripts and nonce-aware framework components

    To adopt nonce-based CSP, update your entry.ssr.tsx (run react-router reveal entry.ssr first in RSC Framework Mode) to generate a fresh nonce for each request. Pass it to routeRSCServerRequest, spread the renderHTML options into React's HTML renderer, pass options.nonce to RSCStaticRouter, and use the same nonce in the Content-Security-Policy response header:

    const nonce = crypto.randomUUID();
    const response = await routeRSCServerRequest({
      request,
      serverResponse,
      createFromReadableStream,
      nonce,
      async renderHTML(getPayload, options) {
        const payload = getPayload();
        return renderHTMLToReadableStream(
          <RSCStaticRouter getPayload={getPayload} nonce={options.nonce} />,
          {
            ...options,
            bootstrapScriptContent,
            formState: await payload.formState,
            signal: request.signal,
          },
        );
      },
    });
    response.headers.set(
      "Content-Security-Policy",
      `script-src 'self' 'nonce-${nonce}'`,
    );

v8.2.0

Compare Source

Patch Changes
  • Fix href() to properly stringify and URL-encode param values, matching generatePath() (#​15277)
    • splat params preserve path separators while encoding each segment individually
  • Fix dynamic param extraction for routes with optional static segments (#​15200)
    • When a route path contains optional static segments (e.g. /school?/user/:id), the internal regex's incorrectly shifted parameter indices resulting in incorrect parameter extraction
    • Consecutive optional static segments (e.g. /one?/two?) were only partially handled
  • Preserve navigation blocker state through a revalidation (#​15246)
  • Fix route ranking for dynamic parameters with static extension suffixes (#​15273)
    • These were not being detected as dynamic param segments and instead got incorrectly scored higher as a static segment
    • This meant they could potentially tie truly static routes like /sitemap.xml and outrank them based on definition order
    • These are now correctly identified as dynamic parameter segments and scored correctly
  • Use ReactFormState types instead of unknown (#​15263)

v8.1.0

Compare Source

Minor Changes
  • Return route metadata from server request, client navigation, and client fetcher instrumentations (#​15235)
    • Adds result metadata after instrumented calls complete, including the URL, matched route pattern, and params
    • Adds known HTTP status codes to server request handler instrumentation results

v8.0.1

Compare Source

Patch Changes
  • Remove the obsolete AppLoadContext type export accidentally left over from v7 now that middleware is always enabled and server request context is provided through RouterContextProvider. (#​15207)

v8.0.0

Compare Source

Major Changes
  • Remove the future.v8_trailingSlashAwareDataRequests flag (#​15100)
    • Trailing slash-aware data request URLs are now the default behavior.
  • Update tsconfig.json target/lib from ES2020 -> ES2022 (591853e)
  • Switch the published packages in packages/ to ESM-only. (#​14895) (59ebcf1)
  • Remove deprecated data parameter in favor of loaderData for meta APIs (to align with Route.ComponentProps) (#​14931)
    • Route.MetaArgs, Route.MetaMatch, MetaArgs, MetaMatch, Route.ComponentProps.matches, UIMatch
  • Remove future.v8_passThroughRequests flag - the raw incoming request is now always passed through to loader/action. Use url for the normalized URL without React Router-specific implementation details (.data suffixes, index/_routes search params). (#​15079)
  • Remove internal hasErrorBoundary field added to router.routes when using a data router (#​15074)
    • This should not impact user-facing code since this was an internal prop and was computed based on the presence of ErrorBoundary or errorElement on your route
    • hasErrorBoundary is no longer accepted on RouteObject (IndexRouteObject/NonIndexRouteObject), DataRouteObject, <Route> JSX props, or as a key in lazy route definitions.
    • The MapRoutePropertiesFunction signature no longer requires returning hasErrorBoundary; the router infers it directly.
  • Remove react-router-dom package (#​15076)
    • In v7 everything DOM-specific was collapsed into react-router/dom
      • react-router-dom was kept around as a convenience so existing v6 app imports would still work
    • For v8, you will need to swap react-router-dom imports:
      • RouterProvider/HydratedRouter should be imported from react-router/dom
      • Everything else should be imported from react-router
  • Remove future.v8_middleware flag — middleware is always enabled in v8 (#​15078)
    • The future.v8_middleware flag has been removed; middleware is now always enabled
    • The context parameter passed to loader, action, and middleware functions is always a RouterContextProvider instance
    • getLoadContext functions in custom servers must return a RouterContextProvider — returning a plain object is no longer supported
    • The MiddlewareEnabled type (previously exported as UNSAFE_MiddlewareEnabled) has been removed since the conditional it gated is now unconditional
    • The Future module augmentation pattern (interface Future { v8_middleware: true }) is no longer needed to type context in Data Mode
  • Update minimum Node version to 22.22.0 (#​14928)
  • Update minimum React version to 19.2.7 (#​15062)
Minor Changes
  • Bump dependencies (#​15080)
    • Bumped cookie from ^1.0.1 to ^1.1.1
    • Bumped set-cookie-parser from ^2.6.0 to ^3.1.0
Patch Changes
  • Ensure client middleware errors load lazy route error boundaries before bubbling (#​15086)
  • Remove explicit onSubmit type override from SharedFormProps to fix deprecation warning with @types/react@19.x (#​14932) (59ebcf1)
  • Update package builds to preserve individual module files in published artifacts. Public APIs and documented import paths are unchanged. (#​15092)
    • Updated package TypeScript configs to support modern module syntax used by the build configuration.
  • Migrate package builds from tsup to tsdown. Published package entry points and public APIs are unchanged. (#​15092)
  • Upgrade React Router's TypeScript tooling to TypeScript 6. Runtime behavior and public APIs are unchanged. (#​15092)

Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about these updates again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate
renovate Bot force-pushed the renovate/major-react-router-monorepo branch from b199962 to b109dec Compare June 29, 2026 21:02
@renovate
renovate Bot force-pushed the renovate/major-react-router-monorepo branch 2 times, most recently from 33e9995 to c948b83 Compare July 12, 2026 17:48
@renovate
renovate Bot force-pushed the renovate/major-react-router-monorepo branch 2 times, most recently from 6371f72 to 9354920 Compare July 22, 2026 18:08
@renovate
renovate Bot force-pushed the renovate/major-react-router-monorepo branch 3 times, most recently from bb74555 to ee5f587 Compare July 30, 2026 16:18
@renovate
renovate Bot force-pushed the renovate/major-react-router-monorepo branch from ee5f587 to 0096440 Compare August 7, 2026 18:35
@renovate
renovate Bot force-pushed the renovate/major-react-router-monorepo branch 4 times, most recently from 89b1c2b to 3d73773 Compare September 2, 2026 19:03
@renovate
renovate Bot force-pushed the renovate/major-react-router-monorepo branch 11 times, most recently from 44a2549 to e8c7387 Compare September 9, 2026 20:05
@renovate
renovate Bot force-pushed the renovate/major-react-router-monorepo branch 5 times, most recently from 8a329ae to a69a7a0 Compare September 16, 2026 11:02
@renovate
renovate Bot force-pushed the renovate/major-react-router-monorepo branch from a69a7a0 to fb65034 Compare September 24, 2026 21:13
@renovate
renovate Bot force-pushed the renovate/major-react-router-monorepo branch 3 times, most recently from f6acde2 to 7fe2457 Compare October 1, 2026 06:16
@renovate
renovate Bot force-pushed the renovate/major-react-router-monorepo branch 4 times, most recently from 69c027a to 09e96f4 Compare October 8, 2026 18:44
@renovate
renovate Bot force-pushed the renovate/major-react-router-monorepo branch from 09e96f4 to c6b12ae Compare October 8, 2026 21:12
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.

0 participants