React on its own doesn't know what a URL is. It can render a page, but it has no concept of /about vs /settings vs /app/notes/42. A router is the piece that connects URLs to pages — and React Router is the most widely used one in the React ecosystem.
React Router started as a simple URL-to-component mapper, but it's grown into a full-stack framework. It now handles:
This means you don't need to glue together five separate libraries to build a real app. React Router handles the full stack in one cohesive package.
Next.js (by Vercel) is the other dominant React framework. It's a solid choice with a massive ecosystem. So why didn't we use it?
Stability. React Router has been around since 2014 and has maintained a consistent API philosophy. Next.js has gone through major architectural shifts — Pages Router to App Router, each with different patterns — that can confuse AI tools and produce mixed-generation code.
Simplicity. React Router's model is straightforward: a URL hits a route, the route loads data and renders a component. Next.js introduces more concepts — server components, client components, "use client" directives, caching layers — that add power but also complexity you don't need yet.
Portability. React Router apps deploy anywhere that runs Node.js. Next.js works best on Vercel's platform. You can deploy it elsewhere, but some features require extra configuration.
In your project, you won't see a list of route definitions in a config file. Instead, your file structure is your routing:
app/routes/
├── home.tsx → /
├── about.tsx → /about
└── app/
└── notes.tsx → /app/notes
This is handled by react-router-auto-routes, which reads your file tree and generates routes automatically. Add a file, get a page — no wiring needed.