The React Framework Question Has Three Real Answers Now
For years, "which React framework should I use?" had a one-word answer: Next.js. That era is over. In 2026, two serious competitors have matured enough to warrant consideration for production applications, and they bring genuinely different ideas about how a React app should be structured.
TanStack Start is Tanner Linsley's fullstack framework built on top of TanStack Router. It treats type safety as a first-class concern at every layer: routes, data loading, search params, and server functions all participate in a single TypeScript graph. It uses Vite under the hood, deploys anywhere Nitro can run, and integrates natively with TanStack Query for caching.
React Router v7 (the framework formerly known as Remix) merged Remix's server-first philosophy into the React Router project. If you used Remix before 2025, this is where it went. It gives you nested routes with colocated loaders and actions, progressive enhancement by default, and Vite-powered builds. It is the most "web standards" option of the three.
Next.js 15 remains the market leader. React Server Components, Server Actions, Turbopack, edge middleware, and the deepest ecosystem of any React framework. Vercel continues to push the boundaries of what a React app can do on the server.
We have shipped production apps on all three at Kanopy. Each one is excellent in a specific context and painful in the wrong one. This guide breaks down exactly where those boundaries fall so you can make a confident choice and move on to building your product.
Routing: Type-Safe vs File-Based vs Convention-Driven
Routing is the skeleton of your app, and these three frameworks have fundamentally different ideas about how it should work. The choice you make here shapes every page, every link, and every refactor you will do for the life of the project.
TanStack Start: Code-First, Type-Safe Routing
TanStack Router (which powers TanStack Start) takes an approach that feels unusual at first but becomes addictive quickly. You define routes in code using createFileRoute, and every route path, every search parameter, every path parameter is fully typed. If you rename a route segment, TypeScript errors light up in every <Link> component that references it. If you add a required search param, every link that omits it turns red in your editor before you even save the file.
Search params are treated as first-class citizens. You define their schema using Zod (or any validation library), and the framework parses and validates them automatically. This sounds minor until you build a complex filtering UI where the URL is the source of truth. In Next.js or React Router, search params are untyped strings you parse yourself. In TanStack Start, they are validated, typed, and serialized for you.
The tradeoff is verbosity. Route definitions require more boilerplate than dropping a file into a folder. The route tree is generated from your file structure but augmented with explicit type annotations. For teams that value type safety above all else, this is a feature. For teams that want to scaffold pages quickly, it can feel like friction.
React Router v7: Nested Routes with Loaders and Actions
React Router v7 uses file-based routing similar to what Remix popularized. You create files in a routes/ directory, and the file path maps to the URL. Nested layouts are handled by folder nesting, and each route can export a loader function (for reading data) and an action function (for mutations).
The mental model is clean: every URL maps to a file, every file can load its own data, and layouts compose automatically. React Router v7 also supports "flat routes" where you use dot-separated filenames (routes/projects.$id.tsx) instead of nested folders. This works surprisingly well for large apps where deep folder nesting becomes unwieldy.
Type safety exists but is not as deeply integrated as TanStack Start. Loader return types flow into your component props, but search params and path params require manual typing. The framework prioritizes web standards: loaders receive a standard Request object, actions return a standard Response, and forms use native HTML form submissions enhanced with JavaScript.
Next.js: The App Router
Next.js uses the App Router, where your folder structure inside app/ directly defines your routes. A file at app/dashboard/settings/page.tsx creates a route at /dashboard/settings. Layouts, loading states, error boundaries, and not-found pages all have reserved filenames (layout.tsx, loading.tsx, error.tsx, not-found.tsx).
This convention-driven approach is the most intuitive for newcomers. You do not need to understand any routing API to create your first page. The downside is that the App Router's conventions have multiplied over time: route groups (groupName), parallel routes @slot, intercepting routes (.)path, and dynamic segments [param] create a folder structure that can become difficult to navigate in large projects. We have seen Next.js apps with 50+ routes where the app/ directory is nearly impossible to scan visually.
Type safety for routes is minimal out of the box. Path params arrive as { params: Promise<{ id: string }> }, and search params are an untyped record. Libraries like next-safe-navigation exist to add validation, but they are aftermarket solutions, not built into the framework.
Data Loading: Where the Three Frameworks Diverge Most
How your framework loads data determines everything about your app's performance, your component architecture, and your developer experience. This is the area where the philosophical differences between these three frameworks become impossible to ignore.
TanStack Start: Server Functions + TanStack Query
TanStack Start uses server functions (defined with createServerFn) to run code on the server. These functions can access databases, call external APIs, read environment variables, and return typed data. On the client, you consume them through TanStack Query, which gives you automatic caching, background refetching, optimistic updates, and stale-while-revalidate behavior out of the box.
This is the killer feature. TanStack Query is arguably the best data-fetching library in the React ecosystem, and TanStack Start makes it a first-class integration rather than a bolted-on addition. Your server functions become query functions. Your mutations use useMutation with automatic cache invalidation. You get devtools that show every query's state, cache timing, and refetch behavior.
The data loading story also includes beforeLoad and loader hooks on each route, which run on the server during SSR and prefetch data before the component renders. These loaders are type-safe: the data they return flows directly into your component with full TypeScript inference.
React Router v7: Loaders, Actions, and the Web Platform
React Router v7 keeps Remix's loader/action pattern. Every route can export a loader that runs on the server before rendering and an action that handles form submissions. Data from loaders is available through useLoaderData() in the component.
The elegance here is simplicity. A loader is just an async function that receives a Request and returns data. An action is just an async function that receives a Request (from a form submission) and returns a Response. There is no special caching layer, no query client to configure, no devtools to install. You write a function, it runs on the server, you get the data.
The downside is that once you need client-side caching, background refetching, or optimistic updates, you are on your own. You can bolt on TanStack Query or SWR, but the integration is manual. React Router v7 does support clientLoader and clientAction for client-side data logic, and it handles revalidation after actions automatically. But it does not match TanStack Start's built-in caching sophistication.
Next.js: React Server Components and Server Actions
Next.js takes the most radical approach. With React Server Components, your components themselves are the data loading layer. A Server Component can await a database query directly in its body, and the rendered HTML ships to the client with zero JavaScript for that component. There is no loader function, no hook, no query client. The component is the query.
Server Actions handle mutations. You define an async function with 'use server' at the top, and it becomes callable from the client. Form submissions, button clicks, and programmatic calls all route through Server Actions, which run on the server and can revalidate cached data.
The power of this model is that data fetching disappears as a separate concern. You just write components that fetch what they need. The danger is that caching behavior is opaque. Next.js caches aggressively by default: the full route cache, the data cache, and the router cache all interact in ways that can produce stale data if you do not understand the invalidation rules. The community has pushed back on this, and Next.js 15 made caching opt-in rather than opt-out, which was a welcome change.
If you are evaluating Next.js more broadly, our Next.js vs React deep dive covers the full picture of what the framework gives you beyond data loading.
SSR, SSG, and Rendering Strategies
All three frameworks support server-side rendering, but they differ in how much control you get and how easy it is to mix rendering strategies within a single application.
TanStack Start
TanStack Start is SSR-first. Every request hits the server, runs your route loaders, renders the page, and streams HTML to the client. It uses Nitro as its server layer, which means it can deploy to Node.js, Cloudflare Workers, Deno, Bun, or any platform Nitro supports. Static generation is not a primary use case. If you need a statically generated marketing site, TanStack Start is not the right tool. It is designed for applications where every request benefits from fresh server-rendered data.
Streaming SSR works well. The framework supports Suspense boundaries, so above-the-fold content can ship immediately while slower data loads stream in afterward. This gives you fast initial paints without sacrificing data freshness.
React Router v7
React Router v7 supports SSR, static pre-rendering, and pure client-side rendering, and you can mix them per route. The ssr: false option on any route turns it into a client-only page. The prerender export lets you statically generate specific pages at build time. This flexibility is useful for apps that have a static marketing section and a dynamic authenticated section.
React Router v7 also supports streaming with defer() and Suspense, allowing you to send a shell immediately and stream in slower data. The framework handles the progressive enhancement story well: forms work without JavaScript, and links navigate with full page loads if JS fails. This makes it the most resilient option for users on flaky connections.
Next.js
Next.js offers the most rendering options of any React framework. You can mix static generation (generateStaticParams), server-side rendering, incremental static regeneration (ISR), and client-side rendering within a single application. ISR is particularly powerful: you statically generate a page at build time, then revalidate it on a timer or on-demand, combining the speed of static with the freshness of dynamic.
The App Router defaults to static rendering when possible. If your page has no dynamic data access, Next.js automatically renders it at build time. If it reads cookies, headers, or uses searchParams, it becomes dynamic. This automatic optimization is smart, but it can also be confusing when a page you expected to be static suddenly becomes dynamic because of a seemingly innocent code change.
Edge rendering is another differentiator. Next.js can run specific routes on Vercel's edge network, which gives you sub-50ms response times globally. TanStack Start can do this through Nitro's Cloudflare preset, and React Router v7 supports it through its Cloudflare adapter, but Next.js on Vercel is the most polished edge SSR experience available today.
Deployment Targets and Platform Independence
Where your framework can run matters more than most teams realize at the start of a project. Vendor lock-in is not just a theoretical concern. It directly affects your hosting costs, your scaling options, and your ability to switch providers when pricing changes.
TanStack Start: Nitro Makes It Truly Portable
TanStack Start's use of Nitro (the same server engine that powers Nuxt) is its deployment superpower. You write your app once and deploy to Node.js servers, Cloudflare Workers, Deno Deploy, AWS Lambda, Azure Functions, Netlify, Vercel, or a plain Docker container. Switching providers means changing a config line, not rewriting your server code.
This is not marketing fluff. We have deployed the same TanStack Start app to both Cloudflare Workers and a self-hosted Node.js server on Railway without changing a single line of application code. The Nitro layer abstracts away the platform differences. For teams that want to start on a managed platform and migrate to self-hosted infrastructure later, this flexibility is genuinely valuable.
React Router v7: Adapters for Every Platform
React Router v7 uses adapters to target different platforms. Official adapters exist for Cloudflare, Vercel, Netlify, and Node.js. The adapter model is clean: your application code stays the same, and the adapter handles platform-specific concerns like how requests enter your app and how responses leave it.
Self-hosting React Router v7 is straightforward. The Node.js adapter produces a standard Express-compatible server. You can run it in Docker, on a VPS, or on any container platform. There is no magic compilation step that ties you to a specific host. This was always Remix's strength, and React Router v7 inherits it fully.
Next.js: Best on Vercel, Possible Elsewhere
Next.js runs best on Vercel. That is not controversial; it is by design. Vercel builds Next.js, and the framework's most advanced features (ISR, edge middleware, image optimization, analytics, speed insights) work seamlessly on Vercel's infrastructure.
Running Next.js elsewhere is possible but comes with friction. The OpenNext project has made significant progress packaging Next.js for AWS (Lambda + CloudFront), and Cloudflare has invested in Next.js compatibility through their Workers adapter. But features like ISR, middleware, and image optimization may require workarounds or alternative implementations on non-Vercel platforms.
If you plan to stay on Vercel, this is a non-issue. Vercel is an excellent platform. But if your team needs to self-host for compliance reasons, cost control, or data residency requirements, the deployment story gets more complicated. Our framework comparison guide covers hosting cost differences in detail.
Bundle Size, Build Tooling, and Developer Experience
The day-to-day experience of working in a framework matters as much as its architectural merits. Build speed, hot module replacement, error messages, and tooling quality all compound over months of development.
Build Tooling
TanStack Start and React Router v7 both use Vite. This means sub-second hot module replacement, fast cold starts, and access to Vite's massive plugin ecosystem. If you have used Vite before, you know the experience. Changes appear in the browser almost instantly. The dev server starts in under a second. Build times for production are measured in single-digit seconds for most apps.
Next.js uses Turbopack, Vercel's Rust-based bundler that replaces Webpack. Turbopack has improved dramatically since its introduction and now delivers HMR speeds comparable to Vite for most projects. However, Vite's plugin ecosystem is significantly larger, and if you need a specific build transformation (custom SVG handling, MDX processing, Tailwind v4 integration), Vite plugins are more plentiful and better documented.
Bundle Size
For a comparable "hello world" fullstack app with one route and basic data loading:
- TanStack Start: ~45KB gzipped client bundle. Includes TanStack Router (~12KB) and TanStack Query (~14KB), plus React runtime.
- React Router v7: ~38KB gzipped client bundle. The router itself is lean (~8KB), and the rest is React runtime.
- Next.js: ~85KB gzipped client bundle. Includes the React runtime, the Next.js router, framework code, and the RSC runtime.
These baseline numbers matter less as your app grows, since your own code will eventually dominate the bundle. But for performance-sensitive applications where every kilobyte counts (mobile-first products, emerging market targets), the difference between 38KB and 85KB is noticeable on slow connections.
TypeScript Experience
TanStack Start is the clear winner here. Every route parameter, search parameter, loader return type, and server function argument is fully typed with zero manual annotation required. The TypeScript integration is so tight that some developers describe it as "the framework that makes TypeScript fun." If you want the full story on why TypeScript matters for projects like these, our TypeScript vs JavaScript guide covers the practical tradeoffs.
React Router v7 has solid TypeScript support. Loader and action types flow into components, and the Route.ComponentProps pattern keeps things clean. It is not as deeply inferred as TanStack Start, but it covers the critical paths.
Next.js has improved its TypeScript story significantly, but the App Router's dynamic params, async Server Components, and Server Actions introduce type patterns that feel awkward. Awaiting params and searchParams in every page component is verbose, and Server Action error handling requires manual type narrowing.
Error Messages and Debugging
Vite-based frameworks (TanStack Start and React Router v7) produce clear, source-mapped error messages that point to the exact line in your code. Next.js error messages have improved but can still be cryptic, especially around RSC boundaries. "This module cannot be imported from a Server Component" errors often require tracing through dependency chains to find the offending import.
Community, Ecosystem, and Long-Term Bets
Choosing a framework is a multi-year commitment. The technology matters, but so do the people behind it, the community around it, and the likelihood that it will still be actively maintained when you need to hire your next developer.
Next.js
Next.js has the largest community of any React framework by a wide margin. Vercel employs a large team of engineers dedicated to Next.js development. The npm download numbers, the number of production deployments, the volume of tutorials, courses, and Stack Overflow answers, none of the competitors come close. If you hire a React developer in 2026, there is a good chance they already know Next.js.
The ecosystem is equally strong. Authentication (NextAuth/Auth.js), CMS integration (Sanity, Contentful, Payload), e-commerce (Shopify Hydrogen on Next.js), and analytics (Vercel Analytics) all have first-party or deeply integrated Next.js support. You will rarely find a SaaS product or developer tool that does not offer a Next.js integration.
React Router v7
React Router has been a foundational React library for over a decade. The Shopify acquisition of Remix (now merged into React Router v7) gives it corporate backing and long-term financial stability. Shopify uses React Router v7 internally for customer-facing storefronts, which means the framework is battle-tested at enormous scale.
The community is smaller than Next.js but highly experienced. Developers who chose Remix tended to be web standards advocates who deeply understand HTTP, forms, and progressive enhancement. That knowledge base carries forward into React Router v7. Finding developers with Remix/React Router v7 experience is harder than finding Next.js developers, but those you find tend to be senior.
TanStack Start
TanStack Start is the newest of the three, and its community is the smallest. However, TanStack Router and TanStack Query individually have massive adoption. TanStack Query alone has over 40 million npm downloads per month. The developer behind it, Tanner Linsley, has a track record of building and maintaining widely-used open source libraries over many years.
The risk with TanStack Start is maturity. As of early 2026, it reached its 1.0 release, but the ecosystem of third-party integrations, starter templates, and tutorials is still growing. You will find fewer blog posts, fewer YouTube tutorials, and fewer Stack Overflow answers compared to Next.js. For experienced teams that are comfortable reading source code and working with newer tools, this is manageable. For teams that rely heavily on community resources, it could slow you down.
One advantage TanStack Start has: because it is built on Vite and Nitro, it benefits from the Vite ecosystem's growth. Every Vite plugin, every Nitro deployment preset, and every improvement to those underlying tools automatically benefits TanStack Start applications.
When to Pick Each Framework
After building production apps on all three, here is our honest recommendation for when each framework is the right call.
Pick TanStack Start When:
- Type safety is your highest priority. If your team writes strict TypeScript and wants every route, param, and server call to be fully typed without manual annotations, TanStack Start is unmatched.
- You already use TanStack Query. If your existing app uses TanStack Query and you want a framework that treats it as a first-class citizen rather than a third-party add-on, TanStack Start is the natural home.
- You need platform independence. Nitro's deployment flexibility means you can start on Cloudflare and move to AWS later without rewriting server code.
- You are building a data-heavy SaaS app. Complex filtering, search UIs, dashboards with many parameters in the URL: TanStack Start's type-safe search params and integrated caching shine here.
Pick React Router v7 When:
- Progressive enhancement matters. If your users are on unreliable connections, or if you need forms that work without JavaScript, React Router v7's web-standards approach is the most resilient.
- You are migrating from Remix. The migration path from Remix to React Router v7 is the smoothest upgrade in the React ecosystem. Most apps require only dependency changes and minor config updates.
- Your team values simplicity. The loader/action model is easy to understand, easy to teach, and produces predictable results. There is no caching magic, no opaque optimization, just functions that run on the server.
- You want the smallest bundle. React Router v7 has the leanest client runtime of the three. For mobile-first apps where every kilobyte matters, it wins.
Pick Next.js When:
- Ecosystem breadth matters most. If you need deep integrations with CMSs, authentication providers, analytics tools, and e-commerce platforms, Next.js has the most third-party support by far.
- You need ISR or advanced caching. Incremental Static Regeneration is a Next.js-exclusive feature (on Vercel) that no other framework replicates well. For content-heavy sites that need the speed of static with the freshness of dynamic, ISR is unbeatable.
- You are hiring junior developers. Next.js has the most learning resources, the most tutorials, and the most developers with existing experience. Onboarding is faster.
- Vercel is your deployment target. If you plan to deploy on Vercel and want the smoothest possible experience, Next.js is the obvious choice. The framework and the platform are co-designed.
Our Default at Kanopy
For client projects in 2026, our default recommendation is still Next.js for most startups and businesses. The ecosystem maturity, the hiring pool, and the deployment story on Vercel make it the safest bet. But we are increasingly reaching for TanStack Start on projects where type safety and data complexity are primary concerns, and React Router v7 for projects where progressive enhancement and platform independence are non-negotiable.
The good news is that all three frameworks use React, so your component library, your design system, and most of your UI code will transfer between them. The framework choice primarily affects your routing, data loading, and deployment patterns.
If you are trying to decide which framework fits your specific project, we can help. Book a free strategy call and we will walk through your requirements, timeline, and team constraints to recommend the right stack for your situation.
Need help building this?
Our team has launched 50+ products for startups and ambitious brands. Let's talk about your project.