react-router vs react-router-dom vs @reach/router vs react-router-native
Client-Side Routing Strategies in React Ecosystems
react-routerreact-router-dom@reach/routerreact-router-nativeSimilar Packages:

Client-Side Routing Strategies in React Ecosystems

react-router serves as the core routing logic for React applications, while react-router-dom and react-router-native provide environment-specific bindings for web and mobile platforms respectively. @reach/router was a popular alternative that merged into the react-router project with version 6, making it a legacy package. Together, these tools manage navigation, URL synchronization, and component rendering based on location, but they target different stages of the ecosystem lifecycle and deployment environments.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
react-router27,773,97056,3214.18 MB15625 days agoMIT
react-router-dom24,114,70156,3215.46 kB15625 days agoMIT
@reach/router441,0226,849-1736 years agoMIT
react-router-native41,09456,32140.2 kB1562 months agoMIT

React Routing Ecosystem: Core, Web, Mobile, and Legacy Compared

Navigating between views is a fundamental requirement for single-page applications. The React ecosystem offers a family of routing packages that share a common history but serve distinct purposes. react-router provides the core logic, react-router-dom adapts it for the web, react-router-native adapts it for mobile, and @reach/router represents the legacy predecessor. Let's compare how they handle real-world routing tasks.

🛠️ Maintenance Status: Active vs Legacy

@reach/router is no longer maintained.

  • The team merged efforts with react-router starting at version 6.
  • Using it means missing out on security patches and new features.
// @reach/router: Legacy (Deprecated)  
// Do not use in new projects  
import { Router, Route } from "@reach/router";  
<Router>  
  <Route path="/about" component={About} />  
</Router>

react-router is the active core library.

  • It receives regular updates and powers the other packages.
  • It is stable but often used indirectly via DOM or Native bindings.
// react-router: Core Logic  
// Usually installed as a dependency, not directly  
import { Routes, Route } from "react-router";  
<Routes>  
  <Route path="/about" element={<About />} />  
</Routes>

react-router-dom is the active web standard.

  • It is the recommended entry point for browser-based apps.
  • Fully supported with long-term maintenance guarantees.
// react-router-dom: Web Standard  
// Recommended for web apps  
import { Routes, Route } from "react-router-dom";  
<Routes>  
  <Route path="/about" element={<About />} />  
</Routes>

react-router-native is the active mobile standard.

  • It is the recommended entry point for React Native apps.
  • Fully supported with mobile-specific optimizations.
// react-router-native: Mobile Standard  
// Recommended for mobile apps  
import { Routes, Route } from "react-router-native";  
<Routes>  
  <Route path="/about" element={<About />} />  
</Routes>

🌍 Environment Targeting: Web vs Mobile vs Core

@reach/router was designed primarily for the web.

  • It relied on DOM APIs for history management.
  • Not suitable for native mobile environments without extra work.
// @reach/router: Web Focused  
import { Router } from "@reach/router";  
// Uses browser history internally  
<Router basepath="/app">  
  <Home path="/" />  
</Router>

react-router is platform independent.

  • It does not include history or link components by default.
  • You must provide your own history implementation to use it.
// react-router: Platform Independent  
import { Router, Routes } from "react-router";  
// Requires custom history prop  
<Router history={customHistory}>  
  <Routes>...</Routes>  
</Router>

react-router-dom is built for browsers.

  • It includes BrowserRouter which wraps the HTML5 history API.
  • Provides Link components that render <a> tags.
// react-router-dom: Browser Specific  
import { BrowserRouter, Link } from "react-router-dom";  
<BrowserRouter>  
  <Link to="/about">About</Link>  
</BrowserRouter>

react-router-native is built for mobile.

  • It includes NativeRouter which uses in-memory history.
  • Provides Link components that render TouchableOpacity.
// react-router-native: Mobile Specific  
import { NativeRouter, Link } from "react-router-native";  
<NativeRouter>  
  <Link to="/about">About</Link>  
</NativeRouter>

🧭 Navigation and Links: API Differences

@reach/router used a simpler hook set in version 3.

  • useLocation and navigate were available but less consistent.
  • Link components required exact props for active styling.
// @reach/router: Legacy Navigation  
import { navigate } from "@reach/router";  
function Button() {  
  return <button onClick={() => navigate("/home")}>Go</button>;  
}

react-router provides the core navigation hooks.

  • useNavigate is the standard way to change routes programmatically.
  • Works the same across DOM and Native when wrapped correctly.
// react-router: Core Navigation  
import { useNavigate } from "react-router";  
function Button() {  
  const navigate = useNavigate();  
  return <button onClick={() => navigate("/home")}>Go</button>;  
}

