React Router 01 ⚛️ Installation — Package setup & dependencies
The React Router ecosystem underwent a significant structural change with the release of v7 and v8. The most consequential detail for installation is that the react-router-dom package was removed entirely in v8. Any tutorial or documentation that instructs npm install react-router-dom is outdated and will fail on the current version . The package is now simply react-router. The installation approach also depends on the mode you intend to use: Declarative mode (the simplest, for browser-only apps), Data mode (for advanced data loading), or Framework mode (the full-stack, Vite-powered setup) . Each mode requires a different set of dependencies and a different project configuration.
Key point: The package name is react-router, not react-router-dom. React Router v7 requires Node.js 20, React 18, and React DOM 18 as minimum versions . The create-react-router CLI is the fastest way to scaffold a new project, but the manual installation is the correct path for adding routing to an existing application.
Why package setup and dependencies matter
The package rename problem. In versions 5 and 6, the browser-specific package was react-router-dom, and the core package was react-router. The two were separate because the core package contained the platform-agnostic routing logic, while the DOM package contained the browser-specific components (BrowserRouter, Link, NavLink). In v7 and v8, the two were merged. The react-router package now contains everything, and the react-router-dom package is gone. An import from react-router-dom fails with a module-not-found error . The correct import is from react-router for most APIs, and from react-router/dom for the few DOM-specific components like RouterProvider in Data mode .
The mode problem. The installation dependencies differ by mode. Declarative mode requires only react-router and react-dom . Data mode requires react-router and react-dom, and the createBrowserRouter function is imported from react-router while RouterProvider is imported from react-router/dom . Framework mode requires react-router, @react-router/node, @react-router/serve, isbot, react, and react-dom as runtime dependencies, and @react-router/dev and vite as dev dependencies . The Framework mode is the full-stack setup with server-side rendering, loaders, and actions.
The Node.js version problem. React Router v7 requires Node.js 20 or later. React Router v8 requires Node.js 22.22.0 or later for the @react-router/dev package . The version of Node.js installed on the development machine and the CI runner must meet the minimum. The node --version command confirms the installed version.
The Vite problem. The Framework mode uses Vite as the build tool. The vite.config.js file must include the React Router plugin: import { reactRouter } from "@react-router/dev/vite" and plugins: [reactRouter()] . The package.json must have "type": "module" set, because React Router and future versions of Vite are ES module only . A project that uses CommonJS must be migrated to ESM before adopting React Router v8.
The trade-off. The CLI scaffold (npx create-react-router@latest) is the fastest path for a new project. The manual installation is the correct path for an existing project that already has a Vite setup or a custom build configuration. The manual path requires more steps but gives full control over the project structure and the dependency versions.
a. Declarative mode installation
The Declarative mode is the simplest. It requires only the react-router package and a <BrowserRouter> wrapper around the application .
# Create a Vite React project
npx create-vite@latest my-app --template react
# Navigate into the project
cd my-app
# Install React Router
npm i react-router
The BrowserRouter is imported from react-router and wrapped around the <App /> component in the entry file.
// src/main.jsx
import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter } from "react-router";
import App from "./App";
ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
The Declarative mode is the correct choice for a single-page application that does not need data loading on the server or advanced data fetching. The routes are defined with <Routes> and <Route> inside the <App /> component .
b. Data mode installation
The Data mode requires the same react-router package, but the router is created with createBrowserRouter and the <RouterProvider> is used instead of <BrowserRouter> .
# Install React Router
npm i react-router
The createBrowserRouter is imported from react-router, and the RouterProvider is imported from react-router/dom.
// src/main.jsx
import React from "react";
import ReactDOM from "react-dom/client";
import { createBrowserRouter } from "react-router";
import { RouterProvider } from "react-router/dom";
import App from "./App";
const router = createBrowserRouter([
{
path: "/",
element: <App />,
},
]);
ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<RouterProvider router={router} />
</React.StrictMode>
);
The Data mode is the correct choice for an application that needs loaders, actions, and the advanced data fetching features of React Router without the full-stack server setup .
c. Framework mode installation
The Framework mode is the full-stack setup. It requires the runtime dependencies and the dev dependencies, and it uses Vite with the React Router plugin .
# Create a new project with the CLI
npx create-react-router@latest my-react-router-app
# Navigate into the project
cd my-react-router-app
# Install dependencies
npm i
# Start the development server
npm run dev
The CLI creates the app/ directory with the root.jsx and routes.js files, the vite.config.js file with the React Router plugin, and the package.json with the "type": "module" setting. The npm run dev command starts the development server on http://localhost:5173 .
For a manual installation, the dependencies are installed explicitly:
# Runtime dependencies
npm i react-router @react-router/node @react-router/serve isbot react react-dom
# Dev dependencies
npm i -D @react-router/dev vite
The vite.config.js file is created with the React Router plugin:
import { reactRouter } from "@react-router/dev/vite";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [reactRouter()],
});
The package.json must have "type": "module" set. The npm pkg set type="module" command sets it .
Complete Example Session
# ============================================
# PART 1: DECLARATIVE MODE
# ============================================
npx create-vite@latest my-app --template react
cd my-app
npm i react-router
# ============================================
# PART 2: WRAP WITH BROWSERROUTER
# ============================================
# src/main.jsx
import { BrowserRouter } from "react-router";
<BrowserRouter>
<App />
</BrowserRouter>
# ============================================
# PART 3: DEFINE ROUTES
# ============================================
# src/App.jsx
import { Routes, Route } from "react-router";
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
# ============================================
# PART 4: DATA MODE
# ============================================
npm i react-router
# ============================================
# PART 5: CREATE BROWSER ROUTER
# ============================================
import { createBrowserRouter } from "react-router";
import { RouterProvider } from "react-router/dom";
const router = createBrowserRouter([
{ path: "/", element: <App /> },
]);
<RouterProvider router={router} />
# ============================================
# PART 6: FRAMEWORK MODE WITH CLI
# ============================================
npx create-react-router@latest my-react-router-app
cd my-react-router-app
npm i
npm run dev
# ============================================
# PART 7: FRAMEWORK MODE MANUAL
# ============================================
npm i react-router @react-router/node @react-router/serve isbot react react-dom
npm i -D @react-router/dev vite
# ============================================
# PART 8: VITE CONFIG
# ============================================
import { reactRouter } from "@react-router/dev/vite";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [reactRouter()],
});
# ============================================
# PART 9: VERIFY INSTALLATION
# ============================================
npm run dev
# Open http://localhost:5173
The nine parts trace the installation: Declarative mode, BrowserRouter, routes, Data mode, createBrowserRouter, Framework CLI, Framework manual, Vite config, and verification.
Quick Reference
Package Names
| Version | Package |
|---|---|
| v5, v6 | react-router-dom |
| v7, v8 | react-router |
Mode Dependencies
| Mode | Runtime Dependencies |
|---|---|
| Declarative | react-router, react, react-dom |
| Data | react-router, react, react-dom |
| Framework | react-router, @react-router/node, @react-router/serve, isbot, react, react-dom |
Framework Dev Dependencies
| Package | Purpose |
|---|---|
@react-router/dev | Vite plugin and build tooling |
vite | Build tool |
Minimum Versions
| Version | Node.js | React |
|---|---|---|
| v7 | 20 | 18 |
| v8 | 22.22.0 | 18 |
Import Paths
| API | Import From |
|---|---|
BrowserRouter, Routes, Route, Link | react-router |
createBrowserRouter | react-router |
RouterProvider (Data mode) | react-router/dom |
Best Practices
✅ Do This:
npm i react-router
<!-- Install the correct package --> # ✅
npm pkg set type="module"
<!-- Set ESM for Framework mode --> # ✅
npx create-react-router@latest my-app
<!-- Use the CLI for new projects --> # ✅
❌ Don’t Do This:
npm i react-router-dom
<!-- The package was removed in v8 --> # ❌
import { Link } from "react-router-dom"
<!-- Fails on v8 --> # ❌
# Use CommonJS with Framework mode
<!-- React Router v8 is ESM-only --> # ❌
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
react-router-dom not found | Package removed in v8 | Install react-router |
RouterProvider not found | Wrong import path | Import from react-router/dom |
createBrowserRouter not found | Wrong package | Import from react-router |
| Framework build fails | No "type": "module" | npm pkg set type="module" |
| Vite plugin not applied | Missing plugin in config | Add reactRouter() to plugins |
Real-World Examples
1. Install Declarative
npm i react-router
2. Import BrowserRouter
import { BrowserRouter } from "react-router";
3. Import Routes
import { Routes, Route } from "react-router";
4. Import Link
import { Link, NavLink } from "react-router";
5. Create Data Router
import { createBrowserRouter } from "react-router";
6. Import RouterProvider
import { RouterProvider } from "react-router/dom";
7. Framework CLI
npx create-react-router@latest my-app
8. Framework Manual
npm i react-router @react-router/node @react-router/serve isbot react react-dom
9. Vite Config
plugins: [reactRouter()]
10. Verify Node Version
node --version
Visual
Mode Hierarchy
┌──────────────────────────────────────────────┐
│ Framework Mode │
│ ├── Declarative features │
│ ├── Data features (loaders, actions) │
│ ├── Server-side rendering │
│ └── Vite plugin │
└──────────────────┬───────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ Data Mode │
│ ├── Declarative features │
│ └── Data features (loaders, actions) │
└──────────────────┬───────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ Declarative Mode │
│ ├── Routes and Route │
│ ├── Link and NavLink │
│ └── BrowserRouter │
└──────────────────────────────────────────────┘
Import Paths
┌──────────────────────────────────────────────┐
│ react-router │
│ ├── BrowserRouter │
│ ├── Routes, Route │
│ ├── Link, NavLink │
│ ├── createBrowserRouter │
│ └── useParams, useNavigate │
└──────────────────┬───────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ react-router/dom │
│ └── RouterProvider (Data mode) │
└──────────────────────────────────────────────┘
Summary
| Item | Value |
|---|---|
| Package name | react-router |
| Removed package | react-router-dom (v8) |
| Minimum Node.js (v7) | 20 |
| Minimum Node.js (v8) | 22.22.0 |
| Minimum React | 18 |
| Declarative wrapper | BrowserRouter |
| Data router | createBrowserRouter |
| Data provider | RouterProvider from react-router/dom |
| Framework CLI | npx create-react-router@latest |
| Framework dev deps | @react-router/dev, vite |
| ESM requirement | "type": "module" |
Key takeaways:
- The package is
react-router, notreact-router-dom. Thereact-router-dompackage was removed in v8. The correct import for most APIs is fromreact-router, and the DOM-specificRouterProvideris imported fromreact-router/dom. - The mode determines the dependencies. Declarative mode needs only
react-router. Framework mode needs the@react-routerpackages, Vite, and the@react-router/devplugin . - The Node.js and React versions are minimums. React Router v7 requires Node.js 20 and React 18. React Router v8 requires Node.js 22.22.0 for the dev tooling .
- The Framework mode is ESM-only. The
package.jsonmust have"type": "module"set, and the Vite config must include the React Router plugin . - The CLI is the fastest path for new projects. The
npx create-react-router@latestcommand scaffolds the full Framework mode setup with the correct dependencies and configuration .
Remember: The installation is not a single command. The package, the mode, and the Node.js version must all be correct. The react-router package is the foundation. The BrowserRouter is the Declarative wrapper. The createBrowserRouter is the Data entry point. The @react-router/dev is the Framework build tool. The exam tests the package name and the mode distinction.
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!