- )
- },
-})
-```
-
-## Bundler-Specific Configuration
-
-### Vite Configuration
-
-```typescript
-// vite.config.ts
-import { defineConfig } from 'vite'
-import react from '@vitejs/plugin-react'
-import { TanStackRouterVite } from '@tanstack/router-vite-plugin'
-
-export default defineConfig({
- plugins: [
- react(),
- // TanStackRouterVite generates route tree and enables file-based routing
- TanStackRouterVite(),
- ],
- // Environment variables are handled automatically
- // Custom environment variable handling:
- define: {
- // Global constants (these become available as global variables)
- __APP_VERSION__: JSON.stringify(process.env.npm_package_version),
- },
-})
-```
-
-### Webpack Configuration
-
-```typescript
-// webpack.config.js
-const { TanStackRouterWebpack } = require('@tanstack/router-webpack-plugin')
-const webpack = require('webpack')
-
-module.exports = {
- plugins: [
- // TanStackRouterWebpack generates route tree and enables file-based routing
- new TanStackRouterWebpack(),
- new webpack.DefinePlugin({
- // Inject environment variables (use process.env for Webpack)
- 'process.env.API_URL': JSON.stringify(process.env.API_URL),
- 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
- 'process.env.ENABLE_FEATURE': JSON.stringify(process.env.ENABLE_FEATURE),
- }),
- ],
-}
-```
-
-### Rspack Configuration
-
-```typescript
-// rspack.config.js
-const { TanStackRouterRspack } = require('@tanstack/router-rspack-plugin')
-
-module.exports = {
- plugins: [
- // TanStackRouterRspack generates route tree and enables file-based routing
- new TanStackRouterRspack(),
- ],
- // Rspack automatically handles PUBLIC_ prefixed variables for import.meta.env
- // Custom handling for additional variables:
- builtins: {
- define: {
- // Define additional variables (these become global replacements)
- 'process.env.API_URL': JSON.stringify(process.env.PUBLIC_API_URL),
- __BUILD_TIME__: JSON.stringify(new Date().toISOString()),
- },
- },
-}
-```
-
-## Production Checklist
-
-- [ ] All client-exposed variables use appropriate prefix (`VITE_`, `PUBLIC_`, etc.)
-- [ ] No sensitive data (API secrets, private keys) in environment variables
-- [ ] `.env.local` is in `.gitignore`
-- [ ] Production environment variables are configured on hosting platform
-- [ ] Required environment variables are validated at build time
-- [ ] TypeScript declarations are up to date
-- [ ] Feature flags are properly configured for production
-- [ ] API URLs point to production endpoints
-
-## Common Problems
-
-### Environment Variable is Undefined
-
-**Problem**: `import.meta.env.MY_VARIABLE` returns `undefined`
-
-**Solutions**:
-
-1. **Add correct prefix**: Use `VITE_` for Vite, `PUBLIC_` for Rspack.
- Vite's default prefix may be changed in the config:
- ```ts
- // vite.config.ts
- export const config = {
- // ...rest of your config
- envPrefix: 'MYPREFIX_', // this means `MYPREFIX_MY_VARIABLE` is the new correct way
- }
- ```
-2. **Restart development server** after adding new variables
-3. **Check file location**: `.env` file must be in project root
-4. **Verify bundler configuration**: Ensure variables are properly injected
-5. **Verify variable**:
-
-- **In dev**: is in correct `.env` file or environment
-- **For prod**: is in correct `.env` file or current environment **_at bundle time_**. That's right, `VITE_`/`PUBLIC_`-prefixed variables are replaced in a macro-like fashion at bundle time, and will _never_ be read at runtime on your server. This is a common mistake, so make sure this is not your case.
-
-**Example**:
-
-```bash
-# β Won't work (no prefix)
-API_KEY=abc123
-
-# β Works with Vite
-VITE_API_KEY=abc123
-
-# β Works with Rspack
-PUBLIC_API_KEY=abc123
-
-# β Won't bundle the variable (assuming it is not set in the environment of the build)
-npm run build
-
-# β Works with Vite and will bundle the variable for production
-VITE_API_KEY=abc123 npm run build
-
-# β Works with Rspack and will bundle the variable for production
-PUBLIC_API_KEY=abc123 npm run build
-```
-
-### Runtime Client Environment Variables at Runtime in Production
-
-**Problem**: If `VITE_`/`PUBLIC_` variables are replaced at bundle time only, how to make runtime variables available on the client ?
-
-**Solutions**:
-
-Pass variables from the server down to the client:
-
-1. Add your variable to the correct `env.` file
-2. Create an endpoint on your server to read the value from the client
-
-**Example**:
-
-You may use your prefered backend framework/libray, but here it is using Tanstack Start server functions:
-
-```tsx
-const getRuntimeVar = createServerFn({ method: 'GET' }).handler(() => {
- return process.env.MY_RUNTIME_VAR // notice `process.env` on the server, and no `VITE_`/`PUBLIC_` prefix
-})
-
-export const Route = createFileRoute('/')({
- loader: async () => {
- const foo = await getRuntimeVar()
- return { foo }
- },
- component: RouteComponent,
-})
-
-function RouteComponent() {
- const { foo } = Route.useLoaderData()
- // ... use your variable however you want
-}
-```
-
-### Variable Not Updating
-
-**Problem**: Environment variable changes aren't reflected in app
-
-**Solutions**:
-
-1. **Restart development server** - Required for new variables
-2. **Check file hierarchy** - `.env.local` overrides `.env`
-3. **Clear browser cache** - Hard refresh (Ctrl+Shift+R)
-4. **Verify correct file** - Make sure you're editing the right `.env` file
-
-### TypeScript Errors
-
-**Problem**: `Property 'VITE_MY_VAR' does not exist on type 'ImportMetaEnv'`
-
-**Solution**: Add declaration to `src/vite-env.d.ts`:
-
-```typescript
-interface ImportMetaEnv {
- readonly VITE_MY_VAR: string
-}
-```
-
-### Build Errors
-
-**Problem**: Missing environment variables during build
-
-**Solutions**:
-
-1. **Configure CI/CD**: Set variables in build environment
-2. **Add validation**: Check required variables at build time
-3. **Use .env files**: Ensure production `.env` files exist
-4. **Check bundler config**: Verify environment variable injection
-
-### Security Issues
-
-**Problem**: Accidentally exposing sensitive data
-
-**Solutions**:
-
-1. **Never use secrets in client variables** - They're visible in browser
-2. **Use server-side proxies** for sensitive API calls
-3. **Audit bundle** - Check built files for leaked secrets
-4. **Follow naming conventions** - Only prefixed variables are exposed
-
-### Runtime vs Build-time Confusion
-
-**Problem**: Variables not available at runtime
-
-**Solutions**:
-
-1. **Understand static replacement** - Variables are replaced at build time
-2. **Use server-side for dynamic values** - Use APIs for runtime configuration
-3. **Validate at startup** - Check all required variables exist
-
-### Environment Variables are Always Strings
-
-**Problem**: Unexpected behavior when comparing boolean or numeric values
-
-**Solutions**:
-
-1. **Always compare as strings**: Use `=== 'true'` not `=== true`
-2. **Convert explicitly**: Use `parseInt()`, `parseFloat()`, or `Boolean()`
-3. **Use helper functions**: Create typed conversion utilities
-
-**Example**:
-
-```typescript
-// β Won't work as expected
-const isEnabled = import.meta.env.VITE_FEATURE_ENABLED // This is a string!
-if (isEnabled) {
- /* Always true if variable exists */
-}
-
-// β Correct string comparison
-const isEnabled = import.meta.env.VITE_FEATURE_ENABLED === 'true'
-
-// β Safe numeric conversion
-const port = parseInt(import.meta.env.VITE_PORT || '3000', 10)
-
-// β Helper function approach
-const getBooleanEnv = (value: string | undefined, defaultValue = false) => {
- if (value === undefined) return defaultValue
- return value.toLowerCase() === 'true'
-}
-```
-
-## Common Next Steps
-
-
-
-
-
-## Related Resources
-
-- [TanStack Router File-Based Routing](../../routing/file-based-routing.md) - Learn about route configuration
-- [Vite Environment Variables](https://vitejs.dev/guide/env-and-mode.html) - Official Vite documentation
-- [Webpack DefinePlugin](https://webpack.js.org/plugins/define-plugin/) - Webpack environment configuration
diff --git a/docs/router/framework/react/how-to/validate-search-params.md b/docs/router/framework/react/how-to/validate-search-params.md
deleted file mode 100644
index bc78755f09e..00000000000
--- a/docs/router/framework/react/how-to/validate-search-params.md
+++ /dev/null
@@ -1,643 +0,0 @@
----
-title: Validate Search Parameters with Schemas
----
-
-Learn how to add robust schema validation to your search parameters using popular validation libraries like Zod, Valibot, and ArkType. This guide covers validation setup, error handling, type safety, and common validation patterns for production applications.
-
-**Prerequisites:** [Set Up Basic Search Parameters](../setup-basic-search-params.md) - Foundation concepts for reading and working with search params.
-
-## Quick Start
-
-Add robust validation with custom error messages, complex types, and production-ready error handling:
-
-```tsx
-import { createFileRoute, useRouter } from '@tanstack/react-router'
-import { zodValidator, fallback } from '@tanstack/zod-adapter'
-import { z } from 'zod'
-
-const productSearchSchema = z.object({
- query: z.string().min(1, 'Search query required'),
- category: z.enum(['electronics', 'clothing', 'books', 'home']).optional(),
- minPrice: fallback(z.number().min(0, 'Price cannot be negative'), 0),
- maxPrice: fallback(z.number().min(0, 'Price cannot be negative'), 1000),
- inStock: fallback(z.boolean(), true),
- tags: z.array(z.string()).optional(),
- dateRange: z
- .object({
- start: z.string().datetime().optional(),
- end: z.string().datetime().optional(),
- })
- .optional(),
-})
-
-export const Route = createFileRoute('/products')({
- validateSearch: zodValidator(productSearchSchema),
- errorComponent: ({ error }) => {
- const router = useRouter()
- return (
-
+}
+```
+
+#### `src/main.tsx`
+
+Regardless of whether you are using the `@tanstack/router-plugin` package and running the `npm run dev`/`npm run build` scripts, or manually running the `tsr watch`/`tsr generate` commands from your package scripts, the route tree file will be generated at `src/routeTree.gen.ts`.
+
+Import the generated route tree and create a new router instance:
+
+```tsx
+import { StrictMode } from 'react'
+import ReactDOM from 'react-dom/client'
+import { RouterProvider, createRouter } from '@tanstack/react-router'
+
+// Import the generated route tree
+import { routeTree } from './routeTree.gen'
+
+// Create a new router instance
+const router = createRouter({ routeTree })
+
+// Register the router instance for type safety
+declare module '@tanstack/react-router' {
+ interface Register {
+ router: typeof router
+ }
+}
+
+// Render the app
+const rootElement = document.getElementById('root')!
+if (!rootElement.innerHTML) {
+ const root = ReactDOM.createRoot(rootElement)
+ root.render(
+
+
+ ,
+ )
+}
+```
+
+If you are working with this pattern you should change the `id` of the root `
` on your `index.html` file to ``
+
+## Using Code-Based Route Configuration
+
+> [!IMPORTANT]
+> The following example shows how to configure routes using code, and for simplicity's sake is in a single file for this demo. While code-based generation allows you to declare many routes and even the router instance in a single file, we recommend splitting your routes into separate files for better organization and performance as your application grows.
+
+```tsx
+import { StrictMode } from 'react'
+import ReactDOM from 'react-dom/client'
+import {
+ Outlet,
+ RouterProvider,
+ Link,
+ createRouter,
+ createRoute,
+ createRootRoute,
+} from '@tanstack/react-router'
+import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'
+
+const rootRoute = createRootRoute({
+ component: () => (
+ <>
+
+ },
+})
+
+const routeTree = rootRoute.addChildren([indexRoute, aboutRoute])
+
+const router = createRouter({ routeTree })
+
+declare module '@tanstack/react-router' {
+ interface Register {
+ router: typeof router
+ }
+}
+
+const rootElement = document.getElementById('app')!
+if (!rootElement.innerHTML) {
+ const root = ReactDOM.createRoot(rootElement)
+ root.render(
+
+
+ ,
+ )
+}
+```
+
+If you glossed over these examples or didn't understand something, we don't blame you, because there's so much more to learn to really take advantage of TanStack Router! Let's move on.
diff --git a/docs/router/framework/react/migrate-from-react-location.md b/docs/router/framework/react/installation/migrate-from-react-location.md
similarity index 100%
rename from docs/router/framework/react/migrate-from-react-location.md
rename to docs/router/framework/react/installation/migrate-from-react-location.md
diff --git a/docs/router/framework/react/migrate-from-react-router.md b/docs/router/framework/react/installation/migrate-from-react-router.md
similarity index 100%
rename from docs/router/framework/react/migrate-from-react-router.md
rename to docs/router/framework/react/installation/migrate-from-react-router.md
diff --git a/docs/router/framework/react/routing/installation-with-esbuild.md b/docs/router/framework/react/installation/with-esbuild.md
similarity index 98%
rename from docs/router/framework/react/routing/installation-with-esbuild.md
rename to docs/router/framework/react/installation/with-esbuild.md
index 1932d47edb6..91052d9d2d4 100644
--- a/docs/router/framework/react/routing/installation-with-esbuild.md
+++ b/docs/router/framework/react/installation/with-esbuild.md
@@ -1,5 +1,5 @@
---
-title: Installation with Esbuild
+title: Installation with ESbuild
---
[//]: # 'BundlerConfiguration'
diff --git a/docs/router/framework/react/routing/installation-with-router-cli.md b/docs/router/framework/react/installation/with-router-cli.md
similarity index 100%
rename from docs/router/framework/react/routing/installation-with-router-cli.md
rename to docs/router/framework/react/installation/with-router-cli.md
diff --git a/docs/router/framework/react/routing/installation-with-rspack.md b/docs/router/framework/react/installation/with-rspack.md
similarity index 100%
rename from docs/router/framework/react/routing/installation-with-rspack.md
rename to docs/router/framework/react/installation/with-rspack.md
diff --git a/docs/router/framework/react/routing/installation-with-vite.md b/docs/router/framework/react/installation/with-vite.md
similarity index 100%
rename from docs/router/framework/react/routing/installation-with-vite.md
rename to docs/router/framework/react/installation/with-vite.md
diff --git a/docs/router/framework/react/routing/installation-with-webpack.md b/docs/router/framework/react/installation/with-webpack.md
similarity index 100%
rename from docs/router/framework/react/routing/installation-with-webpack.md
rename to docs/router/framework/react/installation/with-webpack.md
diff --git a/docs/router/framework/react/overview.md b/docs/router/framework/react/overview.md
index 05c70fd4f16..faa6d9b02eb 100644
--- a/docs/router/framework/react/overview.md
+++ b/docs/router/framework/react/overview.md
@@ -2,161 +2,122 @@
title: Overview
---
-**TanStack Router is a router for building React and Solid applications**. Some of its features include:
-
-- 100% inferred TypeScript support
-- Typesafe navigation
-- Nested Routing and layout routes (with pathless layouts)
-- Built-in Route Loaders w/ SWR Caching
-- Designed for client-side data caches (TanStack Query, SWR, etc.)
-- Automatic route prefetching
-- Asynchronous route elements and error boundaries
-- File-based Route Generation
-- Typesafe JSON-first Search Params state management APIs
-- Path and Search Parameter Schema Validation
-- Search Param Navigation APIs
-- Custom Search Param parser/serializer support
-- Search param middleware
-- Route matching/loading middleware
-
-To get started quickly, head to the next page. For a more lengthy explanation, buckle up while I bring you up to speed!
-
-## "A Fork in the Route"
-
-Using a router to build applications is widely regarded as a must-have and is usually one of the first choices youβll make in your tech stack.
-
-[//]: # 'WhyChooseTanStackRouter'
-
-**So, why should you choose TanStack Router over another router?**
-
-To answer this question, we need to look at the other options in the space. There are many if you look hard enough, but in my experience, only a couple are worth exploring seriously:
-
-- **Next.js** - Widely regarded as the de facto framework for starting a new React project, itβs laser focused on performance, workflow, and bleeding edge technology. Its APIs and abstractions are powerful, but can sometimes come across as non-standard. Its extremely fast growth and adoption in the industry has resulted in a featured packed experience, but at the expense of feeling overwhelming and sometimes bloated.
-- **Remix / React Router** - A full-stack framework based on the historically successful React Router offers a similarly powerful developer and user experience, with APIs and vision based firmly on web standards like Request/Response and a focus on running anywhere JS can run. Many of its APIs and abstractions are wonderfully designed and were inspiration for more than a few TanStack Router APIs. That said, its rigid design, bolted-on type safety and sometimes strict over-adherence to platform APIs can leave some developers wanting more.
-
-Both of these frameworks (and their routers) are great, and I can personally attest that both are very good solutions for building React applications. My experience has also taught me that these solutions could also be much better, especially around the actual routing APIs that are available to developers to make their apps faster, easier, and more enjoyable to work with.
-
-It's probably no surprise at this point that picking a router is so important that it is often tied 1-to-1 with your choice of framework, since most frameworks rely on a specific router.
-
-[//]: # 'WhyChooseTanStackRouter'
-
-**Does this mean that TanStack Router is a framework?**
-
-TanStack Router itself is not a "framework" in the traditional sense, since it doesn't address a few other common full-stack concerns. However TanStack Router has been designed to be upgradable to a full-stack framework when used in conjunction with other tools that address bundling, deployments, and server-side-specific functionality. This is why we are currently developing [TanStack Start](https://tanstack.com/start), a full-stack framework that is built on top of TanStack Router and Vite.
-
-For a deeper dive on the history of TanStack Router, feel free to read [TanStack Router's History](../decisions-on-dx.md#tanstack-routers-origin-story).
-
-## Why TanStack Router?
-
-TanStack Router delivers on the same fundamental expectations as other routers that youβve come to expect:
-
-- Nested routes, layout routes, grouped routes
-- File-based Routing
-- Parallel data loading
-- Prefetching
-- URL Path Params
-- Error Boundaries and Handling
-- SSR
-- Route Masking
-
-And it also delivers some new features that raise the bar:
-
-- 100% inferred TypeScript support
-- Typesafe navigation
-- Built-in SWR Caching for loaders
-- Designed for client-side data caches (TanStack Query, SWR, etc.)
-- Typesafe JSON-first Search Params state management APIs
-- Path and Search Parameter Schema Validation
-- Search Parameter Navigation APIs
-- Custom Search Param parser/serializer support
-- Search param middleware
-- Inherited Route Context
-- Mixed file-based and code-based routing
-
-Letβs dive into some of the more important ones in more detail!
-
-## 100% Inferred TypeScript Support
-
-Everything these days is written βin Typescriptβ or at the very least offers type definitions that are veneered over runtime functionality, but too few packages in the ecosystem actually design their APIs with TypeScript in mind. So while Iβm pleased that your router is auto-completing your option fields and catching a few property/method typos here and there, there is much more to be had.
-
-- TanStack Router is fully aware of all of your routes and their configuration at any given point in your code. This includes the path, path params, search params, context, and any other configuration youβve provided. Ultimately this means that you can navigate to any route in your app with 100% type safety and confidence that your link or navigate call will succeed.
-- TanStack Router provides lossless type-inference. It uses countless generic type parameters to enforce and propagate any type information you give it throughout the rest of its API and ultimately your app. No other router offers this level of type safety and developer confidence.
-
-What does all of that mean for you?
-
-- Faster feature development with auto-completion and type hints
-- Safer and faster refactors
-- Confidence that your code will work as expected
-
-## 1st Class Search Parameters
-
-Search parameters are often an afterthought, treated like a black box of strings (or string) that you can parse and update, but not much else. Existing solutions are **not** type-safe either, adding to the caution that is required to deal with them. Even the most "modern" frameworks and routers leave it up to you to figure out how to manage this state. Sometimes they'll parse the search string into an object for you, or sometimes you're left to do it yourself with `URLSearchParams`.
-
-Let's step back and remember that **search params are the most powerful state manager in your entire application.** They are global, serializable, bookmarkable, and shareable making them the perfect place to store any kind of state that needs to survive a page refresh or a social share.
-
-To live up to that responsibility, search parameters are a first-class citizen in TanStack Router. While still based on standard URLSearchParams, TanStack Router uses a powerful parser/serializer to manage deeper and more complex data structures in your search params, all while keeping them type-safe and easy to work with.
-
-**It's like having `useState` right in the URL!**
-
-Search parameters are:
-
-- Automatically parsed and serialized as JSON
-- Validated and typed
-- Inherited from parent routes
-- Accessible in loaders, components, and hooks
-- Easily modified with the useSearch hook, Link, navigate, and router.navigate APIs
-- Customizable with a custom search filters and middleware
-- Subscribed via fine-grained search param selectors for efficient re-renders
-
-Once you start using TanStack Router's search parameters, you'll wonder how you ever lived without them.
-
-## Built-In Caching and Friendly Data Loading
-
-Data loading is a critical part of any application and while most existing routers offer some form of critical data loading APIs, they often fall short when it comes to caching and data lifecycle management. Existing solutions suffer from a few common problems:
-
-- No caching at all. Data is always fresh, but your users are left waiting for frequently accessed data to load over and over again.
-- Overly-aggressive caching. Data is cached for too long, leading to stale data and a poor user experience.
-- Blunt invalidation strategies and APIs. Data may be invalidated too often, leading to unnecessary network requests and wasted resources, or you may not have any fine-grained control over when data is invalidated at all.
-
-TanStack Router solves these problems with a two-prong approach to caching and data loading:
-
-### Built-in Cache
-
-TanStack Router provides a light-weight built-in caching layer that works seamlessly with the Router. This caching layer is loosely based on TanStack Query, but with fewer features and a much smaller API surface area. Like TanStack Query, sane but powerful defaults guarantee that your data is cached for reuse, invalidated when necessary, and garbage collected when not in use. It also provides a simple API for invalidating the cache manually when needed.
-
-### Flexible & Powerful Data Lifecycle APIs
-
-TanStack Router is designed with a flexible and powerful data loading API that more easily integrates with existing data fetching libraries like TanStack Query, SWR, Apollo, Relay, or even your own custom data fetching solution. Configurable APIs like `context`, `beforeLoad`, `loaderDeps` and `loader` work in unison to make it easy to define declarative data dependencies, prefetch data, and manage the lifecycle of an external data source with ease.
-
-## Inherited Route Context
-
-TanStack Router's router and route context is a powerful feature that allows you to define context that is specific to a route which is then inherited by all child routes. Even the router and root routes themselves can provide context. Context can be built up both synchronously and asynchronously, and can be used to share data, configuration, or even functions between routes and route configurations. This is especially useful for scenarios like:
-
-- Authentication and Authorization
-- Hybrid SSR/CSR data fetching and preloading
-- Theming
-- Singletons and global utilities
-- Curried or partial application across preloading, loading, and rendering stages
-
-Also, what would route context be if it weren't type-safe? TanStack Router's route context is fully type-safe and inferred at zero cost to you.
-
-## File-based and/or Code-Based Routing
-
-TanStack Router supports both file-based and code-based routing at the same time. This flexibility allows you to choose the approach that best fits your project's needs.
-
-TanStack Router's file-based routing approach is uniquely user-facing. Route configuration is generated for you either by the Vite plugin or TanStack Router CLI, leaving the usage of said generated code up to you! This means that you're always in total control of your routes and router, even if you use file-based routing.
+TanStack Router is a **typeβsafe router for React and Solid applications**. Itβs designed to make routing, data loading, and navigation smart, predictable, and fully integrated with TypeScript β so you can build faster, safer, and more scalable apps.
+
+## Key Features
+
+On top of the core features you'd expect from a modern router, TanStack Router delivers new features aimed at improving developer experience and productivity:
+
+- **100% inferred TypeScript support** β type safety across navigation, params, and context
+- **Nested & layout routes** β including pathless layouts for flexible route trees
+- **Fileβbased or codeβbased routing** β choose the style that fits your workflow
+- **Builtβin data loading & caching** β with SWRβinspired defaults and integration with TanStack Query
+- **Smart navigation** β prefetching, async route elements, and error boundaries out of the box
+- **Firstβclass search params** β JSONβsafe, validated, and easy to use like state
+
+Unlike frameworkβbound routers, TanStack Router is **frameworkβagnostic at its core**, giving you the freedom to use it standalone or as part of a larger stack. It even powers [TanStack Start](https://tanstack.com/start), our fullβstack React framework built on Router.
+
+[//]: # 'Comparison'
+
+## Comparison
+
+Before selecting a router or framework, itβs useful to compare the available options to understand how they differ. The table below compares **TanStack Router / Start**, **React Router**, and **Next.js** across a range of features and capabilities.
+
+> This comparison table strives to be as accurate and as unbiased as possible. If you use any of these libraries and feel the information could be improved, feel free to suggest changes (with notes or evidence of claims) using the "Edit this page on GitHub" link at the bottom of this page.
+
+### Legend
+
+- β First-class: built-in and ready to use with no extra setup
+- π‘ Partial support (scale of 5)
+- π Supported via addon or community package
+- πΆ Possible with custom code or workarounds
+- π Not officially supported
+
+| | TanStack Router / Start | React Router DOM [_(Website)_][router] | Next.JS [_(Website)_][nextjs] |
+| ---------------------------------------------- | ------------------------------------------------ | ----------------------------------------------------- | ----------------------------------------------------- |
+| Github Repo / Stars | [![][stars-tanstack-router]][gh-tanstack-router] | [![][stars-router]][gh-router] | [![][stars-nextjs]][gh-nextjs] |
+| Bundle Size | [![][bp-tanstack-router]][bpl-tanstack-router] | [![][bp-router]][bpl-router] | β |
+| History, Memory & Hash Routers | β | β | π |
+| Nested / Layout Routes | β | β | π‘ |
+| Suspense-like Route Transitions | β | β | β |
+| Typesafe Routes | β | π‘ (1/5) | π‘ |
+| Code-based Routes | β | β | π |
+| File-based Routes | β | β | β |
+| Virtual/Programmatic File-based Routes | β | β | π |
+| Router Loaders | β | β | β |
+| SWR Loader Caching | β | π | β |
+| Route Prefetching | β | β | β |
+| Auto Route Prefetching | β | β | β |
+| Route Prefetching Delay | β | πΆ | π |
+| Path Params | β | β | β |
+| Typesafe Path Params | β | β | π |
+| Typesafe Route Context | β | π | π |
+| Path Param Validation | β | π | π |
+| Custom Path Param Parsing/Serialization | β | π | π |
+| Ranked Routes | β | β | β |
+| Active Link Customization | β | β | β |
+| Optimistic UI | β | β | πΆ |
+| Typesafe Absolute + Relative Navigation | β | π‘ (1/5 via `buildHref` util) | π (IDE plugin) |
+| Route Mount/Transition/Unmount Events | β | π | π |
+| Devtools | β | π | π |
+| Basic Search Params | β | β | β |
+| Search Param Hooks | β | β | β |
+| ``/`useNavigate` Search Param API | β | π‘ (search-string only via the `to`/`search` options) | π‘ (search-string only via the `to`/`search` options) |
+| JSON Search Params | β | πΆ | πΆ |
+| TypeSafe Search Params | β | π | π |
+| Search Param Schema Validation | β | π | π |
+| Search Param Immutability + Structural Sharing | β | πΆ | π |
+| Custom Search Param parsing/serialization | β | πΆ | π |
+| Search Param Middleware | β | π | π |
+| Suspense Route Elements | β | β | β |
+| Route Error Elements | β | β | β |
+| Route Pending Elements | β | β | β |
+| ``/`useBlocker` | β | πΆ (no hard reloads or cross-origin navigation) | π |
+| Deferred Primitives | β | β | β |
+| Navigation Scroll Restoration | β | β | β |
+| ElementScroll Restoration | β | π | π |
+| Async Scroll Restoration | β | π | π |
+| Router Invalidation | β | β | β |
+| Runtime Route Manipulation (Fog of War) | π | β | β |
+| Parallel Routes | π | π | β |
+| **Full Stack** | -- | -- | -- |
+| SSR | β | β | β |
+| Streaming SSR | β | β | β |
+| Generic RPCs | β | π | π |
+| Generic RPC Middleware | β | π | π |
+| React Server Functions | β | π | β |
+| React Server Function Middleware | β | π | π |
+| API Routes | β | β | β |
+| API Middleware | β | π | β |
+| React Server Components | π | π‘ (Experimental) | β |
+| `