Over the past few years, our platform evolved from a fast-moving startup stack into a performance- and infrastructure-sensitive system.
We started with Next.js — like many teams do. It’s powerful, mature, and incredibly productive.
But as our requirements grew more specific, we increasingly felt constrained by framework assumptions around rendering, deployment, and infrastructure.
Eventually, we made the switch to React Router 7.
Here’s why — and what changed for us.
1. We Use React Server Components — Without Traditional Page SSR
Leaving Next.js doesn’t mean abandoning advanced rendering.
With React Router 7, we use React Server Components (RSC) — but without being tied to a page-based SSR architecture.
What this gives us:
- Server-rendered components where it makes sense
- Streaming support
- Reduced client hydration overhead
- More granular server/client boundaries
Traditional SSR often means rendering entire pages on the server and hydrating everything on the client.
With RSC and React Router’s data APIs, we can be more surgical.
In practice, this improved client performance because we reduced unnecessary hydration and shipped less JavaScript to the browser.
Next.js gives you powerful defaults.
React Router gives you explicit control.
At our scale, explicit control wins.
2. True Middleware Patterns — Fully Integrated
A common assumption is that Next.js has “real” middleware while React Router does not.
That’s outdated.
React Router 7 provides fully integrated request handling via:
loadersactions- standard
Request/Responseobjects - nested route data APIs
These patterns allow:
- Authentication guards
- Geo-based logic
- Logging and observability
- Access control
- Request transformations
Because everything is route-scoped and explicit, it’s easier to reason about.
We don’t rely on edge-only middleware or special folder conventions. We write standard request logic in predictable places.
In practice, this feels cleaner and more composable.
3. SPA Mode — When We Need It
Another major advantage: React Router 7 allows us to run certain parts of our system in pure SPA mode.
This is extremely useful for:
- Internal dashboards
- Admin tools
- Authenticated application areas
- Feature-heavy UI sections
We can:
- Disable server rendering where it’s not needed
- Ship static assets
- Optimize purely for client interactivity
With Next.js, the architecture is always SSR-first (even when using client components heavily).
React Router gives us freedom:
We can choose SSR, RSC, streaming, or pure SPA — per application or even per route.
That flexibility matters.
4. We Recommend Using Framework Mode
One important note: we strongly recommend using React Router 7 in Framework Mode.
While React Router can be used as a minimal routing library, Framework Mode unlocks its full potential:
- Built-in data loading patterns
- Integrated server handling
- Structured routing conventions
- Production-ready architecture out of the box
It removes a lot of boilerplate and architectural decisions you would otherwise have to reinvent.
At the same time, it doesn’t lock you into rigid conventions. The system remains highly adjustable:
- You control hosting
- You control rendering strategy
- You control deployment targets
- You control infrastructure
For us, Framework Mode hits the perfect balance:
Less repetitive setup work —
but still full architectural sovereignty.
5. It’s Lightweight — In Dev and Production
Next.js is a full-stack meta-framework.
React Router is a routing and data orchestration layer.
That difference shows in bundle size and runtime complexity.
What we observed after migrating:
- Smaller production bundles
- Less framework runtime logic
- Cleaner dependency graph
- Faster CI builds
There’s simply less abstraction between us and React.
6. Faster Dev Environment
We use Vite for development, which significantly improved:
- Cold start times
- HMR speed
- Debug clarity
One honest note:
Vite does not fully tree-shake in development mode.
Some of our dev pages can grow large (we’ve seen ~15MB), especially when using icon libraries.
However:
- This only affects development
- Production builds are optimized correctly
Overall, the dev feedback loop is still faster and more transparent than before.
7. Faster Bugfix Turnaround
From our experience:
React Router maintainers respond quickly — often within days from issue report to fix.
With larger frameworks like Next.js, turnaround can take weeks or longer. This is understandable given project size and ecosystem scope.
But when your business depends on framework stability, responsiveness matters.
Smaller, focused projects often move faster.
8. Self-Hosting & Geo Clustering
We host and geo-cluster our infrastructure ourselves.
We require:
- Custom regional routing
- Infrastructure-level SEO optimization
- Strict data control
- Full observability
- Predictable scaling costs
Next.js increasingly assumes Vercel as the optimal deployment target.
React Router makes zero assumptions about hosting.
We can:
- Run on Node
- Deploy to edge runtimes
- Use containers
- Geo-cluster however we want
No vendor lock-in.
No deployment pressure.
No hidden coupling.
That independence is extremely valuable.
9. Clearer Mental Model
This might be subjective — but important.
With React Router:
- What we write is what runs.
- There’s less invisible framework behavior.
- Routing and data are explicit.
In large systems, clarity beats convenience.
10. What Next.js Still Does Well
To be fair, Next.js is excellent at:
- Quick startup productivity
- Batteries-included defaults
- Strong ecosystem adoption
- Opinionated structure for smaller teams
For many projects, it’s absolutely the right choice.
But once you need architectural sovereignty, the trade-offs become more noticeable.
Why We Switched
Our platform operates in:
- SEO-sensitive environments
- Performance-critical markets
- Privacy-sensitive domains
- Regionally distributed infrastructure
We needed:
- Rendering flexibility (RSC + SPA)
- Integrated middleware control
- Hosting independence
- Lightweight runtime
- Faster iteration cycles
React Router 7 gave us exactly that.
Final Thoughts
Switching frameworks is never trivial.
But sometimes growth forces you to reconsider architectural constraints.
For us, moving from Next.js to React Router 7 wasn’t about hype.
It was about:
Control.
Clarity.
Independence.
And so far, we’re very happy with the decision.
Top comments (0)