The great React framework divide
Committing to a React framework is often a one-way door decision that shapes your entire development experience.
Table of content
- React is just one piece of the puzzle
- The Framework's promise
- What makes a framework good?
- The Next.js approach
- The alternative: modular toolchains & meta frameworks
- So which framework should you choose?
- First, define your intentions
- Analyze your starting point
- Quantify the switching cost
- Define success metrics
- Conclusion
I'm having a hard time understanding teams choosing Next.js today. Don't get me wrong, Next.js allows big e-commerce websites and brands to ship web experiences faster with a lot of concerns built-in (think of server-side rendering, routing, bundling).
But committing to a framework is most of the time a one-way door decision that isn’t easy to revert: you're locked into Vercel's vision of how React applications should be built, for better or worse.
While the React & frontend ecosystem in general are intimidating, we're seeing the emergence of meta frameworks & unified toolchains that have an interesting value proposition compared to Next.js: flexibility.
React is just one piece of the puzzle
Let's start with a fundamental truth: React only handles components and render lifecycle. That's it. It's a UI library, not a complete solution for building modern web applications. In fact, as of February 2025, the React team officially sunset Create React App and now explicitly recommends using a framework. This isn't a suggestion, it's an acknowledgment that React alone isn't enough.
Building a real user interface requires far more than just rendering components:
- Bundling — Efficiently load your assets & optimize performance for users.
- Routing — Fundamental to any multi-page application. Nested routes, route parameters, protected routes, search params, loading states, the decisions multiply quickly.
- Data fetching — Requires managing caching strategies, request deduplication, error handling, loading states, and optimistic updates.
- Forms — Deceptively complex. You need validation, error handling, submission states, field dependencies, and proper accessibility attributes.
- Accessibility — No longer optional. Keyboard navigation, focus management, screen reader compatibility, and ARIA attributes are must-haves.
- Internationalization — Means more than just translating strings. You need pluralization rules, date formatting, currency, right-to-left languages, and dynamic content loading based on locale.
The Framework's promise
This is where frameworks come in. A framework establishes conventions and rules that make sense of this complexity. It provides a structured path forward so you're not reinventing the wheel with every new feature.
Most companies end up in one of the following situations:
- They adopt an open-source framework like Next.js, which provides answers to questions they would otherwise have to solve themselves.
- They build their application from a set of tools they find best for the job or are familiar with, ending up with their own custom framework.
Both approaches have pros & cons, but I’d like to emphasize a few questions you should ask yourself whatever course you decide to take:
Choosing an open source framework
- Is the framework built or explicitly supports the type of application you’re building?
- How extensible is the framework?
- Looking at historical releases, do you feel like the framework is moving in the right direction?
Building your own custom framework
- Do you have enough resources internally to maintain your custom solution?
- Do you still make active decisions on the direction of your framework?
- As opposed to an open source alternative, can you justify aspects on which your custom solution brings extra value to users?
What makes a framework good?
Not all frameworks are created equal. The difference between a framework that accelerates your team and one that becomes a burden comes down to a few key factors.
Developer experience
- What’s the learning curve like? Do developers have access to extensive resources (guides, API reference, release notes)? Does the tooling make them faster or slow them down? Developers need to feel like the framework is empowering them to do great things.
Philosophy
- How much guidance or flexibility does the framework provide? Is the preferred way to do things the only way when faced with a unique problem? The best frameworks reduce cognitive load by providing sensible defaults but vary in terms of how opinionated they are. It’s important to know how your project fits into this picture of how things should be done.
Ecosystem
- What is the governance of this framework? Does a single company determines its future or is a foundation behind it? What’s the track record like in terms of breaking changes, major versions, etc. Does the framework expose some APIs to extend it?
While all three matter, developer experience often determines success in the first 6 months. A framework with poor DX stalls adoption regardless of other strengths.
The Next.js approach
Next.js has been around since 2016. It represents the integrated framework philosophy, a cohesive ecosystem where everything is intertwined: routing, rendering, data fetching & deployment all work together.
The core philosophy is about reducing decision fatigue. Instead of choosing between a dozen routing libraries, you use Next.js's file-based routing. Instead of debating SSR strategies, you use their rendering patterns.
The framework emphasizes server-side rendering to show content to users as quickly as possible while maintaining SEO optimization. This makes Next.js particularly strong for e-commerce sites, marketing pages, and content-heavy applications where initial loading time is critical.
Next.js is very opinionated. You work within the boundaries it sets, but in return, you get a proven path to production. The framework comes with solutions to many needs right out of the box:
- Routing is file-based. You either use the pages or app router & need to organize your files in a specific way to create new routes.
- Data fetching is either done using special functions like
getServerSidePropswith the pages router or throughfetchcalls in React server components, even if client-side solutions like TanStack Query or SWR can work based on your rendering strategy. - Code-splitting is built in. You can use
next/dynamicbut Next.js mostly take care of that concern for you. - Server components & rendering patterns to offload some work on the server & make initial loading time faster with server components & custom directives like
'use cache'.
The power of Next.js comes from how you use these primitives, not from changing the primitives themselves. You're not meant to swap out the router or fundamentally alter the rendering pipeline. You're meant to master the tools provided.
Cognitive load in Next.js is initially high but lower long-term once your team has internalized the patterns. Understanding the difference between server and client components or navigating the differences between the App Router and Pages Router requires significant upfront learning. But once that knowledge is established, developers can move quickly because the patterns are consistent.
Next.js offers some form of customization through next.config.js or proxy.ts but you’ll mostly need to follow conventions. For example, you cannot change the chunking strategy.
Adopting Next.js is rarely an incremental process for existing applications. You can try to migrate piece by piece, building a new Next.js app that handles some routes while redirecting to your old app for others, but you're essentially running two applications in parallel. The all-in approach is often cleaner: commit to the migration, accept the short-term pain, and emerge with a fully Next.js application.
The alternative: modular toolchains & meta frameworks
The frontend ecosystem has seen the emergence of unified toolchains like Vite & so-called meta frameworks like Astro for content-focused websites or React Router with its framework mode.
Paired together, they offer flexible foundations letting you layer in exactly the tools you need. This modular approach means each architectural decision remains reversible: you're assembling a stack that evolves with your needs.
TanStack is a great example of that. Rather than an integrated framework, it's a collection of powerful, independent tools. TanStack Query handles data fetching and caching. TanStack Router provides type-safe routing. TanStack Form manages form state. TanStack Start is the meta-framework that can bundle these together, but each piece works independently.
You start with a single-page application architecture with optional server-side rendering capabilities. Most teams begin with TanStack Query because it solves data fetching so elegantly. Then, if you need better routing, you add TanStack Router. Need sophisticated form handling? Add TanStack Form. Each library integrates cleanly, but you're never forced to use all of them.
There's no single, overarching "TanStack way" you must learn upfront. You learn as you go, adopting concepts as you adopt the libraries. This reduces initial cognitive load and gives you the flexibility to use other tools where it makes sense. Don't like TanStack Form? Use React Hook Form instead. Need a different routing solution? That's fine too.
The trade-off is that you make more decisions. You're responsible for ensuring these pieces work together harmoniously. You need to establish conventions for your team. The framework provides excellent tools but doesn't prescribe the complete architecture.
So which framework should you choose?
I’ll go with the usual “It depends”, because it’s impossible to come up with one universal answer. As we’ve seen, adopting a framework can be a decision which is hard to revert. Like any technical project, it’s important to ground your decision in your context.
First, define your intentions
- What type of application are you building? A data-heavy B2B SaaS has different needs than an e-commerce website or a marketing landing page.
- How will server rendering help you? Beyond performance optimizations like CDNs, caching, and code-splitting, is SEO your main priority, or are you building an authenticated application where SEO doesn't matter?
- How sensitive are you to vendor lock-in? Do you prefer the flexibility of choosing the best tool for each job, or do you value the simplicity of following what the framework prescribes?
- What's your team's appetite for learning? Does your team thrive with opinionated guidance, or do they prefer autonomy and flexibility?
Analyze your starting point
- Are you building from scratch or migrating? New application from scratch or migrating an existing one?
- How much technical debt can you tolerate? Framework migrations have real costs in productivity and bug surface area.
- What expertise does your team have? Do you already have strong opinions or needs on specific technical areas?
- What are your long-term maintenance expectations?
- Do you have in-house infrastructure and DevOps capability? Integrated frameworks like Next.js abstract deployment concerns; flexible tool collections require more operational knowledge (bundling config, server setup, monitoring).
Quantify the switching cost
- What libraries or patterns is your team already invested in? TanStack plays better with existing React Hook Form, SWR, or other point solutions you may already use.
- How reversible is this decision? Can you prototype the framework choice before committing the entire product?
Define success metrics
- What does success look like? Ship speed? Developer satisfaction? Maintenance burden? Different frameworks optimize for different outcomes.
- How will you measure framework fit 6 months in? Establish baseline metrics (time-to-feature, bug rates, developer sentiment) to validate your choice wasn't just theoretically sound.
Conclusion
Choosing a framework for your React application is all about aligning your technical choice with your team's constraints, your application's requirements and your organization's tolerance for complexity.
Next.js succeeds when you want to move fast within guardrails. Its opinionated approach eliminates decision fatigue and provides a proven path to production. You trade flexibility for velocity. This works for e-commerce sites, marketing applications, and content-heavy platforms. The cost is commitment: reversing that decision is painful.
Meta frameworks like TanStack succeeds when you need flexibility and already have strong opinions. It provides excellent tools but trusts you to make architectural decisions. You own more of the burden, but also more of the potential.
Neither approach is wrong. Start by prototyping a small feature before committing the entire product. Measure developer experience and maintenance burden over time.
The framework landscape will continue evolving. Rather than seeking the "permanent" choice, build your decision-making process to periodically reassess.