Agent skill

Tanstack Router

by bskimball in bskimball/tanstack-hono

Type-safe routing for React and Solid applications with first-class search params, data loading, and seamless integration with the React ecosystem.

MITAuto-check passedDevelopment

Install Tanstack Router

skills CLI
$ npx skills add bskimball/tanstack-hono --skill tanstack-router -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install bskimball/tanstack-hono tanstack-router --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/bskimball/tanstack-hono.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/tanstack-router .claude/skills/tanstack-router && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
tanstack-router
GitHub stars
119
Token cost
~4.4k tokens
SKILL.md length
556 words
Files
1
Skills in repo
3
Repo updated
First seen
Licence
MIT

At a glance

Type-safe routing for React and Solid applications with first-class search params, data loading, and seamless integration with the React ecosystem.

  • Works in 12 steps: Use file-based routing for most… → Validate search params with Zod or… → Use loaderDeps to control when loaders… → …
  • Tasks that involve Type safety
  • SKILL.md covers Overview, Installation, Core Concepts and Data Loading, plus 6 more sections
  • Calls npm

What it does

Tanstack Router is an agent skill from bskimball/tanstack-hono. Type-safe routing for React and Solid applications with first-class search params, data loading, and seamless integration with the React ecosystem.

Its SKILL.md is about 4.4k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Development, covering Type safety. It works with TanStack, React and Hono. The repository describes itself as: A simple example of using Tanstack Router SSR with Hono in a monolith. The licence is MIT.

When your agent uses it

  • Tasks that involve Type safety

Example prompts

  • “/tanstack-router”

Requirements

  • Node.js

Workflow steps

12 steps, taken from the first numbered list in SKILL.md.

  1. Use file-based routing for most applications - it's simpler and auto-generates the route tree
  2. Validate search params with Zod or custom validators for type safety
  3. Use loaderDeps to control when loaders re-execute based on search param changes
  4. Leverage context for dependency injection (QueryClient, auth state)
  5. Use beforeLoad for authentication guards, not in components
  6. Separate critical vs lazy code - keep loaders in the main file, components in .lazy.tsx
  7. Use preload="intent" on Links for perceived performance
  8. Use staleTime to prevent unnecessary refetches during navigation
  9. Register the router type for full TypeScript inference across the app
  10. Use notFound() instead of conditional rendering for 404 states
  11. Colocate search param logic with routes that own them
  12. Use pathless layouts (_authenticated) for shared auth/layout logic without URL segments

What it can do on your machine

Read from SKILL.md and the folder at commit 2a7f052. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • npm

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use npm, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Tanstack Router loads about 4.4k tokens when it runs. Until then it costs about 41 tokens; SKILL.md has 556 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~41
When it runs · the whole SKILL.md, loaded when a task matches
~4.4k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from bskimball/tanstack-hono at commit 2a7f052, republished under its MIT licence (© bskimball). 556 words, ~4,378 tokens.

Download SKILL.mdSave it as .claude/skills/tanstack-router/SKILL.md (or your agent's skills folder).
name
tanstack-router
description
Type-safe routing for React and Solid applications with first-class search params, data loading, and seamless integration with the React ecosystem.

Overview

TanStack Router is a fully type-safe router for React (and Solid) applications. It provides file-based routing, first-class search parameter management, built-in data loading, code splitting, and deep TypeScript integration. It serves as the routing foundation for TanStack Start (the full-stack framework).

Package: @tanstack/react-router CLI: @tanstack/router-cli or @tanstack/router-plugin (Vite/Rspack/Webpack) Devtools: @tanstack/react-router-devtools

Installation

bash
npm install @tanstack/react-router
# For file-based routing with Vite:
npm install -D @tanstack/router-plugin
# Or standalone CLI:
npm install -D @tanstack/router-cli

Core Concepts

Route Trees

Routes are organized in a tree structure. The root route is the top-level layout, and child routes nest underneath.

tsx
import { createRootRoute, createRoute, createRouter } from '@tanstack/react-router'

const rootRoute = createRootRoute({
  component: RootLayout,
})

const indexRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/',
  component: HomePage,
})

const aboutRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/about',
  component: AboutPage,
})

