If you're feeling impatient and prefer to skip all of our wonderful documentation, here is the bare minimum to get going with TanStack Router using both file-based route generation and code-based route configuration:
File based route generation (through Vite, and other supported bundlers) is the recommended way to use TanStack Router as it provides the best experience, performance, and ergonomics for the least amount of effort.
npm create @tanstack/router@latest# orpnpm create @tanstack/router# oryarn create @tanstack/router# orbun create @tanstack/router
Follow the prompts to setup the project.
npm install -D @tanstack/router-plugin @tanstack/router-devtools# orpnpm add -D @tanstack/router-plugin @tanstack/router-devtools# oryarn add -D @tanstack/router-plugin @tanstack/router-devtools# orbun add -D @tanstack/router-plugin @tanstack/router-devtools
// vite.config.tsimport { defineConfig } from 'vite'import viteReact from '@vitejs/plugin-react'import { TanStackRouterVite } from '@tanstack/router-plugin/vite'
// https://vitejs.dev/config/export default defineConfig({ plugins: [ TanStackRouterVite(), viteReact(), // ..., ],})
[!TIP] If you are not using Vite, or any supported bundler, you can check out the File-Based Routing guide for more info.
Create the following files:
src/routes/__root.tsx
src/routes/index.lazy.tsx
src/routes/about.lazy.tsx
src/main.tsx
🧠Route files with the
.lazy.tsx
extension are lazy loaded via separate bundles to keep the main bundle size as lean as possible.
src/routes/__root.tsx
import { createRootRoute, Link, Outlet } from '@tanstack/react-router'import { TanStackRouterDevtools } from '@tanstack/router-devtools'
export const Route = createRootRoute({ component: () => ( <> <div className="p-2 flex gap-2"> <Link to="/" className="[&.active]:font-bold"> Home </Link>{' '} <Link to="/about" className="[&.active]:font-bold"> About </Link> </div> <hr /> <Outlet /> <TanStackRouterDevtools /> </> ),})
src/routes/index.lazy.tsx
import { createLazyFileRoute } from '@tanstack/react-router'
export const Route = createLazyFileRoute('/')({ component: Index,})
function Index() { return ( <div className="p-2"> <h3>Welcome Home!</h3> </div> )}
src/routes/about.lazy.tsx
import { createLazyFileRoute } from '@tanstack/react-router'
export const Route = createLazyFileRoute('/about')({ component: About,})
function About() { return <div className="p-2">Hello from About!</div>}
src/main.tsx
Regardless if you are using the @tanstack/router-plugin
package or manually running the tsr watch
/tsr generate
commands from your package scripts, the following file will be generated for you at src/routeTree.gen.ts
.
Import the generated route tree and create a new router instance:
import { StrictMode } from 'react'import ReactDOM from 'react-dom/client'import { RouterProvider, createRouter } from '@tanstack/react-router'
// Import the generated route treeimport { routeTree } from './routeTree.gen'
// Create a new router instanceconst router = createRouter({ routeTree })
// Register the router instance for type safetydeclare module '@tanstack/react-router' { interface Register { router: typeof router }}
// Render the appconst rootElement = document.getElementById('root')!if (!rootElement.innerHTML) { const root = ReactDOM.createRoot(rootElement) root.render( <StrictMode> <RouterProvider router={router} /> </StrictMode>, )}
If you are working with this pattern you should change the id
of the root <div>
on your index.html
file to <div id='root'></div>
[!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.
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/router-devtools'
const rootRoute = createRootRoute({ component: () => ( <> <div className="p-2 flex gap-2"> <Link to="/" className="[&.active]:font-bold"> Home </Link>{' '} <Link to="/about" className="[&.active]:font-bold"> About </Link> </div> <hr /> <Outlet /> <TanStackRouterDevtools /> </> ),})
const indexRoute = createRoute({ getParentRoute: () => rootRoute, path: '/', component: function Index() { return ( <div className="p-2"> <h3>Welcome Home!</h3> </div> ) },})
const aboutRoute = createRoute({ getParentRoute: () => rootRoute, path: '/about', component: function About() { return <div className="p-2">Hello from About!</div> },})
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( <StrictMode> <RouterProvider router={router} /> </StrictMode>, )}
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.
Your weekly dose of JavaScript news. Delivered every Monday to over 100,000 devs, for free.