You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Security has become more important recently, partly due to the impact of AI. For this reason, I don't want to run a server just for the frontend, so I would like to use Declarative Mode (<BrowserRouter>) in React Router v8. I really appreciate that you continue to support a mode that works without a server.
What is holding me back
Whichever mode you use, you have to install the react-router package, which contains the code for all modes. In v8, react-router exports server APIs such as createRequestHandler, createCookieSessionStorage, and createStaticHandler from the same entry point as BrowserRouter.
Thanks to tree shaking, unused code does not end up in the browser bundle (bundling v8.5.0 with esbuild produced 42KB when importing only the Declarative Mode APIs, and 211KB when importing everything). Even so, the following happens at the package level:
Many advisories published for react-router limit their scope to Framework Mode, SSR, or RSC in their descriptions (of the 20 advisories in the past 3 years, 12 explicitly state that they do not impact Declarative Mode). However, advisory data only contains package names and version ranges. Because Dependabot and npm audit cannot distinguish between modes, apps that run only in the browser also get alerts.
Every time an alert appears, you have to either read each advisory to check whether your app is affected, or update even when it is not.
Comparison of advisories over the past 3 years
From the GitHub Advisory Database, I collected the 20 advisories published between October 24, 2023 and October 24, 2026 that target react-router (including react-router-dom and @remix-run/router). I classified the affected modes based on each advisory's description.
Severity
Affects Framework Mode
Affects Data Mode (browser only)
Affects Declarative Mode
Critical
0
0
0
High
9
1
0
Medium
7
4
3
Low
1
0
0
Total
17
5
3
During the same period, advisories were also published for @react-router/node (CVE-2025-61686, Critical) and @react-router/express (CVE-2025-31137, High). Because these are separate packages, apps that use only react-router did not get alerts for them. For the server adapters, separating the code into its own package already keeps unrelated alerts away.
Proposal
I propose keeping react-router as it is and adding subset packages that contain only the APIs each mode needs (package names are examples).
The APIs above, plus the Data Mode APIs that run in the browser (createBrowserRouter, RouterProvider, useFetcher, etc., and route definitions using loader and action). SSR APIs such as createStaticHandler are not included
react-router (unchanged)
All modes (including Framework Mode, SSR, and RSC)
Because the features of each mode are additive, each package contains all the APIs of the previous one. Since this only adds packages without breaking the existing one, it has no impact on existing users. The idea is the same as the removal of createCookie and cookie-es that the maintainers are considering in #15371: reducing code and dependencies that apps don't use.
I expect the following benefits:
Based on the past 3 years, alerts for apps that use only Declarative Mode would drop from 20 to 3, and alerts for apps using Data Mode (browser only) would drop from 20 to 5
Users would only need to update when a fix is relevant to their app
Users would not need to install dependencies they don't use (such as cookie-es)
Vulnerabilities in client-side code would still be fixed by updating, as they are today. The goal of this proposal is to eliminate updates for code that the app does not use.
Notes
Considering why the packages were consolidated into react-router in v7, I understand that adding packages increases the maintenance burden. Publishing them from one repository with the same version, like @react-router/node and others, would be fine. Because Dependabot and npm audit only alert on the packages an advisory targets, users would not need to update even if a new version is published every time, as long as their package is not targeted. For this to work, I think advisories need to be registered only against the packages for the affected modes.
I also considered moving the server code (such as server-runtime) out of react-router into a separate package. However, when I looked at the fixes for the 20 advisories from the past 3 years, only about 7 were fixed in server code alone; the remaining 13 or so also changed code shared with the client. So I think this approach would not reduce alerts for Declarative Mode much.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Background
Security has become more important recently, partly due to the impact of AI. For this reason, I don't want to run a server just for the frontend, so I would like to use Declarative Mode (
<BrowserRouter>) in React Router v8. I really appreciate that you continue to support a mode that works without a server.What is holding me back
Whichever mode you use, you have to install the
react-routerpackage, which contains the code for all modes. In v8,react-routerexports server APIs such ascreateRequestHandler,createCookieSessionStorage, andcreateStaticHandlerfrom the same entry point asBrowserRouter.Thanks to tree shaking, unused code does not end up in the browser bundle (bundling v8.5.0 with esbuild produced 42KB when importing only the Declarative Mode APIs, and 211KB when importing everything). Even so, the following happens at the package level:
react-routerlimit their scope to Framework Mode, SSR, or RSC in their descriptions (of the 20 advisories in the past 3 years, 12 explicitly state that they do not impact Declarative Mode). However, advisory data only contains package names and version ranges. Because Dependabot andnpm auditcannot distinguish between modes, apps that run only in the browser also get alerts.Comparison of advisories over the past 3 years
From the GitHub Advisory Database, I collected the 20 advisories published between October 24, 2023 and October 24, 2026 that target
react-router(includingreact-router-domand@remix-run/router). I classified the affected modes based on each advisory's description.During the same period, advisories were also published for
@react-router/node(CVE-2025-61686, Critical) and@react-router/express(CVE-2025-31137, High). Because these are separate packages, apps that use onlyreact-routerdid not get alerts for them. For the server adapters, separating the code into its own package already keeps unrelated alerts away.Proposal
I propose keeping
react-routeras it is and adding subset packages that contain only the APIs each mode needs (package names are examples).@react-router/declarativeBrowserRouter,Routes,Route,Link,useNavigate,useLocation, etc.)@react-router/datacreateBrowserRouter,RouterProvider,useFetcher, etc., and route definitions usingloaderandaction). SSR APIs such ascreateStaticHandlerare not includedreact-router(unchanged)Because the features of each mode are additive, each package contains all the APIs of the previous one. Since this only adds packages without breaking the existing one, it has no impact on existing users. The idea is the same as the removal of
createCookieandcookie-esthat the maintainers are considering in #15371: reducing code and dependencies that apps don't use.I expect the following benefits:
cookie-es)Vulnerabilities in client-side code would still be fixed by updating, as they are today. The goal of this proposal is to eliminate updates for code that the app does not use.
Notes
react-routerin v7, I understand that adding packages increases the maintenance burden. Publishing them from one repository with the same version, like@react-router/nodeand others, would be fine. Because Dependabot andnpm auditonly alert on the packages an advisory targets, users would not need to update even if a new version is published every time, as long as their package is not targeted. For this to work, I think advisories need to be registered only against the packages for the affected modes.server-runtime) out ofreact-routerinto a separate package. However, when I looked at the fixes for the 20 advisories from the past 3 years, only about 7 were fixed in server code alone; the remaining 13 or so also changed code shared with the client. So I think this approach would not reduce alerts for Declarative Mode much.Thank you for considering this.
All reactions