const routeTree = rootRoute.addChildren([indexRoute, aboutRoute])
const router = createRouter({ routeTree })
File-Based Routing

File-based routing automatically generates the route tree from your file structure. Configure with Vite plugin:

ts
// vite.config.ts
import { defineConfig } from 'vite'
import { TanStackRouterVite } from '@tanstack/router-plugin/vite'

export default defineConfig({
  plugins: [
    TanStackRouterVite(),
    // ... other plugins
  ],
})
File Naming Conventions
File PatternRoute TypeExample Path
__root.tsxRoot layoutN/A (wraps all)
index.tsxIndex route/
about.tsxStatic route/about
$postId.tsxDynamic param/posts/$postId
posts.tsxLayout route/posts/* (layout)
posts/index.tsxNested index/posts
posts/$postId.tsxNested dynamic/posts/123
posts_.$postId.tsxPathless layout/posts/123 (different layout)
_layout.tsxPathless layoutN/A (groups routes)
_layout/dashboard.tsxGrouped route/dashboard
$.tsxSplat/catch-all/*
posts.$postId.edit.tsxDot notation/posts/123/edit
Special Prefixes
  • _ prefix: Pathless routes (layout groups without URL segment)
  • $ prefix: Dynamic path parameters
  • (folder) parentheses: Route groups (organizational, no URL impact)
Route Configuration

Each route can define:

tsx
// routes/posts.$postId.tsx
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/posts/$postId')({
  // Validation for path params
  params: {
    parse: (params) => ({ postId: Number(params.postId) }),
    stringify: (params) => ({ postId: String(params.postId) }),
  },

  // Search params validation
  validateSearch: (search: Record<string, unknown>) => {
    return {
      page: Number(search.page ?? 1),
      filter: (search.filter as string) || '',
    }
  },

  // Data loading
  loader: async ({ params, context, abortController }) => {
    return fetchPost(params.postId)
  },

  // Loader dependencies (re-run loader when these change)
  loaderDeps: ({ search }) => ({ page: search.page }),

  // Stale time for cached loader data
  staleTime: 5_000,

  // Preloading
  preloadStaleTime: 30_000,

  // Error component
  errorComponent: PostErrorComponent,

  // Pending/loading component
  pendingComponent: PostLoadingComponent,

  // 404 component
  notFoundComponent: PostNotFoundComponent,

  // Before load hook (authentication, redirects)
  beforeLoad: async ({ context, location }) => {
    if (!context.auth.isAuthenticated) {
      throw redirect({
        to: '/login',
        search: { redirect: location.href },
      })
    }
  },

  // Head/meta management
  head: () => ({
    meta: [{ title: 'Post Details' }],
  }),

  // Component
  component: PostComponent,
})

function PostComponent() {
  const { postId } = Route.useParams()
  const post = Route.useLoaderData()
  const { page, filter } = Route.useSearch()

  return <div>{post.title}</div>
}

Data Loading

Route Loaders
tsx
export const Route = createFileRoute('/posts')({
  loader: async ({ context }) => {
    // Access router context (e.g., queryClient)
    const posts = await context.queryClient.ensureQueryData({
      queryKey: ['posts'],
      queryFn: fetchPosts,
    })
    return { posts }
  },
  component: PostsComponent,
})

function PostsComponent() {
  const { posts } = Route.useLoaderData()
  // ...
}
Loader Dependencies

Control when loaders re-execute:

tsx
export const Route = createFileRoute('/posts')({
  loaderDeps: ({ search: { page, filter } }) => ({ page, filter }),
  loader: async ({ deps: { page, filter } }) => {
    return fetchPosts({ page, filter })
  },
})
Deferred Data Loading

Stream non-critical data:

tsx
import { Await, defer } from '@tanstack/react-router'

export const Route = createFileRoute('/dashboard')({
  loader: async () => {
    const criticalData = await fetchCriticalData()
    const deferredData = defer(fetchSlowData())
    return { criticalData, deferredData }
  },
  component: DashboardComponent,
})

function DashboardComponent() {
  const { criticalData, deferredData } = Route.useLoaderData()

  return (
    <div>
      <CriticalSection data={criticalData} />
      <Suspense fallback={<Loading />}>
        <Await promise={deferredData}>
          {(data) => <SlowSection data={data} />}
        </Await>
      </Suspense>
    </div>
  )
}
Context-Based Data Loading

Provide shared dependencies via router context:

tsx
// Create router with context
const router = createRouter({
  routeTree,
  context: {
    queryClient,
    auth: undefined!, // Will be provided by RouterProvider
  },
})

// In root/app component
function App() {
  const auth = useAuth()
  return <RouterProvider router={router} context={{ auth }} />
}

// In routes
export const Route = createFileRoute('/protected')({
  beforeLoad: ({ context }) => {
    if (!context.auth.user) throw redirect({ to: '/login' })
  },
  loader: ({ context }) => {
    return context.queryClient.ensureQueryData(userQueryOptions())
  },
})

Search Parameters

Validation
tsx
import { z } from 'zod'

const postSearchSchema = z.object({
  page: z.number().default(1),
  filter: z.string().default(''),
  sort: z.enum(['date', 'title']).default('date'),
})

export const Route = createFileRoute('/posts')({
  validateSearch: postSearchSchema,
  // Or manual validation:
  // validateSearch: (search) => postSearchSchema.parse(search),
})
Reading Search Params
tsx
function PostsComponent() {
  // From route
  const { page, filter, sort } = Route.useSearch()

  // Or from any component with useSearch hook
  const search = useSearch({ from: '/posts' })
}
Updating Search Params
tsx
import { useNavigate } from '@tanstack/react-router'

function Pagination() {
  const navigate = useNavigate()
  const { page } = Route.useSearch()

  return (
    <button
      onClick={() =>
        navigate({
          search: (prev) => ({ ...prev, page: prev.page + 1 }),
        })
      }
    >
      Next Page
    </button>
  )
}

// Or via Link component
<Link
  to="/posts"
  search={(prev) => ({ ...prev, page: 2 })}
>
  Page 2
</Link>
Search Param Options
tsx
const router = createRouter({
  routeTree,
  // Custom serialization
  search: {
    strict: true, // Reject unknown params
  },
  // Default search param serializer
  stringifySearch: defaultStringifySearch,
  parseSearch: defaultParseSearch,
})

Navigation

tsx
import { Link } from '@tanstack/react-router'

// Static route
<Link to="/about">About</Link>

// Dynamic route with params
<Link to="/posts/$postId" params={{ postId: '123' }}>
  Post 123
</Link>

// With search params
<Link to="/posts" search={{ page: 2, filter: 'react' }}>
  Page 2
</Link>

// Active link styling
<Link
  to="/posts"
  activeProps={{ className: 'active' }}
  inactiveProps={{ className: 'inactive' }}
  activeOptions={{ exact: true }}
>
  Posts
</Link>

// Preloading
<Link to="/posts" preload="intent">Posts</Link>
<Link to="/dashboard" preload="viewport">Dashboard</Link>

// Hash
<Link to="/docs" hash="api-reference">API Reference</Link>
Programmatic Navigation
tsx
import { useNavigate, useRouter } from '@tanstack/react-router'

function MyComponent() {
  const navigate = useNavigate()
  const router = useRouter()

  // Navigate to a route
  navigate({ to: '/posts', search: { page: 1 } })

  // Navigate with replace
  navigate({ to: '/posts', replace: true })

  // Relative navigation
  navigate({ to: '.', search: (prev) => ({ ...prev, page: 2 }) })

  // Go back/forward
  router.history.back()
  router.history.forward()

  // Invalidate and reload current route
  router.invalidate()
}
Redirects
tsx
import { redirect } from '@tanstack/react-router'

// In beforeLoad or loader
throw redirect({
  to: '/login',
  search: { redirect: location.href },
  // Optional status code
  statusCode: 301, // Permanent redirect (SSR)
})
Navigation Blocking
tsx
import { useBlocker } from '@tanstack/react-router'

function FormComponent() {
  const [isDirty, setIsDirty] = useState(false)

  useBlocker({
    shouldBlockFn: () => isDirty,
    withResolver: true, // Shows confirm dialog
  })

  // Or with custom UI
  const { proceed, reset, status } = useBlocker({
    shouldBlockFn: () => isDirty,
  })

  if (status === 'blocked') {
    return (
      <div>
        <p>Are you sure you want to leave?</p>
        <button onClick={proceed}>Leave</button>
        <button onClick={reset}>Stay</button>
      </div>
    )
  }
}

Code Splitting

Automatic (File-Based Routing)

With file-based routing, create a lazy file:

routes/
  posts.tsx          # Critical: loader, beforeLoad, meta
  posts.lazy.tsx     # Lazy: component, pendingComponent, errorComponent
tsx
// posts.tsx (loaded eagerly)
export const Route = createFileRoute('/posts')({
  loader: () => fetchPosts(),
})

// posts.lazy.tsx (loaded lazily)
import { createLazyFileRoute } from '@tanstack/react-router'

export const Route = createLazyFileRoute('/posts')({
  component: PostsComponent,
  pendingComponent: PostsLoading,
  errorComponent: PostsError,
})
Manual Code Splitting
tsx
const postsRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/posts',
  loader: () => fetchPosts(),
}).lazy(() => import('./posts.lazy').then((d) => d.Route))

Preloading

tsx
// Router-level defaults
const router = createRouter({
  routeTree,
  defaultPreload: 'intent', // 'intent' | 'viewport' | 'render' | false
  defaultPreloadStaleTime: 30_000, // 30 seconds
})

// Route-level
export const Route = createFileRoute('/posts/$postId')({
  // Stale time for the loader data
  staleTime: 5_000,
  // How long preloaded data stays fresh
  preloadStaleTime: 30_000,
})

// Link-level
<Link to="/posts" preload="intent" preloadDelay={100}>
  Posts
</Link>

Type Safety

Register Router Type
tsx
// Declare module for type inference
declare module '@tanstack/react-router' {
  interface Register {
    router: typeof router
  }
}
Type-Safe Hooks

All hooks are fully typed based on the route tree:

tsx
// useParams - typed to route's params
const { postId } = useParams({ from: '/posts/$postId' })

// useSearch - typed to route's search schema
const { page } = useSearch({ from: '/posts' })

// useLoaderData - typed to loader return
const data = useLoaderData({ from: '/posts/$postId' })

// useRouteContext - typed to route context
const { auth } = useRouteContext({ from: '/protected' })
Route Generics
tsx
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/posts/$postId')({
  // TypeScript infers:
  // params: { postId: string }
  // search: validated search schema type
  // loaderData: return type of loader
  // context: router context type
})

Authenticated Routes

tsx
// __root.tsx
export const Route = createRootRouteWithContext<{
  auth: AuthContext
}>()({
  component: RootComponent,
})

// _authenticated.tsx (pathless layout for auth)
export const Route = createFileRoute('/_authenticated')({
  beforeLoad: ({ context, location }) => {
    if (!context.auth.isAuthenticated) {
      throw redirect({
        to: '/login',
        search: { redirect: location.href },
      })
    }
  },
})

// _authenticated/dashboard.tsx
export const Route = createFileRoute('/_authenticated/dashboard')({
  component: Dashboard, // Only accessible when authenticated
})

Scroll Restoration

tsx
const router = createRouter({
  routeTree,
  // Enable scroll restoration
  defaultScrollRestoration: true,
})

// Or per-route
export const Route = createFileRoute('/posts')({
  // Scroll to top on navigation
  scrollRestoration: true,
})

// Custom scroll restoration key
<ScrollRestoration
  getKey={(location) => location.pathname}
/>

Route Masking

Display a different URL than the actual route:

tsx
<Link
  to="/photos/$photoId"
  params={{ photoId: photo.id }}
  mask={{ to: '/photos', search: { photoId: photo.id } }}
>
  View Photo
</Link>

// Or programmatically
navigate({
  to: '/photos/$photoId',
  params: { photoId: photo.id },
  mask: { to: '/photos', search: { photoId: photo.id } },
})

Not Found Handling

tsx
// Global 404
const router = createRouter({
  routeTree,
  defaultNotFoundComponent: () => <div>Page not found</div>,
})

// Route-level 404
export const Route = createFileRoute('/posts/$postId')({
  loader: async ({ params }) => {
    const post = await fetchPost(params.postId)
    if (!post) throw notFound()
    return post
  },
  notFoundComponent: () => <div>Post not found</div>,
})

Head Management

tsx
export const Route = createFileRoute('/posts/$postId')({
  head: ({ loaderData }) => ({
    meta: [
      { title: loaderData.title },
      { name: 'description', content: loaderData.excerpt },
      { property: 'og:title', content: loaderData.title },
    ],
    links: [
      { rel: 'canonical', href: `https://example.com/posts/${loaderData.id}` },
    ],
  }),
})

Integration with TanStack Query

tsx
import { queryOptions } from '@tanstack/react-query'

const postsQueryOptions = queryOptions({
  queryKey: ['posts'],
  queryFn: fetchPosts,
})

export const Route = createFileRoute('/posts')({
  loader: ({ context: { queryClient } }) => {
    // Ensure data is in cache, won't refetch if fresh
    return queryClient.ensureQueryData(postsQueryOptions)
  },
  component: PostsComponent,
})

function PostsComponent() {
  // Use the same query options for reactive updates
  const { data: posts } = useSuspenseQuery(postsQueryOptions)
  return <PostsList posts={posts} />
}

Router Hooks Reference

HookPurpose
useRouter()Access router instance
useRouterState()Subscribe to router state
useParams()Get route path params
useSearch()Get validated search params
useLoaderData()Get route loader data
useRouteContext()Get route context
useNavigate()Get navigate function
useLocation()Get current location
useMatches()Get all matched routes
useMatch()Get specific route match
useBlocker()Block navigation
useLinkProps()Get link props for custom components
useMatchRoute()Check if a route matches
Show full SKILL.md (205 more words)Show less

Best Practices

  1. Use file-based routing for most applications - it's simpler and auto-generates the route tree
  2. Validate search params with Zod or custom validators for type safety
  3. Use loaderDeps to control when loaders re-execute based on search param changes
  4. Leverage context for dependency injection (QueryClient, auth state)
  5. Use beforeLoad for authentication guards, not in components
  6. Separate critical vs lazy code - keep loaders in the main file, components in .lazy.tsx
  7. Use preload="intent" on Links for perceived performance
  8. Use staleTime to prevent unnecessary refetches during navigation
  9. Register the router type for full TypeScript inference across the app
  10. Use notFound() instead of conditional rendering for 404 states
  11. Colocate search param logic with routes that own them
  12. Use pathless layouts (_authenticated) for shared auth/layout logic without URL segments

Common Pitfalls

  • Forgetting to register the router type (declare module)
  • Not using loaderDeps when loader depends on search params (causes stale data)
  • Putting auth checks in components instead of beforeLoad (flash of protected content)
  • Not handling the loading state with pendingComponent
  • Using useEffect for data fetching instead of route loaders
  • Mutating search params directly instead of using navigate/Link
  • Not wrapping the app with RouterProvider
  • Forgetting getParentRoute in code-based route definitions

© bskimball, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/tanstack-router of bskimball/tanstack-hono.

Open the folder on GitHubat commit 2a7f052

Compare with similar skills

Tanstack Router next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Tanstack Router compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Tanstack Router this skillbskimball/tanstack-hono119—~4.4kAutomated safety check: PassMIT
Wagmi Feature Developmentwevm/wagmi6.8k—~3.8kAutomated safety check: PassMIT
Tanstack Router Best PracticesDeckardGer/tanstack-agent-skills222—~1.1kAutomated safety check: PassMIT
Tanstack Routersecondsky/claude-skills227—~1.9kAutomated safety check: NotesMIT
Tanstack RouterMindrally/skills267—~1.9kAutomated safety check: PassApache-2.0
Olore Tanstack Router Latestolorehq/olore103—~477Automated safety check: PassMIT

Similar skills

  • Walks through adding a Wagmi feature across its layers: a Viem-based core action, TanStack Query options, and React and Vue bindings.

    6.8k GitHub stars~3.8k tokensUpdated 6 days ago
    DevelopmentAuto-check passed
  • Tanstack Router Best Practices

    DeckardGer/tanstack-agent-skills

    TanStack Router best practices for type-safe routing, data loading, search params, and navigation.

    222 GitHub stars~1.1k tokensUpdated 28 days ago
    DevelopmentAuto-check passed
  • Tanstack Router

    secondsky/claude-skills

    TanStack Router type-safe file-based routing for React. An agent skill from secondsky/claude-skills.

    227 GitHub stars~1.9k tokensUpdated 9 days ago
    DevelopmentAuto-check: notes
  • Tanstack Router

    Mindrally/skills

    Type-safe, file-based routing for React with TanStack Router.

    267 GitHub stars~1.9k tokensUpdated 1 mo ago
    DevelopmentAuto-check passed
  • Local TanStack Router documentation reference (latest). An agent skill from olorehq/olore.

    103 GitHub stars~477 tokensUpdated today
    DevelopmentAuto-check passed
  • React Dev

    davila7/claude-code-templates

    This skill should be used when building React components with TypeScript, typing hooks, handling events, or when React TypeScript, React 19, Server Components are mentioned.

    32k GitHub starsUsed in 2 repos~2.6k tokens
    Frontend & DesignAuto-check passed

More from bskimball/tanstack-hono

  • Hono

    bskimball/tanstack-hono

    A skill your agent uses when building Hono web applications or when the user asks about Hono APIs, routing, middleware, JSX, validation, testing, or streaming.

    119 GitHub stars~3.4k tokensUpdated 26 days ago
    Auto-check passed
  • Tanstack Query

    bskimball/tanstack-hono

    Powerful asynchronous state management, server-state utilities, and data fetching for TS/JS, React, Vue, Solid, Svelte & Angular.

    119 GitHub starsUsed in 1 repo~5.4k tokens
    Auto-check passed

Categories

Questions about Tanstack Router

What does Tanstack Router do?

Type-safe routing for React and Solid applications with first-class search params, data loading, and seamless integration with the React ecosystem. Tanstack Router is an agent skill from bskimball/tanstack-hono. Type-safe routing for React and Solid applications with first-class search params, data loading, and seamless integration with the React ecosystem.

When should I use Tanstack Router?

Tanstack Router fits situations like: tasks that involve Type safety.

How do I install Tanstack Router in Claude Code?

Run `npx skills add bskimball/tanstack-hono --skill tanstack-router -a claude-code`. Or copy the skill folder (.agents/skills/tanstack-router in bskimball/tanstack-hono) into .claude/skills/tanstack-router in your project. Claude Code loads it when a task matches its description.

How do I install Tanstack Router in Codex?

Run `npx skills add bskimball/tanstack-hono --skill tanstack-router -a codex`. Or copy the skill folder (.agents/skills/tanstack-router in bskimball/tanstack-hono) into .agents/skills/tanstack-router in your project. Codex loads it when a task matches its description.

Can I use Tanstack Router in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add bskimball/tanstack-hono --skill tanstack-router -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/tanstack-router, .gemini/skills/tanstack-router, .github/skills/tanstack-router and .opencode/skills/tanstack-router in your project.

What does Tanstack Router need to run?

Going by SKILL.md and its folder, Tanstack Router needs the command-line tools its instructions call (npm). Our summary lists: Node.js.

Does Tanstack Router access the network?

SKILL.md contains no URLs. Its commands use npm, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Tanstack Router safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Tanstack Router use?

Tanstack Router is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Tanstack Router use?

About 4.4k tokens (SKILL.md is roughly 18k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Tanstack Router?

Skills that share tags, products or a category with Tanstack Router: Wagmi Feature Development (wevm/wagmi, 6.8k stars), Tanstack Router Best Practices (DeckardGer/tanstack-agent-skills, 222 stars), Tanstack Router (secondsky/claude-skills, 227 stars) and Tanstack Router (Mindrally/skills, 267 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Tanstack Router?

bskimball (a GitHub user) maintains it in bskimball/tanstack-hono, which has 119 GitHub stars. The repository holds 3 skills in this directory. The repository was last updated on September 11, 2026.

Source: bskimball/tanstack-hono on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.