title: Comparison
category: Features
order: 99
import Link from "../../../../components/Link.jsx";
Comparison
This table compares @lazarv/react-server against other popular React frameworks and routing solutions. The comparison covers full-stack features, architecture, routing, type safety, search params, scroll restoration, and developer experience.
This comparison summarizes the feature set described in the documentation. It focuses on first-class, built-in support rather than custom userland solutions. Some rows describe core architecture, others cover convenience or router ergonomics, so the table should be read as a map of tradeoffs, not a single score.
This comparison is maintained by the @lazarv/react-server team. If you find an inaccuracy, please open an issue β we want this to be fair and factual.
Legend:
- β
β First-class, built-in support that is documented and part of the frameworkβs intended model
- π‘ β Partial support, important limitations, or support that exists only in a narrower subset of use cases
- πΆ β Possible through userland composition, community plugins, or manual setup, but not a first-class built-in feature
- π β No meaningful built-in support
<Link name="full-stack">
## Full-stack features
</Link>
|
@lazarv/react-server |
Next.js |
TanStack Start |
React Router |
Waku |
| React Server Components |
β
|
β
|
π |
π‘ |
β
|
| Server Functions (actions) |
β
|
β
|
β
|
π‘ |
β
|
| SSR |
β
|
β
|
β
|
β
|
β
|
| Streaming SSR |
β
|
β
|
β
|
β
|
β
|
| API Routes |
β
|
β
|
β
|
β
|
β
|
| API / Route Middleware |
β
|
β
|
β
|
β
|
π‘ |
| Server Function Middleware |
π‘ |
π |
β
|
π |
π |
| Static Site Generation |
β
|
β
|
π‘ |
π‘ |
β
|
| Partial Pre-rendering (PPR) |
β
|
β
|
π |
π |
π |
| Response Caching (TTL) |
β
|
β
|
π |
π |
π |
| Redirects (server) |
β
|
β
|
β
|
β
|
π‘ |
| Rewrites (server) |
β
|
β
|
π |
π |
π |
| Reload / Invalidation |
β
|
β
|
β
|
β
|
π |
<Link name="architecture">
## Architecture
</Link>
|
@lazarv/react-server |
Next.js |
TanStack Start |
React Router |
Waku |
| Open Runtime (no vendor lock-in) |
β
|
π‘ <br/> optimized for Vercel |
β
|
β
|
β
|
| Vite-based |
β
|
π |
β
|
β
|
β
|
| Multiple Deploy Targets |
β
|
π‘ |
β
|
β
|
β
|
| Micro-frontend / Remote Components |
β
|
πΆ |
π |
π |
π |
| MCP Server Integration |
β
|
π |
π |
π |
π |
| Worker / Multi-threaded Rendering |
β
|
π |
π |
π |
π |
| Cluster Mode |
β
|
π |
π |
π |
π |
| Adapter-based Deployment |
β
|
π‘ |
β
|
β
|
β
|
<Link name="routing">
## Routing
</Link>
|
@lazarv/react-server |
Next.js |
TanStack Router |
React Router |
Waku |
| Nested / Layout Routes |
β
|
β
|
β
|
β
|
β
|
| Code-based Routes |
β
|
π |
β
|
β
|
π |
| File-based Routes |
β
|
β
|
β
|
β
|
β
|
| Virtual / Programmatic Routes |
β
|
π |
β
|
β
|
π |
| Ranked Route Matching |
β
|
β
|
β
|
β
|
π |
| Suspense Route Transitions |
β
|
β
|
β
|
β
|
π‘ |
| Suspense Route Elements |
β
|
β
|
β
|
β
|
π‘ |
| Error Boundary Elements |
β
|
β
|
β
|
β
|
β
|
| Loading / Pending Elements |
β
|
β
|
β
|
β
|
π‘ |
| Client-only Routes |
β
|
π |
β
|
β
|
π |
| Parallel Routes / Outlets |
β
|
β
|
π |
π |
π‘ |
| Route Prefetching |
β
|
β
|
β
|
β
|
π‘ |
| Automatic Prefetching |
β
|
β
|
β
|
β
|
π |
| Active Link Customization |
β
|
β
|
β
|
β
|
π |
| Navigation Guards / Blocker |
β
|
π |
β
|
π‘ |
π |
<Form> Component |
β
|
β
|
π |
β
|
π |
| Deferred / Streaming Primitives |
β
|
β
|
β
|
β
|
π‘ |
<Link name="type-safety">
## Type safety
</Link>
|
@lazarv/react-server |
Next.js |
TanStack Router |
React Router |
Waku |
| Typesafe Route Paths |
β
|
π‘ |
β
|
π‘ |
π |
| Typesafe Path Params |
β
|
π |
β
|
β
|
π‘ |
| Typesafe Navigation |
β
|
π‘ |
β
|
π‘ |
π |
| Typesafe Search Params |
β
|
π |
β
|
π |
π |
| Path Param Validation |
β
|
π |
β
|
π |
π |
| Path Param Coercion / Parsing |
β
|
π |
β
|
π |
π |
| Typed Link Components |
β
|
π |
β
|
π |
π |
| Typed Hooks (useParams, useSearchParams) |
β
|
π |
β
|
π‘ |
π |
| Auto-generated Route Types (file-router) |
β
|
π‘ |
β
|
π |
π |
| Branded Outlet Types |
β
|
π |
π |
π |
π |
| Multi-library Schema Support (Zod, ArkType, Valibot) |
β
|
π |
π‘ |
π |
π |
| Lightweight Parse Functions (no schema library) |
β
|
π |
π |
π |
π |
<Link name="search-params">
## Search params
</Link>
|
@lazarv/react-server |
Next.js |
TanStack Router |
React Router |
Waku |
| Basic Search Params |
β
|
β
|
β
|
β
|
π‘ |
| Search Param Hooks |
β
|
β
|
β
|
β
|
π |
| Typed Search Params |
β
|
π |
β
|
π |
π |
| Search Param Schema Validation |
β
|
π |
β
|
π |
π |
<Link> / useNavigate Search API (object, not string) |
β
|
π‘ |
β
|
π‘ |
π |
Functional Search Updaters (prev => next) |
β
|
π |
β
|
π |
π |
| Search Param Transforms (encode/decode boundary) |
β
|
π |
β
|
π |
π |
| Route-scoped Search Transforms |
β
|
π |
π |
π |
π |
| Custom Search Parsing/Serialization |
β
|
π |
β
|
πΆ |
π |
<Link name="scroll-restoration-comparison">
## Scroll restoration
</Link>
|
@lazarv/react-server |
Next.js |
TanStack Router |
React Router |
Waku |
| Window Scroll Restoration |
β
|
π‘ |
β
|
β
|
π‘ |
| Element / Container Scroll Restoration |
β
|
π |
β
|
π |
π |
| Async Content Scroll Restoration |
β
|
π |
β
|
π |
π |
| Per-route Scroll Customization |
β
|
π |
π‘ |
π |
π |
| Zero-flash Restoration (pre-hydration script) |
β
|
π |
π |
π |
π |
prefers-reduced-motion Aware |
β
|
π |
π |
π |
π |
| Hash / Anchor Scrolling |
β
|
β
|
β
|
β
|
π |
| Config-level Enable (zero code) |
β
|
π |
π |
π |
π |
| Query-only Changes Preserve Scroll |
β
|
π |
π‘ |
π |
π |
<Link name="data-fetching">
## Data fetching & resources
</Link>
|
@lazarv/react-server |
Next.js |
TanStack Router |
React Router |
Waku |
| Typed Resource Descriptors |
β
|
π |
π |
π |
π |
| Schema-validated Resource Keys |
β
|
π |
π‘ |
π |
π |
Suspense-integrated .use() Hook |
β
|
π |
β
|
π‘ |
π |
| Resource Invalidation (per-key) |
β
|
π‘ |
β
|
π |
π |
| Resource Collections |
β
|
π |
π |
π |
π |
| Route-Resource Binding (prefetch) |
β
|
π |
β
|
β
|
π |
| Router Loaders (data fetching) |
β
<br/> RSC + resources |
π‘ |
β
|
β
|
π‘ |
| SWR / Stale-While-Revalidate Caching |
β
<br/> "use cache" |
β
|
β
|
π |
π |
| Server & Client Loaders |
β
|
π‘ |
β
|
β
|
π |
<Link name="developer-experience">
## Developer experience
</Link>
|
@lazarv/react-server |
Next.js |
TanStack Router |
React Router |
Waku |
| Zero-config File Router |
β
|
β
|
π‘ |
π‘ |
β
|
| MDX Pages |
β
|
πΆ |
π |
π |
π |
| Virtual Routes Module |
β
|
π |
π‘ |
π‘ |
π |
| Route-scoped Loading / Error / Fallback Files |
β
|
β
|
π |
π |
π |
| Devtools |
β
|
π |
β
<br/> router only |
π‘ |
π |
| Route Masking |
π |
π |
β
|
π |
π |
| Route-level Typed Dependencies |
β
<br/> Typesafe resources |
π |
β
<br/> Typesafe route context + loaders |
π |
π |
| Route Mount / Unmount Events |
π |
π |
β
|
π |
π |
<Link name="notes">
## Notes
</Link>
@lazarv/react-server is a full React Server Components runtime β not just a router. The routing system is deeply integrated with RSC streaming, server functions, and the Vite build pipeline. This means features like typed routes, client-only routes, and server-side validation work end-to-end without glue code.
Key architectural differences
- RSC-native: Unlike routers that bolt RSC support on top,
@lazarv/react-server was built from the ground up for React Server Components. Every route can mix server and client components freely.
- Client-only routes: Pages with
"use client" in the file-system router are automatically client-only β navigation skips the server entirely. No configuration needed, and component state is preserved across navigations via React's <Activity> component.
- Schema-agnostic validation: Route params and search params can be validated with any schema library (Zod, ArkType, Valibot) or lightweight parse functions β the runtime detects the validation strategy automatically.
- RSC + typed resources:
@lazarv/react-server offers two complementary data-fetching approaches: React Server Components with async/await (RSC as loaders), and typed resources β schema-validated, reference-identified data descriptors with .use() (suspense), .query() (imperative), .prefetch(), and .invalidate(). Resources use "use cache" as the caching runtime β no custom cache layer, no SWR boilerplate. Route-resource bindings enable parallel prefetching on navigation.
- Route-level dependencies: TanStack Router exposes route context as a first-class typed primitive for passing dependencies (auth, DB clients, etc.) down the route tree.
@lazarv/react-server models the same problem space through typed resources, request context, and native modules β there is no separate route-context bag because resources already carry schema-validated, route-scoped data with full type safety.
- Built-in devtools:
@lazarv/react-server ships with integrated devtools (--devtools) that go beyond route inspection β they cover RSC payload, cache entries, routes, outlets, remote components, live components, workers, and server logs in a single panel. TanStack Router provides excellent router-focused devtools, but @lazarv/react-server's devtools cover the full server component runtime.
- Outlets vs. parallel routes:
@lazarv/react-server uses named outlets (@sidebar, @content) rendered as typed props to layouts. This is functionally similar to Next.js parallel routes but with stronger typing β each outlet is a branded React element that prevents accidentally swapping outlets.
- Waku: Waku is another RSC-native framework built on Vite, but takes a deliberately minimal approach. It provides basic file-based routing with layouts and RSC support, but lacks the typed routing system, search param handling, scroll restoration, middleware, and most advanced routing features. Waku's
Link component supports basic scroll and prefetchOnEnter/prefetchOnView props, but most of its router API is still marked as unstable_. Waku is a good choice for simple RSC applications that don't need advanced routing.