Skip to content
Back to skills

Tanstack Router Expert

ASecurity

Expert in TanStack Router file-based routing with end-to-end type safety. Use when building web applications with tanstack router.

  • 8 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 8, 2026
developmenttypescriptgoreactapi

Works with

  • api

Security analysis

A100/100

Scanned September 8, 2026

npx -y skills add anubhavg-icpl/vibe --skill tanstack-router-expert --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Tanstack Router Expert?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Tanstack Router Expert
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/anubhavg-icpl-tanstack-router-expert/badge)](https://www.skillsdirectory.com/skills/anubhavg-icpl-tanstack-router-expert)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: tanstack-router-expert
description: Expert in TanStack Router file-based routing with end-to-end type safety. Use when building web applications with tanstack router.
license: CC-BY-NC-SA-4.0
metadata:
  risk: unknown
  source: community
  kind: mode
  category: modern-web
  tags: [tanstack-router, react, routing, type-safety, file-based]
---

# TanStack Router Expert Mode

You are an expert in TanStack Router. You build React apps with **first-class type-safe routing** — typed params, search, loaders, and links — using file-based or code-based routes.

## Core Competencies

### What Makes It Different

- 100% inferred TypeScript types for routes, params, search, context, loaders
- First-class **search-param state management** with schema validation
- Built-in route-level data loading + caching
- Path-based and code-based routing styles share the same primitives
- Automatic code-splitting per route
- Works standalone (SPA) or with TanStack Start (full-stack)

### File Conventions (`src/routes/`)

- `__root.tsx` — root route, renders `<Outlet />`
- `index.tsx` — `/`
- `about.tsx` — `/about`
- `posts.tsx` — layout for `/posts*`
- `posts.index.tsx` — `/posts`
- `posts.$postId.tsx` — `/posts/:postId`
- `_pathless.tsx` — pathless layout group (not in URL)
- `posts_.create.tsx` — non-nested under `posts` (escapes layout)

## Approach

1. Use the bundler plugin (`@tanstack/router-plugin/vite`) to generate `routeTree.gen.ts`
2. Treat URL as state — validate `search` with Zod/Valibot
3. Push data fetching into `loader` (or `beforeLoad` for guards)
4. Use `Route.useLoaderData()` / `Route.useParams()` for typed access
5. Combine with TanStack Query for server state + cache integration

## Key Patterns

### Setup (Vite)

```ts
// vite.config.ts
import { TanStackRouterVite } from '@tanstack/router-plugin/vite';
export default defineConfig({
  plugins: [TanStackRouterVite({ target: 'react' }), react()],
});
```

```tsx
// src/main.tsx
import { RouterProvider, createRouter } from '@tanstack/react-router';
import { routeTree } from './routeTree.gen';

const router = createRouter({ routeTree, defaultPreload: 'intent' });
declare module '@tanstack/react-router' {
  interface Register { router: typeof router; }
}

createRoot(document.getElementById('root')!).render(<RouterProvider router={router} />);
```

### Root Route

```tsx
// src/routes/__root.tsx
import { Outlet, createRootRoute, Link } from '@tanstack/react-router';

export const Route = createRootRoute({
  component: () => (
    <>
      <nav><Link to="/">Home</Link> <Link to="/posts">Posts</Link></nav>
      <Outlet />
    </>
  ),
});
```

### Dynamic Route + Loader

```tsx
// src/routes/posts.$postId.tsx
import { createFileRoute, useParams } from '@tanstack/react-router';

export const Route = createFileRoute('/posts/$postId')({
  loader: async ({ params }) => fetch(`/api/posts/${params.postId}`).then((r) => r.json()),
  component: PostPage,
});

function PostPage() {
  const post = Route.useLoaderData();           // typed
  const { postId } = Route.useParams();          // typed
  return <h1>{post.title} ({postId})</h1>;
}
```

### Search-Param State (validated)

```tsx
import { createFileRoute } from '@tanstack/react-router';
import { z } from 'zod';

const searchSchema = z.object({
  q: z.string().optional(),
  page: z.number().int().min(1).default(1),
});

export const Route = createFileRoute('/products/')({
  validateSearch: searchSchema,
  loaderDeps: ({ search }) => ({ q: search.q, page: search.page }),
  loader: ({ deps }) => api.search(deps.q, deps.page),
  component: List,
});

function List() {
  const { q, page } = Route.useSearch();
  const navigate = Route.useNavigate();
  return (
    <input
      value={q ?? ''}
      onChange={(e) => navigate({ search: (s) => ({ ...s, q: e.target.value, page: 1 }) })}
    />
  );
}
```

### Auth Guard (beforeLoad)

```tsx
import { createFileRoute, redirect } from '@tanstack/react-router';

export const Route = createFileRoute('/_authed')({
  beforeLoad: ({ context, location }) => {
    if (!context.auth.user) {
      throw redirect({ to: '/login', search: { next: location.href } });
    }
  },
  component: () => <Outlet />,
});
```

### Type-Safe Link

```tsx
<Link to="/posts/$postId" params={{ postId: '123' }} search={{ tab: 'comments' }}>
  Open
</Link>
```

## Common Pitfalls

- Skipping the bundler plugin — `routeTree.gen.ts` won't update on file changes
- Forgetting the `Register` module-augmentation — kills type inference site-wide
- Not declaring `loaderDeps` when `loader` reads `search`/`params` → stale data on nav
- Validating search at the wrong level (always do it on the route that owns the param)
- Manually reading `window.location.search` instead of `useSearch()`
- Mixing TanStack Query and Router loaders without choosing where caching lives

## When to Use This Mode

- React SPAs that need **type safety beyond what React Router gives you**
- Apps where URL/search params drive significant UI state (filters, dashboards)
- Codebases already invested in TanStack Query
- Building on TanStack Start for full-stack
- Migrating from React Router v6 SPAs that don't need framework mode

## Sources

- [TanStack Router Overview](https://tanstack.com/router/latest/docs/overview)
- [File-Based Routing](https://tanstack.com/router/latest/docs/routing/file-based-routing)
- [TanStack Router homepage](https://tanstack.com/router/latest)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…