react-router-dom adds web-specific link behavior.

  • Link prevents full page reloads automatically.
  • NavLink supports active state styling for menus.
// react-router-dom: Web Links  
import { Link, NavLink } from "react-router-dom";  
function Menu() {  
  return <NavLink to="/home" className={({ isActive }) => isActive ? "bold" : ""}>Home</NavLink>;  
}

react-router-native adds mobile-specific touch handling.

  • Link uses native touchables for better performance.
  • underlayColor props allow visual feedback on press.
// react-router-native: Mobile Links  
import { Link } from "react-router-native";  
function Menu() {  
  return <Link to="/home" underlayColor="#eee"><Text>Home</Text></Link>;  
}

📥 Data Loading: Legacy vs Modern Patterns

@reach/router did not have built-in data loading.

  • Developers used useEffect or external libraries like React Query.
  • No integration with the routing lifecycle for fetching.
// @reach/router: Manual Data Loading  
function Profile() {  
  const [data, setData] = useState(null);  
  useEffect(() => { fetch("/api").then(setData) }, []);  
  return <div>{data?.name}</div>;  
}

react-router v6.4+ introduced data routers.

  • loader functions run before the component renders.
  • Core logic supports this but requires environment bindings.
// react-router: Core Data Loading  
// Conceptual example using createRouter  
const router = createRouter({  
  routes: [{ path: "/profile", loader: loadProfile }]  
});

react-router-dom fully supports data loading APIs.

  • createBrowserRouter enables loader and action usage.
  • useLoaderData hook accesses the fetched data safely.
// react-router-dom: Web Data Loading  
import { createBrowserRouter, useLoaderData } from "react-router-dom";  
const router = createBrowserRouter([{  
  path: "/profile",  
  loader: async () => fetch("/api"),  
  element: <Profile />  
}]);

react-router-native has limited data router support currently.

  • Most mobile apps still rely on useEffect or React Query.
  • The API surface is smaller compared to the DOM version.
// react-router-native: Mobile Data Loading  
// Common pattern using hooks  
function Profile() {  
  const [data, setData] = useState(null);  
  useEffect(() => { fetch("/api").then(setData) }, []);  
  return <View>{data && <Text>{data.name}</Text>}</View>;  
}

📊 Summary: Key Differences

Feature@reach/routerreact-routerreact-router-domreact-router-native
Status⚠️ Deprecated✅ Active Core✅ Active Web✅ Active Mobile
Target🌐 Web (Legacy)⚙️ Logic Only🌐 Browser📱 React Native
Router<Router><Router> (Custom)<BrowserRouter><NativeRouter>
Links<Link>N/A<Link> ()<Link> (Touchable)
Data API❌ None⚙️ Core Support✅ Full Support⚠️ Limited Support

💡 The Big Picture

@reach/router is a legacy tool that should be retired.

  • It served a purpose in the past but is now obsolete.
  • Migration to react-router-dom is the only sustainable path.

react-router is the engine under the hood.

  • You rarely install it alone unless building custom tools.
  • It ensures consistency across web and mobile packages.

react-router-dom is the default for web developers.

  • It offers the best balance of features and ease of use.
  • Ideal for dashboards, e-commerce, and content sites.

react-router-native is the choice for mobile teams.

  • It adapts routing concepts to touch interfaces.
  • Essential for cross-platform React Native applications.

Final Thought: Stick to the official react-router family for new work.

  • Use react-router-dom for web and react-router-native for mobile.
  • Avoid @reach/router to prevent future migration headaches.

How to Choose: react-router vs react-router-dom vs @reach/router vs react-router-native

  • react-router:

    Choose react-router only if you are building a custom routing environment or a library that needs to work across multiple platforms without binding to DOM or Native specifics. For standard application development, this package is usually a dependency of react-router-dom or react-router-native rather than a direct install target.

  • react-router-dom:

    Choose react-router-dom for any standard web application running in a browser. It includes all core routing features plus essential web components like BrowserRouter, Link, and NavLink. This is the default choice for 99% of React web projects and provides the best integration with browser history APIs.

  • @reach/router:

    Do not choose this package for new projects. It is officially deprecated and merged into react-router version 6. Using it introduces technical debt and limits access to modern features like data loading and improved hooks. Migrate existing projects to react-router-dom to ensure long-term maintenance and security.

  • react-router-native:

    Choose react-router-native when building mobile applications using React Native. It replaces web-specific components with mobile-friendly equivalents like NativeRouter and touch-optimized Link components. It ensures navigation feels natural on iOS and Android while sharing the same core logic as the web version.

README for react-router

react-router is the primary package in the React Router project.

Installation

npm i react-router