Installing React Router

One package covers the browser, the server and React Native 36,878 :

Adding React Router to a Vite projectShell
npm install react-router@8.4.0

That adds four packages in all: React Router 8 139,386 ships only cookie-es and @remix-run/route-pattern of its own, and React 7,897 and React DOM are peer dependencies, so npm 2,036 refuses the install below React 19.2.7. The package publishes three entry points: react-router, react-router/dom and react-router/route-pattern.

For years the browser package was react-router-dom, a thin re-export plus the DOM-only pieces. Version 8 deletes it. It stopped at 7.18.4 and will never get an 8.x release, so any tutorial or package.json that installs it is pre-v8. The migration is mechanical:

The one import change that v8 forcesJavaScript
import { Link, Routes, Route, useNavigate } from 'react-router-dom';  // v6 and v7
import { Link, Routes, Route, useNavigate } from 'react-router';      // v8
import { RouterProvider } from 'react-router/dom';                    // the one exception

RouterProvider is the exception worth memorizing. The copy in react-router/dom is wired to React DOM's flushSync, which the router needs to make view transitions and some pending states land in a single paint; the copy in react-router is for non-DOM renderers. Import it from the wrong place and everything still works, just less smoothly — a bug that never produces an error message.

Upgrade an older code base v6 to v7 first, adopting the v8_middleware, v8_splitRouteModules and v8_viteEnvironmentApi future flags one at a time, then rename. From v5 it is a rewrite: <Switch>, <Route render>, useHistory and the match prop are all gone.