Remix Release Notes

Follow

92 release notes curated from 2 sources by the Releasebot Team. Last updated: Oct 21, 2026

Get this feed:

Remix Products

  • Oct 19, 2026
    • Date parsed from source:
      Oct 19, 2026
    • First seen by Releasebot:
      Oct 21, 2026
    Remix logo

    React Router by Remix

    v8.5.0

    React Router releases new unstable API-only rendering, custom request handling, and application-controlled route discovery, alongside fixes for hydration, routing, and session reliability. It also deprecates its view transition APIs in favor of React’s <ViewTransition>.

    What's Changed

    View Transition Deprecations

    React Router's view transition APIs are now marked deprecated in favor of React's <ViewTransition> component, available in React 19.3+. The existing APIs will continue to work for the duration of React Router v8 and will be removed in v9.

    To use <ViewTransition>, wrap it around an <Outlet> in a persistent layout:

    import { ViewTransition } from "react";
    import { Outlet } from "react-router";
    
    export default function Layout() {
      return (
        <ViewTransition>
          <Outlet />
        </ViewTransition>
      );
    }
    

    When migrating, remove the viewTransition props/options and replace useViewTransitionState, NavLink's isTransitioning, and .transitioning styles with React's View Transition classes. Note using <ViewTransition> requires React transitions be enabled, so do not set useTransitions={false} on your router component. See the migration guide for examples and compatibility considerations.

    API-only Mode (unstable)

    Framework Mode can now serve static HTML while retaining a runtime server for loaders, actions, revalidation, and lazy route discovery. This allows you to deploy your static HTML files to a CDN on one origin while having them hit server loader/actions on a runtime server potentially on another origin.

    Enable API-only Mode in react-router.config.ts:

    import type { Config } from "@react-router/dev/config";
    
    export default {
      ssr: "unstable_api-only",
      // Optionally serve complete HTML for selected paths:
      prerender: ["/", "/about"],
    } satisfies Config;
    

    If you are running your API server on a separate origin, set unstable_apiServerOrigin in your config to route API calls to the proper origin (and ensure you configure CORS and allowedActionOrigins appropriately). See Rendering Strategies for deployment details.

    Custom Fetch and Request Metadata (unstable)

    In Framework Mode, pass unstable_fetch to <HydratedRouter> in app/entry.client.tsx to customize JavaScript-issued server data and route discovery requests:

    import { hydrateRoot } from "react-dom/client";
    import { HydratedRouter, type unstable_RouterFetch } from "react-router/dom";
    
    const customFetch: unstable_RouterFetch = (request, context) => {
      let headers = new Headers(request.headers);
      headers.set("X-App-Request-Type", context.type);
      return fetch(request, { headers });
    };
    
    hydrateRoot(document, <HydratedRouter unstable_fetch={customFetch} />);
    

    The callback receives a constructed Request and context identifying initialization, navigation, fetcher, revalidation, or manifest requests. Navigation-initiated data requests also include navigationType ("PUSH", "REPLACE", or "POP"). Data Mode data strategies receive equivalent metadata through unstable_initiator and unstable_navigationType. See Custom Fetch and Data Strategy for more information.

    Application-Controlled Route Discovery (unstable)

    In Framework Mode, enable future.unstable_customRouteDiscovery to discover selected destinations or complete the running client's route manifest:

    import type { Config } from "@react-router/dev/config";
    
    export default {
      future: { unstable_customRouteDiscovery: true },
    } satisfies Config;
    

    Custom discovery is optional: enabling the flag preserves automatic route discovery and built-in manifest-mismatch recovery unless you provide a custom onManifestMismatch handler. You do not need to call unstable_useRouteDiscovery to retain this behavior.

    import { Outlet, unstable_useRouteDiscovery } from "react-router";
    
    function Layout() {
      unstable_useRouteDiscovery({
        async onManifestMismatch(event) {
          await event.loadAllRoutes();
        },
      });
      return <Outlet />;
    }
    

    The hook exposes discoverRoutes(paths), loadAllRoutes(), and a shared state ("partial", "loading", or "complete"). Discovery loads route metadata without navigating, running loaders/actions, or prefetching route modules. With lazy discovery, custom mismatch handlers can load the running client's full manifest or let the pending operation cancel while preserving the current screen and data. See Application-Controlled Route Discovery for cancellation and recovery details.

    Minor Changes

    • react-router - Deprecate React Router's view transition APIs in favor of React's <ViewTransition> component, available in React 19.3 and later (#15493)
      • Deprecate the viewTransition props/options, useViewTransitionState, and NavLink's isTransitioning render prop and transitioning class
      • Preserve existing behavior, including support for older React versions
      • See the migration guide for a navigation example and compatibility considerations

    Patch Changes

    • react-router - Declare @types/react and @types/react-dom as optional peer dependencies so the shipped type definitions resolve React types under strict (non-hoisted) node_modules layouts (#15528)
    • react-router - Render the HydrateFallback of a route discovered through patchRoutesOnNavigation during initial hydration (#15537)
      • Routes discovered during initial hydration are now exposed in state.matches while their loaders run, so <RouterProvider> renders down to the discovered route's HydrateFallback instead of rendering nothing
    • react-router - Fix router state recovery when updates occur before RouterProvider subscribes, including when other subscribers are already attached, and report current client errors once without replaying server errors during hydration (#15637)
    • react-router - Fix matchPath not treating a static segment as optional when it contains characters outside [\w-] (#15425)
    • react-router - Stop revalidating a fetcher after fetcher.reset(), so its cleared data no longer comes back on the next revalidation (#15633)
    • @react-router/dev - Fix critical CSS collection in dev registering server-only route imports as client dependencies, which triggered dependency re-optimization and full page reloads (#15595)
    • @react-router/dev - Fix intermittent Prerender: Request failed for ... connect ECONNREFUSED errors during prerendering (#15325)
      • Send requests to the address the Vite preview server bound to
      • Avoid re-resolving localhost for each request, which could select a different address family (127.0.0.1 vs ::1)
    • @react-router/express - Fix the request URL losing its port when the Host or X-Forwarded-Host header is an IPv6 address (e.g., [::1]:3000) (#15559)
    • @react-router/node - Write file session data to a temporary file and rename it into place so concurrent commits of the same session can no longer corrupt its file (#15620)
      • Preserve existing session file permissions when replacing the file

    Unstable Changes

    ⚠️ Unstable features are not recommended for production use

    • react-router - Add an unstable_fetch prop to <HydratedRouter> to customize JavaScript-issued manifest and server data requests in conventional Framework Mode (#15586)
      • The function receives the intended request as well as context identifying the type of request
      • Data request context includes navigationType ("PUSH", "REPLACE", or "POP" for navigation-initiated requests, including reloaded fetchers; null otherwise)
        • Data strategies receive equivalent metadata through unstable_initiator and unstable_navigationType
      • The custom fetch context is a discriminated union, so narrowing type to "navigation" guarantees a non-null navigationType, while other data requests have a null navigationType
        • Fetchers reloaded after an initialization redirect retain the "initialization" type and include their fetcher key
      • Like other router initialization options, the implementation is captured when the singleton router is created and thus subsequent prop changes are ignored
      • Browser-managed data prefetches from <Link prefetch> use native <link rel="prefetch"> elements and do not call the custom implementation
      • Use the callback for custom fetch options, custom headers, safe request retries, or response header inspection
      • Return response bodies unchanged so React Router can decode its manifest and Turbo Stream data protocols
    • react-router - Support API-only Framework Mode with runtime server data loading, actions, revalidation, and lazy route discovery (#15601)
      • Hydrate prerendered pages from build-time data and fetch server loader data when hydrating a SPA fallback
      • Preserve normal loader revalidation and server-action support for eagerly loaded and lazily discovered routes, and honor loader opt-outs when making server data requests
    • @react-router/dev - Add unstable_apiServerOrigin to configure the origin for API-only loader, action, and route discovery requests (#15601)
    • react-router - Add unstable_useRouteDiscovery for application-controlled route discovery in conventional Framework Mode (#15602)
      • Discover selected destinations or load the running client's full route manifest without loading route modules
      • Compose manifest-mismatch handlers, with shared recovery and cancellation that preserves application state
      • Keep full-manifest failures catchable without rendering error boundaries, whether mismatch handlers use the hook or event's loadAllRoutes()
      • Cancel pending revalidation alongside a canceled navigation, retaining existing data and settling interrupted fetchers before restoring Back/Forward history
      • Enable future.unstable_customRouteDiscovery to opt in
        • Apps without the flag retain existing discovery behavior
      • Call event.defaultBehavior() from a custom mismatch handler to explicitly run built-in recovery
    • @react-router/dev - Add the future.unstable_customRouteDiscovery flag to opt into application-controlled route discovery in conventional Framework Mode (#15602)
    • react-router - Return middleware short-circuit responses as-is for document requests in RSC modes, including resource routes, instead of decoding non-RSC bodies as Flight (#15628)
      • Include server middleware in both eager and lazy RSC route configuration types
      • Preserve HTML rendering for cached Flight responses returned by middleware, and pass through raw responses that replace the result of next()
    • react-router - Fix <Await> failing to server render promises decoded from an RSC payload, which caused the Suspense boundary to switch to client rendering (#15597)
    • react-router - Fix an RSC server crash when a client aborts a document request while the HTML stream waits for the RSC payload (#15612)
    • react-router - Fix the unstable_useRouterState documentation example to call the imported alias (#15535)
    • @react-router/dev - Fix source maps for route modules in unstable RSC Framework Mode (#15479)

    Full Changelog: v8.4.0...v8.5.0

    Original source
  • Oct 19, 2026
    • Date parsed from source:
      Oct 19, 2026
    • First seen by Releasebot:
      Oct 21, 2026
    Remix logo

    React Router by Remix

    v8.5.0

    React Router adds API-only Framework Mode, customizable data fetching, and application-controlled route discovery, while deprecating its view transition APIs in favor of React’s component. The release also improves hydration, routing, and server reliability.

    What's Changed

    View Transition Deprecations

    React Router's view transition APIs are now marked deprecated in favor of React's component, available in React 19.3+. The existing APIs will continue to work for the duration of React Router v8 and will be removed in v9.

    To use , wrap it around an in a persistent layout:

    import { ViewTransition } from "react";
    import { Outlet } from "react-router";
    
    export default function Layout() {
      return (
        <ViewTransition>
          <Outlet />
        </ViewTransition>
      );
    }
    

    When migrating, remove the viewTransition props/options and replace useViewTransitionState, NavLink's isTransitioning, and .transitioning styles with React's View Transition classes. Note using requires React transitions be enabled, so do not set useTransitions={false} on your router component. See the migration guide for examples and compatibility considerations.

    API-only Mode (unstable)

    Framework Mode can now serve static HTML while retaining a runtime server for loaders, actions, revalidation, and lazy route discovery. This allows you to deploy your static HTML files to a CDN on one origin while having them hit server loader/actions on a runtime server potentially on another origin.

    Enable API-only Mode in react-router.config.ts:

    import type { Config } from "@react-router/dev/config";
    
    export default {
      ssr: "unstable_api-only",
      // Optionally serve complete HTML for selected paths:
      prerender: ["/", "/about"],
    } satisfies Config;
    

    If you are running your API server on a separate origin, set unstable_apiServerOrigin in your config to route API calls to the proper origin (and ensure you configure CORS and allowedActionOrigins appropriately). See Rendering Strategies for deployment details.

    Custom Fetch and Request Metadata (unstable)

    In Framework Mode, pass unstable_fetch to in app/entry.client.tsx to customize JavaScript-issued server data and route discovery requests:

    import { hydrateRoot } from "react-dom/client";
    import { HydratedRouter, type unstable_RouterFetch } from "react-router/dom";
    
    const customFetch: unstable_RouterFetch = (request, context) => {
      let headers = new Headers(request.headers);
      headers.set("X-App-Request-Type", context.type);
      return fetch(request, { headers });
    };
    
    hydrateRoot(document, <HydratedRouter unstable_fetch={customFetch} />);
    

    The callback receives a constructed Request and context identifying initialization, navigation, fetcher, revalidation, or manifest requests. Navigation-initiated data requests also include navigationType ("PUSH", "REPLACE", or "POP"). Data Mode data strategies receive equivalent metadata through unstable_initiator and unstable_navigationType. See Custom Fetch and Data Strategy for more information.

    Application-Controlled Route Discovery (unstable)

    In Framework Mode, enable future.unstable_customRouteDiscovery to discover selected destinations or complete the running client's route manifest:

    import type { Config } from "@react-router/dev/config";
    
    export default {
      future: { unstable_customRouteDiscovery: true },
    } satisfies Config;
    

    Custom discovery is optional: enabling the flag preserves automatic route discovery and built-in manifest-mismatch recovery unless you provide a custom onManifestMismatch handler. You do not need to call unstable_useRouteDiscovery to retain this behavior.

    import { Outlet, unstable_useRouteDiscovery } from "react-router";
    
    function Layout() {
      unstable_useRouteDiscovery({
        async onManifestMismatch(event) {
          await event.loadAllRoutes();
        },
      });
      return <Outlet />;
    }
    

    The hook exposes discoverRoutes(paths), loadAllRoutes(), and a shared state ("partial", "loading", or "complete"). Discovery loads route metadata without navigating, running loaders/actions, or prefetching route modules. With lazy discovery, custom mismatch handlers can load the running client's full manifest or let the pending operation cancel while preserving the current screen and data. See Application-Controlled Route Discovery for cancellation and recovery details.

    Minor Changes

    • react-router - Deprecate React Router's view transition APIs in favor of React's component, available in React 19.3 and later (#15493)
      • Deprecate the viewTransition props/options, useViewTransitionState, and NavLink's isTransitioning render prop and transitioning class
      • Preserve existing behavior, including support for older React versions
      • See the migration guide for a navigation example and compatibility considerations

    Patch Changes

    • react-router - Declare @types/react and @types/react-dom as optional peer dependencies so the shipped type definitions resolve React types under strict (non-hoisted) node_modules layouts (#15528)
    • react-router - Render the HydrateFallback of a route discovered through patchRoutesOnNavigation during initial hydration (#15537)
      • Routes discovered during initial hydration are now exposed in state.matches while their loaders run, so renders down to the discovered route's HydrateFallback instead of rendering nothing
    • react-router - Fix router state recovery when updates occur before RouterProvider subscribes, including when other subscribers are already attached, and report current client errors once without replaying server errors during hydration (#15637)
    • react-router - Fix matchPath not treating a static segment as optional when it contains characters outside [\w-] (#15425)
    • react-router - Stop revalidating a fetcher after fetcher.reset(), so its cleared data no longer comes back on the next revalidation (#15633)
    • @react-router/dev - Fix critical CSS collection in dev registering server-only route imports as client dependencies, which triggered dependency re-optimization and full page reloads (#15595)
    • @react-router/dev - Fix intermittent Prerender: Request failed for ... connect ECONNREFUSED errors during prerendering (#15325)
      • Send requests to the address the Vite preview server bound to
      • Avoid re-resolving localhost for each request, which could select a different address family (127.0.0.1 vs ::1)
    • @react-router/express - Fix the request URL losing its port when the Host or X-Forwarded-Host header is an IPv6 address (e.g., [::1]:3000) (#15559)
    • @react-router/node - Write file session data to a temporary file and rename it into place so concurrent commits of the same session can no longer corrupt its file (#15620)
      • Preserve existing session file permissions when replacing the file

    Unstable Changes

    ⚠️ Unstable features are not recommended for production use

    • react-router - Add an unstable_fetch prop to to customize JavaScript-issued manifest and server data requests in conventional Framework Mode (#15586)
      • The function receives the intended request as well as context identifying the type of request
      • Data request context includes navigationType ("PUSH", "REPLACE", or "POP" for navigation-initiated requests, including reloaded fetchers; null otherwise)
        • Data strategies receive equivalent metadata through unstable_initiator and unstable_navigationType
      • The custom fetch context is a discriminated union, so narrowing type to "navigation" guarantees a non-null navigationType, while other data requests have a null navigationType
        • Fetchers reloaded after an initialization redirect retain the "initialization" type and include their fetcher key
      • Like other router initialization options, the implementation is captured when the singleton router is created and thus subsequent prop changes are ignored
      • Browser-managed data prefetches from use native elements and do not call the custom implementation
      • Use the callback for custom fetch options, custom headers, safe request retries, or response header inspection
      • Return response bodies unchanged so React Router can decode its manifest and Turbo Stream data protocols
    • react-router - Support API-only Framework Mode with runtime server data loading, actions, revalidation, and lazy route discovery (#15601)
      • Hydrate prerendered pages from build-time data and fetch server loader data when hydrating a SPA fallback
      • Preserve normal loader revalidation and server-action support for eagerly loaded and lazily discovered routes, and honor loader opt-outs when making server data requests
    • @react-router/dev - Add unstable_apiServerOrigin to configure the origin for API-only loader, action, and route discovery requests (#15601)
    • react-router - Add unstable_useRouteDiscovery for application-controlled route discovery in conventional Framework Mode (#15602)
      • Discover selected destinations or load the running client's full route manifest without loading route modules
      • Compose manifest-mismatch handlers, with shared recovery and cancellation that preserves application state
      • Keep full-manifest failures catchable without rendering error boundaries, whether mismatch handlers use the hook or event's loadAllRoutes()
      • Cancel pending revalidation alongside a canceled navigation, retaining existing data and settling interrupted fetchers before restoring Back/Forward history
      • Enable future.unstable_customRouteDiscovery to opt in
        • Apps without the flag retain existing discovery behavior
      • Call event.defaultBehavior() from a custom mismatch handler to explicitly run built-in recovery
    • @react-router/dev - Add the future.unstable_customRouteDiscovery flag to opt into application-controlled route discovery in conventional Framework Mode (#15602)
    • react-router - Return middleware short-circuit responses as-is for document requests in RSC modes, including resource routes, instead of decoding non-RSC bodies as Flight (#15628)
      • Include server middleware in both eager and lazy RSC route configuration types
      • Preserve HTML rendering for cached Flight responses returned by middleware, and pass through raw responses that replace the result of next()
    • react-router - Fix failing to server render promises decoded from an RSC payload, which caused the Suspense boundary to switch to client rendering (#15597)
    • react-router - Fix an RSC server crash when a client aborts a document request while the HTML stream waits for the RSC payload (#15612)
    • react-router - Fix the unstable_useRouterState documentation example to call the imported alias (#15535)
    • @react-router/dev - Fix source maps for route modules in unstable RSC Framework Mode (#15479)
    Original source
  • All of your release notes in one feed

    Join Releasebot and get updates from Remix and hundreds of other software products.

    Create account
  • Sep 15, 2026
    • Date parsed from source:
      Sep 15, 2026
    • First seen by Releasebot:
      Sep 18, 2026
    Remix logo

    React Router by Remix

    v8.4.0

    React Router releases 8.4.0 with faster, more granular router contexts that reduce unnecessary re-renders, plus an unstable route-pattern matcher for more efficient route matching and parameter validation. It also ships deprecations, bug fixes, and dev and node runtime improvements.

    What's Changed

    Reduced Route Component Re-renders

    In 8.4.0, we reworked our internal data router contexts to be more granular which will reduce re-renders for components using hooks to access only some router state. For example, your component won't automatically re-render when navigation.state transitions to loading if it only calls useLocation. 4 internal contexts are now used:

    • Current location info (useLocation, useSearchParams, useMatches)
    • Pending navigation/revalidation info (useNavigation, useRevalidation)
    • Router loader/action data (useLoaderData, useActionData)
    • Fetcher info (useFetcher, useFetchers)

    More Efficient Route Matching (unstable)

    Data Mode can now opt into a more efficient route matcher powered by @remix-run/route-pattern. Synthetic Chromium benchmarks reduced navigation and fetcher completion times by ~19–38% with 100 routes and ~71–88% with 1,000 routes, excluding network latency and React rendering.

    Route definitions and path generation APIs such as generatePath and href continue to use React Router path syntax. Before enabling the flag, call unstable_preloadRoutePattern() so applications that do not opt in avoid downloading the new matcher.

    This also comes with a new unstable_validateParams route field that accepts keyed regular expressions. When a parameter fails validation, matching continues to later routes. Optional parameters that are not present are not validated.

    import { createBrowserRouter } from "react-router";
    import { unstable_preloadRoutePattern } from "react-router/route-pattern";
    
    unstable_preloadRoutePattern();
    
    let router = createBrowserRouter(
      [
        {
          path: "/:drink",
          unstable_validateParams: {
            drink: /^(wines|whiskeys|sakes|beers)$/,
          },
        },
        {
          path: "/:food",
          unstable_validateParams: {
            food: /^(meats|veggies|cheeses|sweets)$/,
          },
        },
      ],
      {
        future: {
          unstable_routePatternMatching: true,
        },
      },
    );
    

    The legacy matching APIs (matchRoutes, matchPath, and useMatch) continue to use the previous regex-based matcher and may produce slightly different results. Use the new router.match() API when you need to match with the opted-in router. This API is private and unstable along with the flag, and will stabilize as the first-class matching API when the flag stabilizes.

    Minor Changes

    • react-router - 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

    • react-router - 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
    • react-router - Preserve lazy route module import errors during SPA navigations instead of replacing them with a missing dataStrategy result error (#15464)
    • react-router - 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
    • react-router - Correctly escape streamed RSC redirect locations in meta tag attributes (#15491)
    • react-router - Avoid unintended document.startViewTransition calls during initial hydration and router.revalidate() calls (#15484)
    • react-router - 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
    • react-router - Preserve the underlying decode failure as the cause of the Unable to decode turbo-stream response error (#15450)
    • @react-router/dev - 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
    • @react-router/dev - Pass development conditions as CLI flags when relaunching the dev process (#15435)
    • @react-router/dev - Fix stack trace locations for split route modules when source maps are enabled in the reactRouter Vite plugin (#15440)
    • @react-router/node - 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

    Unstable Changes

    ⚠️ Unstable features are not recommended for production use

    • react-router - 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
    • react-router - 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

    Full Changelog: v8.3.1...v8.4.0

    Original source
  • Sep 15, 2026
    • Date parsed from source:
      Sep 15, 2026
    • First seen by Releasebot:
      Sep 18, 2026
    • Modified by Releasebot:
      Oct 13, 2026
    Remix logo

    React Router by Remix

    v8.4.0

    React Router 8.4.0 reduces unnecessary component re-renders and adds an opt-in, faster route matcher with parameter validation. The release also fixes navigation, streaming, proxy, and memory issues, while deprecating a static-router option.

    What's Changed

    Reduced Route Component Re-renders

    In 8.4.0, we reworked our internal data router contexts to be more granular which will reduce re-renders for components using hooks to access only some router state. For example, your component won't automatically re-render when navigation.state transitions to loading if it only calls useLocation. 4 internal contexts are now used:

    • Current location info (useLocation, useSearchParams, useMatches)
    • Pending navigation/revalidation info (useNavigation, useRevalidation)
    • Router loader/action data (useLoaderData, useActionData)
    • Fetcher info (useFetcher, useFetchers)

    More Efficient Route Matching (unstable)

    Data Mode can now opt into a more efficient route matcher powered by @remix-run/route-pattern. Synthetic Chromium benchmarks reduced navigation and fetcher completion times by ~19–38% with 100 routes and ~71–88% with 1,000 routes, excluding network latency and React rendering.

    Route definitions and path generation APIs such as generatePath and href continue to use React Router path syntax. Before enabling the flag, call unstable_preloadRoutePattern() so applications that do not opt in avoid downloading the new matcher.

    This also comes with a new unstable_validateParams route field that accepts keyed regular expressions. When a parameter fails validation, matching continues to later routes. Optional parameters that are not present are not validated.

    import { createBrowserRouter } from "react-router";
    import { unstable_preloadRoutePattern } from "react-router/route-pattern";
    unstable_preloadRoutePattern();
    let router = createBrowserRouter([
      {
        path: "/:drink",
        unstable_validateParams: {
          drink: /^(wines|whiskeys|sakes|beers)$/,
        },
      },
      {
        path: "/:food",
        unstable_validateParams: {
          food: /^(meats|veggies|cheeses|sweets)$/,
        },
      },
    ], {
      future: {
        unstable_routePatternMatching: true,
      },
    });
    

    The legacy matching APIs (matchRoutes, matchPath, and useMatch) continue to use the previous regex-based matcher and may produce slightly different results. Use the new router.match() API when you need to match with the opted-in router. This API is private and unstable along with the flag, and will stabilize as the first-class matching API when the flag stabilizes.

    Minor Changes

    • react-router - 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

    • react-router - 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
    • react-router - Preserve lazy route module import errors during SPA navigations instead of replacing them with a missing dataStrategy result error (#15464)
    • react-router - 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
    • react-router - Correctly escape streamed RSC redirect locations in meta tag attributes (#15491)
    • react-router - Avoid unintended document.startViewTransition calls during initial hydration and router.revalidate() calls (#15484)
    • react-router - 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
    • react-router - Preserve the underlying decode failure as the cause of the Unable to decode turbo-stream response error (#15450)
    • @react-router/dev - 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
    • @react-router/dev - Pass development conditions as CLI flags when relaunching the dev process (#15435)
    • @react-router/dev - Fix stack trace locations for split route modules when source maps are enabled in the reactRouter Vite plugin (#15440)
    • @react-router/node - 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

    Unstable Changes

    ⚠️ Unstable features are not recommended for production use

    • react-router - 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
    • react-router - 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

    Full Changelog: v8.3.1...v8.4.0

    Original source
  • Aug 27, 2026
    • Date parsed from source:
      Aug 27, 2026
    • First seen by Releasebot:
      Aug 28, 2026
    Remix logo

    React Router by Remix

    v8.3.1

    React Router ships patch updates that fix navigation, fetcher, scroll restoration, and lazy route discovery bugs, improve route matching performance and action origin validation, and strengthen URL handling. It also updates dev, node, and serve packages with build, streaming, and well-known file fixes.

    Patch Changes

    • react-router - Fix Expected fetcher: <key> error thrown on navigation when a fetcher is aborted during its post-action revalidation (#15365)
    • react-router - 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)
    • react-router - Improve route matching performance for long paths (#15417)
    • react-router - Improve validation of action request origins (#15419)
    • react-router - 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)
    • react-router - Properly respect the relative option in useSubmit/fetcher.submit when resolivng the action path (#15400)
    • react-router - Add additional URL validation on client side navigations/redirects (#15445)
    • @react-router/dev - Bump @remix-run/node-fetch-server dependency (#15447)
    • @react-router/dev - Generate JavaScript entry files at package build time so react-router reveal --no-typescript does not require Prettier at runtime (#15373)
      • Deprecate the --no-typescript flag ahead of its removal in React Router v9
    • @react-router/node - Bump @remix-run/node-fetch-server dependency (#15447)
    • @react-router/node - fix: Prevent client disconnects during streaming from crashing the Node process (#15324)
    • @react-router/serve - Bump @remix-run/node-fetch-server dependency (#15447)
    • @react-router/serve - 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)

    Full Changelog: v8.3.0...v8.3.1

    Original source
  • Similar to Remix with recent updates:

  • Aug 27, 2026
    • Date parsed from source:
      Aug 27, 2026
    • First seen by Releasebot:
      Aug 28, 2026
    • Modified by Releasebot:
      Oct 21, 2026
    Remix logo

    React Router by Remix

    v8.3.1

    React Router ships fixes and improvements across routing, navigation, and server handling, including faster matching for long paths, stronger URL and origin validation, more reliable scroll restoration, and safer streaming and static-file delivery.

    Patch Changes

    • react-router - Fix Expected fetcher: error thrown on navigation when a fetcher is aborted during its post-action revalidation (#15365)
    • react-router - 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)
    • react-router - Improve route matching performance for long paths (#15417)
    • react-router - Improve validation of action request origins (#15419)
    • react-router - Fix 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)
    • react-router - Properly respect the relative option in useSubmit / fetcher.submit when resolivng the action path (#15400)
    • react-router - Add additional URL validation on client side navigations/redirects (#15445)
    • @react-router/dev - Bump @remix-run/node-fetch-server dependency (#15447)
    • @react-router/dev - Generate JavaScript entry files at package build time so react-router reveal --no-typescript does not require Prettier at runtime (#15373)
      • Deprecate the --no-typescript flag ahead of its removal in React Router v9
    • @react-router/node - Bump @remix-run/node-fetch-server dependency (#15447)
    • @react-router/node - fix: Prevent client disconnects during streaming from crashing the Node process (#15324)
    • @react-router/serve - Bump @remix-run/node-fetch-server dependency (#15447)
    • @react-router/serve - 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)
    Original source
  • Jul 22, 2026
    • Date parsed from source:
      Jul 22, 2026
    • First seen by Releasebot:
      Jul 23, 2026
    Remix logo

    React Router by Remix

    v8.3.0

    React Router releases improved RSC support, adding CSP nonce and subresource integrity handling for custom entries, plus safer client version wiring and stability fixes. It also improves path param encoding, fixes NavLink pending state, and expands TypeScript 7 support across packages.

    What's Changed

    RSC Entry Updates

    This release includes several updates for unstable RSC apps that use custom entry files. Apps using the default RSC Framework entries do not need any changes.

    If you maintain custom RSC entries, review the generated unstable change notes for the new client version, subresource integrity, and CSP nonce wiring. Custom entry.rsc.tsx files should pass the generated client version to unstable_matchRSCServerRequest, and custom entry.ssr.tsx files may need to pass the generated import map integrity data and request nonce through React's HTML renderer.

    Minor Changes

    • @react-router/dev - Restart react-router dev with --conditions=development when not already configured (#15291)

    Patch Changes

    • react-router - 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
    • react-router - Use crypto.randomUUID() for createMemorySessionStorage session ids (#15302)
      • createMemorySessionStorage is only intended for local development and testing - sessions are lost when the server restarts
    • react-router - Fix NavLink not applying its pending state when to has a trailing slash (#15300)
    • @react-router/architect - Allow typescript@7 to be used (#15317)
    • @react-router/cloudflare - Allow typescript@7 to be used (#15317)
    • @react-router/dev - Allow typescript@7 to be used (#15317)
    • @react-router/express - Allow typescript@7 to be used (#15317)
    • @react-router/fs-routes - Allow typescript@7 to be used (#15317)
    • @react-router/node - Allow typescript@7 to be used (#15317)
    • @react-router/remix-routes-option-adapter - Allow typescript@7 to be used (#15317)

    Unstable Changes

    ⚠️ Unstable features are not recommended for production use

    • react-router - 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)
    • react-router - Harden RSC CSRF code paths (#15311)
    • react-router - 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
    • react-router - 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,
    });
    
    • react-router - 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}'`,
    );
    
    • @react-router/dev - Add unstable_rsc/client-version client build version virtual module (#15318)

    • @react-router/dev - 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,
    });
    

    Full Changelog: v8.2.0...v8.3.0

    Original source
  • Jul 22, 2026
    • Date parsed from source:
      Jul 22, 2026
    • First seen by Releasebot:
      Jul 23, 2026
    • Modified by Releasebot:
      Oct 11, 2026
    Remix logo

    React Router by Remix

    v8.3.0

    React Router ships RSC entry updates, stronger security support, and key bug fixes. It adds guidance for custom RSC entries, CSP nonce and subresource integrity wiring, improves dev and TypeScript 7 support, and fixes path encoding, NavLink pending state, and RSC stream stability.

    What's Changed

    RSC Entry Updates

    This release includes several updates for unstable RSC apps that use custom entry files. Apps using the default RSC Framework entries do not need any changes.

    If you maintain custom RSC entries, review the generated unstable change notes for the new client version, subresource integrity, and CSP nonce wiring. Custom entry.rsc.tsx files should pass the generated client version to unstable_matchRSCServerRequest, and custom entry.ssr.tsx files may need to pass the generated import map integrity data and request nonce through React's HTML renderer.

    Minor Changes

    • @react-router/dev - Restart react-router dev with --conditions=development when not already configured (#15291)

    Patch Changes

    • react-router - 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
    • react-router - Use crypto.randomUUID() for createMemorySessionStorage session ids (#15302)
      • createMemorySessionStorage is only intended for local development and testing - sessions are lost when the server restarts
    • react-router - Fix NavLink not applying its pending state when to has a trailing slash (#15300)
    • @react-router/architect - Allow typescript@7 to be used (#15317)
    • @react-router/cloudflare - Allow typescript@7 to be used (#15317)
    • @react-router/dev - Allow typescript@7 to be used (#15317)
    • @react-router/express - Allow typescript@7 to be used (#15317)
    • @react-router/fs-routes - Allow typescript@7 to be used (#15317)
    • @react-router/node - Allow typescript@7 to be used (#15317)
    • @react-router/remix-routes-option-adapter - Allow typescript@7 to be used (#15317)

    Unstable Changes

    ⚠️ Unstable features are not recommended for production use

    • react-router - 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)
    • react-router - Harden RSC CSRF code paths (#15311)
    • react-router - 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
    • react-router - 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,
    });
    
    • react-router - 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}'`);
    
    • @react-router/dev - Add unstable_rsc/client-version client build version virtual module (#15318)
    • @react-router/dev - 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,
      importMap: subResourceIntegrity ? { integrity: subResourceIntegrity } : undefined,
      signal: request.signal,
    });
    

    Full Changelog: v8.2.0...v8.3.0

    Original source
  • Jul 8, 2026
    • Date parsed from source:
      Jul 8, 2026
    • First seen by Releasebot:
      Jul 10, 2026
    Remix logo

    React Router by Remix

    v8.2.0

    React Router adds a Web Streams default server entry for non-Node Framework mode apps, with an opt-in flag for Node apps, and improves routing, param handling, blockers, and Vite 8+ config detection while also fixing URL encoding and route ranking issues.

    What's Changed

    Web Streams Default Server Entry

    Non-Node runtime Framework Mode apps no longer need a custom entry.server.tsx file using React's renderToReadableStream API. Apps with @react-router/{node,express,serve} dependencies will continue to default to renderToPipeableStream, while non-Node apps default to renderToReadableStream.

    Because Web Streams are stable in Node 22+, Node apps can also opt-into the Web Streams default entry with the new future.unstable_enableNodeReadableStream flag:

    import type { Config } from "@react-router/dev/config";
    
    export default {
      future: {
        unstable_enableNodeReadableStream: true,
      },
    } satisfies Config;
    

    This flag has no effect if you have a custom entry.server.tsx keep using their custom entry file. It only applies to the default entry used if one doesn't exist.

    Node apps opting-into the Web Streams API might even see a small performance boost because React Router already uses Web Streams internally, so this avoids additional conversions between Web/Node streams. If you see perf changes one way or another upon adopting this flag, please let us know!

    Minor Changes

    • @react-router/dev - 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
    • @react-router/dev - Detect nub as a supported package manager when installing framework dependencies (#15276)
    • create-react-router - Detect nub as a supported package manager when creating new projects (#15276)

    Patch Changes

    • react-router - Fix href() to properly stringify and URL-encode param values, matching generatePath() (#15277)
      • splat params preserve path separators while encoding each segment individually
    • react-router - 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
    • react-router - Preserve navigation blocker state through a revalidation (#15246)
    • react-router - 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
    • react-router - Use ReactFormState types instead of unknown (#15263)
    • @react-router/dev - Detect user rolldownOptions config in Vite 8+ (#15278)

    Unstable Changes

    ⚠️ Unstable features are not recommended for production use

    • @react-router/dev - Add the future.unstable_enableNodeReadableStream flag to opt Node Framework mode apps into using renderToReadableStream instead of renderToPipeableStream (#15290)
      • This flag has no effect if you have your own entry.server.tsx

    Full Changelog: v8.1.0...v8.2.0

    Original source
  • Jul 8, 2026
    • Date parsed from source:
      Jul 8, 2026
    • First seen by Releasebot:
      Jul 9, 2026
    • Modified by Releasebot:
      Oct 1, 2026
    Remix logo

    React Router by Remix

    v8.2.0

    React Router adds a Web Streams default server entry for non-Node Framework Mode apps, with an opt-in flag for Node apps to use renderToReadableStream. This release also brings route matching and navigation fixes, plus improved package manager and Vite 8 detection.

    What's Changed

    Web Streams Default Server Entry

    Non-Node runtime Framework Mode apps no longer need a custom entry.server.tsx file using React's renderToReadableStream API. Apps with @react-router/{node,express,serve} dependencies will continue to default to renderToPipeableStream, while non-Node apps default to renderToReadableStream.

    Because Web Streams are stable in Node 22+, Node apps can also opt-into the Web Streams default entry with the new future.unstable_enableNodeReadableStream flag:

    import type { Config } from "@react-router/dev/config";
    export default {
      future: {
        unstable_enableNodeReadableStream: true,
      },
    } satisfies Config;
    

    This flag has no effect if you have a custom entry.server.tsx keep using their custom entry file. It only applies to the default entry used if one doesn't exist.

    Node apps opting-into the Web Streams API might even see a small performance boost because React Router already uses Web Streams internally, so this avoids additional conversions between Web/Node streams. If you see perf changes one way or another upon adopting this flag, please let us know!

    Minor Changes

    • @react-router/dev - 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
    • @react-router/dev - Detect nub as a supported package manager when installing framework dependencies (#15276)
    • @create-react-router - Detect nub as a supported package manager when creating new projects (#15276)

    Patch Changes

    • react-router - Fix href() to properly stringify and URL-encode param values, matching generatePath() (#15277)
      • splat params preserve path separators while encoding each segment individually
    • react-router - 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
    • react-router - Preserve navigation blocker state through a revalidation (#15246)
    • react-router - 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
    • react-router - Use ReactFormState types instead of unknown (#15263)
    • @react-router/dev - Detect user rolldownOptions config in Vite 8+ (#15278)

    Unstable Changes

    ⚠️ Unstable features are not recommended for production use

    • @react-router/dev - Add the future.unstable_enableNodeReadableStream flag to opt Node Framework mode apps into using renderToReadableStream instead of renderToPipeableStream (#15290)
      • This flag has no effect if you have your own entry.server.tsx

    Full Changelog: v8.1.0...v8.2.0

    Original source
  • Jun 29, 2026
    • Date parsed from source:
      Jun 29, 2026
    • First seen by Releasebot:
      Jun 30, 2026
    Remix logo

    React Router by Remix

    v8.1.0

    React Router ships improved observability metadata, adding route and request details to instrumented results plus HTTP status codes for server handlers. It also expands create-react-router with optional Agent Skill setup by default in new projects, alongside several dev and CLI fixes.

    What's Changed

    Agent Skills Installation via create-react-router

    create-react-router can now setup the React Router Agent Skill in your new project. Interactive shells will issue a prompt on whether to include the skills, and they will be included by default with when running with --yes or in non-interactive shells. You can skip the skill addition with the --no-agent-skills CLI flag.

    Observability Metadata

    The Instrumentation APIs info parameter usually corresponds roughly to the inputs to the thing being instrumented (handler, loader, etc.). For route level instrumentations such as loaders, this contains useful information like the pattern (i.e., /blog/:slug) that allows you to report information that is easily aggregated by pattern, instead of having to manually deduce one from the request url.

    However, for outer layers such as the handler or a router navigate call - we can't provide a pattern because we haven't yet done any route matching, so it wasn't easy to report at those levels based on a generic route pattern.

    The internal instrumentation results now contain relevant metadata in result.meta for these outer instrumentation layers. For server handler instrumentations, we also expose the statusCode of the outgoing HTTP response:

    export const instrumentations = [
      {
        handler(handler) {
          handler.instrument({
            async request(handleRequest) {
              let result = await handleRequest();
    
              // Available to server `handler`, and router `navigate`/`fetch` instrumentations
              let normalizedUrl = result.meta?.url;
              let routePattern = result.meta?.pattern;
              let routeParams = result.meta?.params;
    
              // Available to server `handler` only
              let statusCode = result.statusCode;
            },
          });
        },
      },
    ];
    

    Please see the docs for more information.

    Minor Changes

    • react-router - 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
    • create-react-router - Add a default-on CLI option to include the official React Router agent skill in generated projects (#15213)
      • New projects include .agents/skills/react-router by default when running with --yes or in non-interactive shells
      • Interactive runs prompt to include the skill, defaulting to yes
      • Use --no-agent-skills to skip copying the skill

    Patch Changes

    • @react-router/dev - Fix a regression with the new prerendering plugin where the react-router.config.ts buildEnd hook would run before prerendering was completed (#15211)
    • @react-router/dev - Fixed react-router typegen crashes under the Bun runtime when Babel default imports are already unwrapped (#15214)
    • @react-router/dev - Replace the deprecated envFile:false Vite config with envDir:false to eliminate a deprecation warning when using [email protected]+ (#15230)
    • @react-router/dev - 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
    • @react-router/serve - Use Node's built-in networking APIs to find an available port and remove the get-port dependency (#15239)
    • create-react-router - Use Node's built-in utilities for CLI argument parsing, ANSI-stripping, and child process execution to remove the arg, strip-ansi, and execa dependencies (#15231)

    Full Changelog: v8.0.1...v8.1.0

    Original source
  • Jun 29, 2026
    • Date parsed from source:
      Jun 29, 2026
    • First seen by Releasebot:
      Jun 30, 2026
    • Modified by Releasebot:
      Oct 13, 2026
    Remix logo

    React Router by Remix

    v8.1.0

    React Router releases improved instrumentation metadata for server requests, navigation, and fetches, plus default-on agent skill setup for new projects. The update also fixes prerendering, type generation, and runtime configuration issues while trimming CLI dependencies.

    What's Changed

    Agent Skills Installation via create-react-router

    create-react-router can now setup the React Router in your new project. Interactive shells will issue a prompt on whether to include the skills, and they will be included by default with when running with --yes or in non-interactive shells. You can skip the skill addition with the --no-agent-skills CLI flag.

    Observability Metadata

    The Instrumentation APIs info parameter usually corresponds roughly to the inputs to the thing being instrumented (handler, loader, etc.). For route level instrumentations such as loaders, this contains useful information like the pattern (i.e., /blog/:slug) that allows you to report information that is easily aggregated by pattern, instead of having to manually deduce one from the request url.

    However, for outer layers such as the handler or a router navigate call - we can't provide a pattern because we haven't yet done any route matching, so it wasn't easy to report at those levels based on a generic route pattern.

    The internal instrumentation results now contain relevant metadata in result.meta for these outer instrumentation layers. For server handler instrumentations, we also expose the statusCode of the outgoing HTTP response:

    export const instrumentations = [
      {
        handler(handler) {
          handler.instrument({
            async request(handleRequest) {
              let result = await handleRequest();
              // Available to server `handler`, and router `navigate`/`fetch` instrumentations
              let normalizedUrl = result.meta?.url;
              let routePattern = result.meta?.pattern;
              let routeParams = result.meta?.params;
              // Available to server `handler` only
              let statusCode = result.statusCode;
            },
          });
        },
      },
    ];
    

    Please see the docs for more information.

    Minor Changes

    • react-router - 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
    • create-react-router - Add a default-on CLI option to include the official React Router agent skill in generated projects (#15213)
      • New projects include .agents/skills/react-router by default when running with --yes or in non-interactive shells
      • Interactive runs prompt to include the skill, defaulting to yes
      • Use --no-agent-skills to skip copying the skill

    Patch Changes

    • @react-router/dev - Fix a regression with the new prerendering plugin where the react-router.config.ts buildEnd hook would run before prerendering was completed (#15211)
    • @react-router/dev - Fixed react-router typegen crashes under the Bun runtime when Babel default imports are already unwrapped (#15214)
    • @react-router/dev - Replace the deprecated envFile:false Vite config with envDir:false to eliminate a deprecation warning when using [email protected]+ (#15230)
    • @react-router/dev - 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
    • @react-router/serve - Use Node's built-in networking APIs to find an available port and remove the get-port dependency (#15239)
    • create-react-router - Use Node's built-in utilities for CLI argument parsing, ANSI-stripping, and child process execution to remove the arg, strip-ansi, and execa dependencies (#15231)

    Full Changelog: v8.0.1...v8.1.0

    Original source
  • Jun 18, 2026
    • Date parsed from source:
      Jun 18, 2026
    • First seen by Releasebot:
      Jun 19, 2026
    Remix logo

    React Router by Remix

    v8.0.1

    React Router removes the obsolete AppLoadContext export in a patch update.

    Patch Changes

    • react-router - 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)

    Full Changelog: v8.0.0...v8.0.1

    Original source
  • Jun 18, 2026
    • Date parsed from source:
      Jun 18, 2026
    • First seen by Releasebot:
      Jun 18, 2026
    Remix logo

    React Router by Remix

    v8.0.1

    React Router fixes a patch release by removing the obsolete AppLoadContext export from v8.

    Patch Changes

    • react-router - 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)

    Full Changelog: v8.0.0...v8.0.1

    Original source
  • Jun 17, 2026
    • Date parsed from source:
      Jun 17, 2026
    • First seen by Releasebot:
      Jun 18, 2026
    • Modified by Releasebot:
      Jun 19, 2026
    Remix logo

    React Router by Remix

    v8.0.0

    React Router ships v8 with a new yearly major release cadence, default future flag behavior, updated baseline support for Node 22.22.0+, React 19.2.7+ and Vite 7+, plus an ESM-only publish model and several breaking API removals.

    What's Changed

    React Router v8 is here!

    We introduced a new Open Governance model last year and this marks the first major release on our new planned yearly major release cadence. We chose the June timeframe this year to align with the EOL timeframe for Node 20. Node 22 is scheduled to reach EOL in the May 2027 timeframe so we'll be aiming for a v9 release around the same time next year.

    Our API Development Strategy aims to make major releases relatively boring by introducing breaking changes ahead of time behind Future Flags. If you've adopted all active future flags in v7, then from a React Router API surface you're in good shape for v8. All future.v8_* flags have been removed (or lifted to a top-level config) and their behaviors are now the default.

    Baseline Support

    React Router v8 updates the following minimum supported versions:

    • Node 22.22.0+
      • Starting with v8, React Router will officially support all Active LTS node versions and only the latest minor branch of Maintenance LTS versions
      • This better allows us to bump minimum Maintenance LTS versions to account for newly released security patches
      • It also allows us to more quickly and easily adopt new Active LTS features backported to Maintenance LTS lines
      • Upgraded minimum Maintenance LTS versions will be done in React Router minor releases
    • React 19.2.7+
    • Vite 7+

    To modernize the library, React Router is now published as an ESM-only module and tsconfig target/lib fields have been updated to ES2022 across the board

    Adopted Future Flag Behavior

    The following v8 future flags have been removed and their behaviors are now the default:

    • future.v8_trailingSlashAwareDataRequests
    • future.v8_passThroughRequests
    • future.v8_middleware
    • future.v8_viteEnvironmentApi
    • future.v8_splitRouteModules has been moved to a to a top-level splitRouteModules config option and is enabled by default

    Removed react-router-dom

    In v7, we collapsed the DOM APIs into react-router/dom, but to ease the v6->v7 upgrade we continued re-exporting everything through react-router-dom. We have now dropped react-router-dom, so if you didn't get around to swapping your imports in v7, you will need to swap them to react-router and react-router/dom for v8.

    Removed deprecated meta data fields

    The data fields passed to route module meta functions were deprecated in v7 and are remove din v8. Use loaderData instead of data on MetaArgs and each item in MetaArgs.matches.

    Cloudflare Vite Plugin

    The React Router Cloudflare dev proxy (@react-router/dev/vite/cloudflare) has been removed in v8. Cloudflare projects should use @cloudflare/vite-plugin instead.

    @react-router/architect useRequestContextDomainName

    The @react-router/architect createRequestHandler useRequestContextDomainName option has been removed as that is now the default behavior in v8.

    Pre-rendering Flow

    In v7 we had a future.unstable_previewServerPrerendering flag that would opt you into a new pre-rendering flow using the Vite preview server (leveraging the Vite environment API). Now that the Vite environment API is always available on our new Vite 7+ baseline, we dropped this flag and the preview server flow has replaced our old pre-rendering implementation. It should be a non-breaking change but if you see issues, please let us know!

    Major Changes

    • react-router - Update minimum Node version to 22.22.0 (#14928)
    • react-router - Update minimum React version to 19.2.7 (#15062)
    • react-router - Remove the future.v8_trailingSlashAwareDataRequests flag (#15100)
      • Trailing slash-aware data request URLs are now the default behavior.
    • react-router - 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)
    • 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
    • react-router - Remove future.v8_passThroughRequests flag - the raw incoming request is now always passed through to loader/action. (#15079)
    • react-router - 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
    • @react-router/dev - Removed the future.v8_viteEnvironmentApi flag because the Vite Environment API is always enabled (#15077)
    • @react-router/dev - Removed the future.unstable_previewServerPrerendering flag and make prerendering with the Vite Environment API the default. (#15077)
    • react-router - Update tsconfig.json target/lib from ES2020 -> ES2022 (591853e)
    • react-router - Switch the published packages in packages/ to ESM-only. (#14895) (59ebcf1)
    • react-router - 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
    • react-router - 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.
    • react-router - 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
    • @react-router/architect - Bump @architect/functions to v8 (#15106)
    • @react-router/architect - Remove the useRequestContextDomainName option from createRequestHandler - this is now the default behavior (#15188)
    • @react-router/dev - 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
    • @react-router/dev - Require Vite 7+ and make the Vite Environment API build path mandatory (#15077)
    • @react-router/express - 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
    • @react-router/node - Switch from @mjackson/node-fetch-server to @remix-run/node-fetch-server now that we can directly use ESM-only packages (#14930)
    • @react-router/serve - Switch from @mjackson/node-fetch-server to @remix-run/node-fetch-server now that we can directly use ESM-only packages (#14930)
    • create-react-router - Switch from @remix-run/web-fetch to native fetch internally. (#14929)
      • This removes the underlying HTTPS_PROXY support that node-fetch and subsequently @remix-run/web-fetch supported

    Minor Changes

    • react-router - 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
    • @react-router/cloudflare - Bump @cloudflare/workers-types fromn ^4.20260520.1 to ^4.20260527.1 (#15106)
    • @react-router/dev - 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 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
    • @react-router/dev - Replace cookie and set-cookie-parser with cookie-es (#15109)
    • @react-router/dev - Removed the vite-node dependency in favor of Vite's native module runner APIs (#15104)
    • @react-router/serve - Bump express from 4.21.2 to 5.2.1 (#15101)
    • create-react-router - Bump dependencies (#15080)
      • Bumped execa from 5.1.1 to 9.6.1
      • Bumped log-update from ^5.0.1 to ^8.0.0
      • Bumped semver from ^7.3.7 to ^7.8.1
      • Bumped sort-package-json from ^1.55.0 to ^3.6.1
      • Bumped strip-ansi from ^6.0.1 to ^7.2.0
      • Bumped tar-fs from ^2.1.3 to ^3.1.2

    Patch Changes

    • react-router - Ensure client middleware errors load lazy route error boundaries before bubbling (#15086)
    • react-router - Remove explicit onSubmit type override from SharedFormProps to fix deprecation warning with @types/[email protected] (#14932) (59ebcf1)
    • react-router - 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.
    • react-router - Migrate package builds from tsup to tsdown. Published package entry points and public APIs are unchanged. (#15092)
    • react-router - Upgrade React Router's TypeScript tooling to TypeScript 6. Runtime behavior and public APIs are unchanged. (#15092)
    • @react-router/architect - Bump dependencies (#15080)
      • Bumped @types/aws-lambda from ^8.10.82 to ^8.10.161
    • @react-router/dev - 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
    • @react-router/dev - 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)
    • @react-router/fs-routes - Bump dependencies (#15091)
      • Bumped minimatch from ^9.0.0 to ^10.2.5
    • @react-router/node - Bump dependencies (#15106)
      • Bumped @remix-run/node-fetch-server from ^0.13.0 to ^0.13.3
    • @react-router/serve - Bump dependencies (#15091)
      • Bumped @remix-run/node-fetch-server from ^0.13.0 to ^0.13.3
      • Bumped get-port from 5.1.1 to 7.2.0

    Full Changelog: v7.18.0...v8.0.0

    Original source
Releasebot

Curated by the Releasebot team

Releasebot is an aggregator of official release notes from hundreds of software vendors and thousands of sources.

Our editorial process involves the manual review and audit of release notes procured with the help of automated systems.