Next.js vs TanStack Start vs Furin
Choose these frameworks by architecture and constraints, not by a universal performance ranking. Next.js offers the broadest integrated React platform, TanStack Start is router-first and deeply type-safe, and Furin is the compact Bun/Elysia option.
Reviewed September 10, 2026. Next.js here means the current App Router. TanStack Start's official docs still label it Release Candidate. Furin refers to the
0.7alpha line in this repository.
At A Glance
| Next.js | TanStack Start | Furin | |
|---|---|---|---|
| Maturity | Stable, widely deployed | Release Candidate | Alpha |
| Primary runtime | Node.js and supported platform runtimes | Adapter-dependent | Bun only |
| Dev/build engine | Turbopack by default | Vite or Rsbuild | Bun full-stack dev server and bundler |
| HTTP model | Next.js runtime and Route Handlers | Start server routes/functions | Elysia plugins and routes |
| Routing center | App Router and React Server Components | TanStack Router | File routes compiled into Elysia |
| Rendering | App Router static/dynamic/streaming model | Full-document SSR and prerendering | Explicit SSR, SSG, or ISR per route |
| Best fit | Full React platform and ecosystem | Router/search/data type safety | Bun/Elysia teams wanting one process |
No neutral benchmark currently compares the same application, route graph, machine, and edit sequence across all three. Furin should not claim a speed winner until those reproducible results exist.
Development Architecture
Next.js
Next.js owns an integrated compiler and runtime graph. Turbopack is the default development and build engine, supports Fast Refresh, performs lazy work, and can persist compiler artifacts. The developer runs one framework server even though the framework manages several execution environments.
TanStack Start
TanStack Start builds on TanStack Router and delegates bundling and HMR to Vite or Rsbuild. That gives it mature plugin ecosystems, established React Fast Refresh integrations, and a public invalidation lifecycle.
Furin
Furin runs Elysia HTTP handling, API plugins, SSR, route discovery, and Bun's browser bundler in one Bun process and on one origin. Client and server still have different module graphs and transforms; the accurate promise is one runtime and one process, not one identical graph.
Furin adds framework-specific coherence around Bun HMR: versioned SSR imports, live route topology, loader invalidation, stable React boundaries, an error overlay, and route/cache DevTools. See Development HMR Internals.
HMR And Diagnostics
| Dimension | Next.js | TanStack Start | Furin |
|---|---|---|---|
| React state | Mature Fast Refresh rules | React Fast Refresh through Vite/Rsbuild | Preserved for compatible page/layout edits covered by browser tests |
| Server edits | Integrated Server Component refresh | Toolchain/server-function integration | Fresh versioned SSR imports and route-data refresh |
| Route add/remove | Integrated App Router graph | Generated file-route tree | Live filesystem rescan and generated route refresh |
| Error UI | Mature framework overlay | Mature toolchain overlay | Phase-aware overlay for transform, import, loader, render, hydration, and client render |
| Persistent graph cache | Turbopack filesystem cache | Toolchain dependency caches | No comparable cross-restart cache yet |
| Current gaps | Framework-specific edge cases | Depends on Vite/Rsbuild integration | Five executable TODOs around unloaded dynamic imports, missing/restored imports, CSS pruning, and CSS Module values |
Furin's real-browser suite covers pages, layouts, re-exports, cycles, rapid edits, stale loader rejection, route topology, multiple tabs, reconnects, SSR/SSG/ISR, deferred data, composite server markup, and overlay recovery. Its main architectural compromise is that code and refreshed loader data arrive as two updates, so a component may briefly see the previous payload.
Routing And Types
| Dimension | Next.js | TanStack Start | Furin |
|---|---|---|---|
| Route definition | Files and special App Router conventions | Generated or code-based route tree | Files plus an explicit defineRoute(id) chain, keyed by the file |
| Typed destinations | Optional generated typed routes | Strong typed to, params, and search | Generated autocomplete; known paths infer params/search, with a string escape hatch |
| Search state | Application-defined parsing | First-class validated search state | TypeBox runtime schemas plus useSearch() |
| Loader inference | Generated route props and component conventions | Route tree and loader APIs | Parent loader promises flow through the route builder |
| Advanced routing | Groups, parallel routes, intercepting routes | Rich router composition | Nested layouts and catch-alls; no parallel/intercepting route conventions |
TanStack Start is the strongest fit when typed search state and router composition are the center of the application. Furin is strongest when the same TypeBox/Elysia model should validate both page inputs and HTTP APIs. Next.js provides more routing conventions and generated route-aware types than a simple “string routes” description suggests.
Data And Mutations
Next.js
The App Router centers React Server Components, fetch, Cache Components, Server Actions, and Route Handlers. Its caching system can operate at several layers and supports time- and tag/path-based revalidation.
TanStack Start
Route loaders coordinate navigation data, while Server Functions and TanStack Query provide typed server calls and client cache workflows. It is a natural choice when an application already standardizes on the TanStack data stack.
Furin
Public loaders are server-only and serialized into page responses. Layout loaders start in parallel and expose ancestor fields as promises. requestLoader() isolates cookies/headers from cached public data; defer() streams selected SSR fields.
Mutations remain ordinary Elysia routes, usually called through Eden Treaty. Furin Sync optionally adds idempotent replay and an ordered invalidation journal. It does not introduce Server Actions or pretend that external domain writes are automatically atomic.
Caching And Deployment
| Dimension | Next.js | TanStack Start | Furin |
|---|---|---|---|
| Static output | Built in | Prerendering support | SSG-only static exporter |
| Incremental content | Framework caching and revalidation | Application/adapter strategy | Built-in ISR with memory or Redis page cache and path/tag invalidation |
| Personalization | Dynamic APIs and component boundaries | Server functions/loaders | SSR or requestLoader() beside cached public data |
| Main deployment story | Vercel and self-hosting | Adapter ecosystem | Vercel, Bun server, Bun executable, static files |
| Composable artifact | Framework/application deployment | Adapter-dependent | Packaged Furin app as an Elysia plugin |
Furin uses an instance-local memory page cache by default and supports a Redis adapter for shared SSG, ISR, and PPR artifacts across Bun replicas. Distributed regeneration leases reduce duplicate work, while fenced writes prevent stale publication after invalidation or lease takeover. Sync remains responsible for browser invalidations, while setCachePurger() handles an upstream CDN. The Vercel target delegates public SSG/ISR pages and PPR shells to Vercel's native cache, then resumes private PPR content in a Function. Coherent public PPR artifacts also use Runtime Cache for origin rendering and navigation. Node.js and Cloudflare build targets remain planned.
React Server Components
Next.js uses React Server Components as the App Router's core rendering model. TanStack Start documents RSC support separately from its standard full-document SSR path. Furin exposes an explicit composite server-markup transport as a loader value, with browser slots for interactivity.
Furin's API is intentionally narrower: it is not the Next.js RSC programming model and does not include React Server Functions or Server Actions.
Recommendation
Choose Next.js when:
- RSC, Server Actions, advanced App Router conventions, or the largest ecosystem are requirements.
- You want the most mature integrated compiler, deployment, and troubleshooting story.
Choose TanStack Start when:
- The router, typed search state, and TanStack Query are architectural foundations.
- Vite/Rsbuild portability and their plugin ecosystems matter.
Choose Furin when:
- Bun and Elysia are deliberate constraints.
- Pages, APIs, SSR, and development updates should live in one compact process.
- Explicit route rendering modes and Elysia/TypeBox inference fit the team's mental model.
- Alpha maturity, Bun-only deployment, and the documented HMR/cache limitations are acceptable.
The recommended direction for Furin is to keep the Bun-native architecture. Replacing it with Vite would close some HMR gaps quickly but create two development architectures and erase its clearest distinction. The higher-value path is stronger browser conformance, persistent graph performance work, and broader deployment-adapter coverage.
Next.js has the broadest integrated cache revalidation API. TanStack Start emphasizes typed same-origin Server Functions and deliberate client-cache integration. Furin keeps standard HTTP routes as the public mutation contract and adds an optional durable replay/change journal around them. For multi-replica production, PostgreSQL is the recommended source of truth and native LISTEN/NOTIFY wake-up path; Redis remains an optional independent notifier.
Primary Sources
- Next.js: project structure, data fetching, linking and navigation, Fast Refresh, and revalidation
- TanStack: Start overview, file-based routing, and data loading
- Runtime/tooling: Elysia plugins and scope, Bun full-stack development, and Bun hot reloading