React Router v8.0.0 shipped on June 17, 2026, followed by a v8.0.1 patch the next day. It is the first major release under the project's Open Governance model and the first on a planned yearly cadence, deliberately timed to the Node 20 end-of-life window. Node 22 itself is scheduled to reach EOL around May 2027, which is where the team is pointing v9. The headline is less a single feature and more a graduation: the API Development Strategy's job is to make major releases boring by landing breaking changes early behind Future Flags, and v8 is the release where every future.v8_* flag from v7 becomes the default.
Future flags graduate to defaults
If you adopted all active future flags in v7, the v8 API surface is largely unchanged, because those flags are removed or lifted to top-level config and their behavior is now unconditional. The flags that graduated:
future.v8_trailingSlashAwareDataRequestsis gone; trailing-slash-aware data request URLs are the default.future.v8_passThroughRequestsis gone; the raw incomingrequestis now always passed through toloaderandaction. Use theurlparameter when you want the normalized URL without React Router internals like.datasuffixes and_routessearch params.future.v8_middlewareis gone; middleware always runs. Thecontextpassed to loaders, actions, and middleware is always aRouterContextProvider,getLoadContextin a custom server must return one rather than a plain object, theMiddlewareEnabledtype is removed, and theinterface Future { v8_middleware: true }augmentation trick is no longer needed to typecontextin Data Mode.future.v8_viteEnvironmentApiis gone; the Vite Environment API build path is mandatory, which is why v8 requires Vite 7+ and why the old pre-rendering implementation was replaced by the Vite preview-server flow.future.v8_splitRouteModulesmoved to a top-levelsplitRouteModulesconfig option and defaults totrue. Set it tofalseto keep route modules in a single chunk, or"enforce"to require every route to be splittable.
The "graduation" framing is the real story. Future flags let the team land a breaking change in a v7 minor, let users opt in and report back, and then flip the default in the major with a year of production validation behind it. v8 is the payoff release for that pipeline.
New baselines: Node 22.22, React 19.2.7, Vite 7, and ESM-only
v8 sets a new baseline policy that is worth reading closely. React Router now officially supports all Active LTS Node versions and only the latest minor branch of Maintenance LTS, so it can bump the Maintenance LTS floor quickly when a security patch lands (as it did in the June 2026 Node.js security releases) and adopt Active LTS features that get backported. For the launch that floor is Node 22.22.0+, alongside React 19.2.7+ and Vite 7+.
To modernize the library, every published package is now ESM-only and the tsconfig target/lib fields moved from ES2020 to ES2022 across the board. That ESM-only decision is not cosmetic: it is what unlocked the adapter rewrites below, because the adapters could finally consume other ESM-only packages directly.
react-router-dom is gone, and so are a few deprecated APIs
The most visible removal is react-router-dom. In v7 the DOM APIs were collapsed into react-router/dom, and react-router-dom was kept only as a re-export shim so existing v6 imports kept working. The shim is gone in v8. Any remaining react-router-dom imports must move: RouterProvider and HydratedRouter come from react-router/dom, everything else from react-router.
Three more removals round out the list. The deprecated data fields passed to route-module meta functions are gone; use loaderData instead on MetaArgs and each item in MetaArgs.matches (#14931). The Cloudflare dev proxy at @react-router/dev/vite/cloudflare is removed in favor of @cloudflare/vite-plugin, which also drops wrangler@3 as a peer dependency of @react-router/dev. And the internal hasErrorBoundary field that was injected onto router.routes is gone; the router now infers error boundaries directly, and hasErrorBoundary is no longer accepted on RouteObject, DataRouteObject, the <Route> JSX props, or lazy route definitions (#15074).
Adapter internals: native fetch, node-fetch-server, tsdown, TypeScript 6
The adapter layer got a quiet rewrite that matters for anyone running React Router on Node or generating apps with create-react-router. @react-router/node and @react-router/serve switch from @mjackson/node-fetch-server to @remix-run/node-fetch-server, and create-react-router replaces @remix-run/web-fetch with Node's native fetch. The practical side effect: create-react-router no longer supports the HTTPS_PROXY environment variable that the old node-fetch-based polyfill honored (#14929), which is worth knowing if your CI sits behind a corporate proxy.
On the build side, the package build migrated from tsup to tsdown and the TypeScript tooling moved to TypeScript 6, while preserving individual module files in the published artifacts so public APIs and documented import paths are unchanged (#15092). @react-router/dev replaced cookie and set-cookie-parser with cookie-es, removed the vite-node dependency in favor of Vite's native module runner APIs, and bumped a long tail of dependencies (Babel to 7.29, react-refresh to 0.18, es-module-lexer to 2.1, chokidar to 5). The Express adapter now requires Express ^4.22.2 || ^5, and @react-router/serve moved to Express 5.2.1.
The upgrade path
For most teams the upgrade is mechanical if v7's future flags were already on. The work is: bump Node to 22.22+, React to 19.2.7+, and Vite to 7+; swap any lingering react-router-dom imports; rename data to loaderData in meta functions; and make sure getLoadContext returns a RouterContextProvider. The v7.18.0 release on June 16 also shipped a CSRF check logic fix that is a potential "breaking bug fix" behind a reverse proxy: the check now reads the host from the request URL rather than HTTP headers, so @react-router/serve or @react-router/express apps without trust proxy enabled may need to add the internal host to allowedActionOrigins. Test mutation requests as part of the upgrade.
v8.0.1 (June 18) is a single cleanup patch that removes the obsolete AppLoadContext type export left over from v7, now that request context always flows through RouterContextProvider (#15207). It lands a day after the major, which itself lands the same week vue-router hit its v5 line. The yearly cadence and the future-flag pipeline mean the next major should look a lot like this one: most of the breaks will already have shipped in a v8 minor, and v9 will mostly flip the defaults.



