| | |

React Router 01 ⚛️ Installation — Package setup & dependencies

⏱️ Estimated read: 9 min | |

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

VersionPackage
v5, v6react-router-dom
v7, v8react-router

Mode Dependencies

ModeRuntime Dependencies
Declarativereact-router, react, react-dom
Datareact-router, react, react-dom
Frameworkreact-router, @react-router/node, @react-router/serve, isbot, react, react-dom

Framework Dev Dependencies

PackagePurpose
@react-router/devVite plugin and build tooling
viteBuild tool

Minimum Versions

VersionNode.jsReact
v72018
v822.22.018

Import Paths

APIImport From
BrowserRouter, Routes, Route, Linkreact-router
createBrowserRouterreact-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

PitfallWhy It HappensFix
react-router-dom not foundPackage removed in v8Install react-router
RouterProvider not foundWrong import pathImport from react-router/dom
createBrowserRouter not foundWrong packageImport from react-router
Framework build failsNo "type": "module"npm pkg set type="module"
Vite plugin not appliedMissing plugin in configAdd 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

ItemValue
Package namereact-router
Removed packagereact-router-dom (v8)
Minimum Node.js (v7)20
Minimum Node.js (v8)22.22.0
Minimum React18
Declarative wrapperBrowserRouter
Data routercreateBrowserRouter
Data providerRouterProvider from react-router/dom
Framework CLInpx create-react-router@latest
Framework dev deps@react-router/dev, vite
ESM requirement"type": "module"

Key takeaways:

  • The package is react-router, not react-router-dom. The react-router-dom package was removed in v8. The correct import for most APIs is from react-router, and the DOM-specific RouterProvider is imported from react-router/dom .
  • The mode determines the dependencies. Declarative mode needs only react-router. Framework mode needs the @react-router packages, Vite, and the @react-router/dev plugin .
  • 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.json must 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@latest command 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.

Was this helpful?


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!