UNPKG

6.74 kBMarkdownView Raw
1---
2title: Future Changes
3order: 1
4---
5
6# Future Changes
7
8We try our best to keep major version upgrades simple and boring through the use of opt-in APIs and [Future Flags][api-development-strategy]. Future flags are used to gate breaking changes that don't otherwise have a good call-site opt-in strategy. By adopting all opt-in APIs and future flags, you should be able to upgrade to the next major version of React Router with minimal changes.
9
10We plan to ship new major versions roughly once a year as described in our [Open Governance Model][governance], so this guide will continue to track future changes you can adopt ahead of the next major release. v9 is currently estimated for mid-2027 when Node 22 reaches EOL.
11
12We highly recommend you make a commit after each step and ship it instead of doing everything all at once. Most flags can be adopted in any order, with exceptions noted below.
13
14<docs-info>This is an evolving document that will be updated throughout the duration of v8</docs-info>
15
16## Minimum Versions
17
18[MODES: framework, data, declarative]
19
20<br/>
21<br/>
22
23React Router v9 will require the following minimum versions (as of now). You can prepare for the upgrade by updating them while still on v8:
24
25- `node@24+`
26
27## Update to latest v8.x
28
29Before adopting any future flags or call-site opt-in changes, you should update to the latest minor version of v8.x to make sure you have access to the latest flags. You may see a number of deprecation warnings as you upgrade, which we'll cover below.
30
31👉 Update to latest v8
32
33```sh
34npm install react-router@8 @react-router/{dev,node,etc.}@8
35```
36
37## Future Flags
38
39_No future flags yet_
40
41## Other Planned Breaking Changes
42
43_No known planned breaking changes yet_
44
45## Unstable Future Flags (Optional)
46
47We document some [unstable] flags here as a reference for folks contributing to the project via beta testing, but they are not generally recommended for production use and may have breaking changes in patch or minor releases - adopt with caution!
48
49### `future.unstable_enableNodeReadableStream`
50
51[MODES: framework]
52
53<br/>
54<br/>
55
56**Background**
57
58Now that the Web Streams API is [stable](https://nodejs.org/docs/latest-v22.x/api/webstreams.html) in Node 22+, it's viable for React Router to use React's [`renderToReadableStream`](https://react.dev/reference/react-dom/server/renderToReadableStream) in the server entry.
59
60When no `entry.server.tsx` file is present, React Router defaults to [`renderToPipeableStream`](https://react.dev/reference/react-dom/server/renderToPipeableStream) when a Node runtime is detected, and `renderToReadableStream` otherwise.
61
62With this flag enabled, React Router will default to `renderToReadableStream` on all runtimes, including Node. You can continue to use `renderToPipeableStream` via a custom `entry.server.tsx` file if needed.
63
64<docs-info>Enabling this flag might even provide slight performance gains because we are already using Web Streams internally, so this flag removes some unnecessary transforms between Web and Node streams.</docs-info>
65
66👉 **Enable the Flag**
67
68```ts filename=react-router.config.ts
69import type { Config } from "@react-router/dev/config";
70
71export default {
72 future: {
73 unstable_enableNodeReadableStream: true,
74 },
75} satisfies Config;
76```
77
78**Update your Code**
79
80No code changes are required. If your app has a custom `entry.server.tsx`, this flag will not change your runtime behavior.
81
82### `future.unstable_optimizeDeps`
83
84[MODES: framework]
85
86<br/>
87<br/>
88
89**Background**
90
91This flag lets React Router provide Vite's dependency optimizer with the client entry file and route module files. This can improve dependency optimization in development, but the behavior is still experimental.
92
93👉 **Enable the Flag**
94
95```ts filename=react-router.config.ts
96import type { Config } from "@react-router/dev/config";
97
98export default {
99 future: {
100 unstable_optimizeDeps: true,
101 },
102} satisfies Config;
103```
104
105**Update your Code**
106
107No code changes are required. If you run into dependency optimization issues after enabling this flag, remove the flag and restart the dev server.
108
109### `future.unstable_routePatternMatching`
110
111[MODES: data]
112
113<br/>
114<br/>
115
116**Background**
117
118This flag opts Data Routers into a new (and vastly more efficient) route matcher
119powered by [`@remix-run/route-pattern`](https://github.com/remix-run/remix/tree/main/packages/route-pattern).
120It supports the existing React Router path syntax and matching behavior, but may
121rank _slightly_ differently in some cases - please read the section below on
122potential ranking differences.
123
124👉 **Preload the Matcher and Enable the Flag**
125
126```ts
127import { createBrowserRouter } from "react-router";
128import { unstable_preloadRoutePattern } from "react-router/route-pattern";
129
130unstable_preloadRoutePattern();
131
132const router = createBrowserRouter(routes, {
133 future: {
134 unstable_routePatternMatching: true,
135 },
136});
137```
138
139The `react-router/route-pattern` sub-export statically imports the new matcher
140implementation. Tree-shaking bundlers remove it from applications that do not
141use the preload function. You must call the function before creating a router
142with the flag enabled - router creation will throw if the matcher has not been
143initialized. Initialization is synchronous, and repeated calls are safe.
144
145**Update your Code**
146
147No route configuration changes are required, but you should review any routes with
148overlapping patterns to ensure the new ranking behavior selects the intended route.
149The new implementation matches by positional specificity instead of aggregate
150segment scores. This means a route with a longer static prefix can rank above a
151route with more dynamic segments.
152
153For example, both of these routes match `/products/one/two/three`:
154
155```ts
156const routes = [
157 { path: "/products/*", id: "products" },
158 {
159 path: "/:first/:second/:third/:fourth",
160 id: "segments",
161 },
162];
163```
164
165The legacy matcher selects `segments` based on its aggregate segment score. The
166new matcher selects `products` because its static `products` segment is more
167specific than the dynamic `:first` segment in the same position.
168
169Once you enable this flag, use the `router.match()` when you need to match a
170location (this is currently marked private and will become stable at the same
171time this flag stabilizes). Standalone matching APIs such as `matchRoutes`,
172`matchPath`, and `useMatch` continue to use the legacy matcher and may return
173different matches than the router.
174
175Case-sensitive routes are not currently supported with this flag.
176
177[api-development-strategy]: ../community/api-development-strategy
178[governance]: https://github.com/remix-run/react-router/blob/main/GOVERNANCE.md#design-goals
179[unstable]: ../community/api-development-strategy#unstable-flags