Wagmi Feature Development
wevm/wagmi
Walks through adding a Wagmi feature across its layers: a Viem-based core action, TanStack Query options, and React and Vue bindings.
Type-safe routing for React and Solid applications with first-class search params, data loading, and seamless integration with the React ecosystem.
$ npx skills add bskimball/tanstack-hono --skill tanstack-router -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install bskimball/tanstack-hono tanstack-router --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ 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-srcUse ~/.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/
Install the "tanstack-router" agent skill from https://github.com/bskimball/tanstack-hono/tree/master/.agents/skills/tanstack-router into .claude/skills/tanstack-router/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "tanstack-router", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/bskimball/tanstack-hono/tree/master/.agents/skills/tanstack-routerType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add bskimball/tanstack-hono --skill tanstack-router -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install bskimball/tanstack-hono tanstack-router --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/bskimball/tanstack-hono.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/tanstack-router .agents/skills/tanstack-router && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "tanstack-router" agent skill from https://github.com/bskimball/tanstack-hono/tree/master/.agents/skills/tanstack-router into .agents/skills/tanstack-router/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "tanstack-router", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add bskimball/tanstack-hono --skill tanstack-router -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install bskimball/tanstack-hono tanstack-router --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/bskimball/tanstack-hono.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/tanstack-router .cursor/skills/tanstack-router && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "tanstack-router" agent skill from https://github.com/bskimball/tanstack-hono/tree/master/.agents/skills/tanstack-router into .cursor/skills/tanstack-router/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "tanstack-router", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/bskimball/tanstack-hono.git --path .agents/skills/tanstack-router--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add bskimball/tanstack-hono --skill tanstack-router -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install bskimball/tanstack-hono tanstack-router --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/bskimball/tanstack-hono.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/tanstack-router .gemini/skills/tanstack-router && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "tanstack-router" agent skill from https://github.com/bskimball/tanstack-hono/tree/master/.agents/skills/tanstack-router into .gemini/skills/tanstack-router/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "tanstack-router", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install bskimball/tanstack-hono tanstack-routerInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add bskimball/tanstack-hono --skill tanstack-router -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/bskimball/tanstack-hono.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/tanstack-router .github/skills/tanstack-router && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "tanstack-router" agent skill from https://github.com/bskimball/tanstack-hono/tree/master/.agents/skills/tanstack-router into .github/skills/tanstack-router/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "tanstack-router", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add bskimball/tanstack-hono --skill tanstack-router -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install bskimball/tanstack-hono tanstack-router --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/bskimball/tanstack-hono.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/tanstack-router .opencode/skills/tanstack-router && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "tanstack-router" agent skill from https://github.com/bskimball/tanstack-hono/tree/master/.agents/skills/tanstack-router into .opencode/skills/tanstack-router/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "tanstack-router", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
tanstack-routerType-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.
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.
12 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 2a7f052. It shows what the files ask for, not the result of running them.
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.
Shell commands in SKILL.md call:
npmFrom the folder's file list and the shell code blocks in SKILL.md.
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.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
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.
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.
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.
The full file from bskimball/tanstack-hono at commit 2a7f052, republished under its MIT licence (© bskimball). 556 words, ~4,378 tokens.
.claude/skills/tanstack-router/SKILL.md (or your agent's skills folder).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
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-cliRoutes are organized in a tree structure. The root route is the top-level layout, and child routes nest underneath.
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 automatically generates the route tree from your file structure. Configure with Vite plugin:
// vite.config.ts
import { defineConfig } from 'vite'
import { TanStackRouterVite } from '@tanstack/router-plugin/vite'
export default defineConfig({
plugins: [
TanStackRouterVite(),
// ... other plugins
],
})| File Pattern | Route Type | Example Path |
|---|---|---|
__root.tsx | Root layout | N/A (wraps all) |
index.tsx | Index route | / |
about.tsx | Static route | /about |
$postId.tsx | Dynamic param | /posts/$postId |
posts.tsx | Layout route | /posts/* (layout) |
posts/index.tsx | Nested index | /posts |
posts/$postId.tsx | Nested dynamic | /posts/123 |
posts_.$postId.tsx | Pathless layout | /posts/123 (different layout) |
_layout.tsx | Pathless layout | N/A (groups routes) |
_layout/dashboard.tsx | Grouped route | /dashboard |
$.tsx | Splat/catch-all | /* |
posts.$postId.edit.tsx | Dot notation | /posts/123/edit |
_ prefix: Pathless routes (layout groups without URL segment)$ prefix: Dynamic path parameters(folder) parentheses: Route groups (organizational, no URL impact)Each route can define:
// 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>
}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()
// ...
}Control when loaders re-execute:
export const Route = createFileRoute('/posts')({
loaderDeps: ({ search: { page, filter } }) => ({ page, filter }),
loader: async ({ deps: { page, filter } }) => {
return fetchPosts({ page, filter })
},
})Stream non-critical data:
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>
)
}Provide shared dependencies via router context:
// 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())
},
})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),
})function PostsComponent() {
// From route
const { page, filter, sort } = Route.useSearch()
// Or from any component with useSearch hook
const search = useSearch({ from: '/posts' })
}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>const router = createRouter({
routeTree,
// Custom serialization
search: {
strict: true, // Reject unknown params
},
// Default search param serializer
stringifySearch: defaultStringifySearch,
parseSearch: defaultParseSearch,
})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>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()
}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)
})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>
)
}
}With file-based routing, create a lazy file:
routes/
posts.tsx # Critical: loader, beforeLoad, meta
posts.lazy.tsx # Lazy: component, pendingComponent, errorComponent// 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,
})const postsRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/posts',
loader: () => fetchPosts(),
}).lazy(() => import('./posts.lazy').then((d) => d.Route))// 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>// Declare module for type inference
declare module '@tanstack/react-router' {
interface Register {
router: typeof router
}
}All hooks are fully typed based on the route tree:
// 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' })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
})// __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
})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}
/>Display a different URL than the actual route:
<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 } },
})// 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>,
})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}` },
],
}),
})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} />
}| Hook | Purpose |
|---|---|
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 |
loaderDeps to control when loaders re-execute based on search param changesbeforeLoad for authentication guards, not in components.lazy.tsxpreload="intent" on Links for perceived performancestaleTime to prevent unnecessary refetches during navigationnotFound() instead of conditional rendering for 404 states_authenticated) for shared auth/layout logic without URL segmentsdeclare module)loaderDeps when loader depends on search params (causes stale data)beforeLoad (flash of protected content)pendingComponentuseEffect for data fetching instead of route loadersRouterProvidergetParentRoute 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
Just SKILL.md in .agents/skills/tanstack-router of bskimball/tanstack-hono.
Open the folder on GitHubat commit 2a7f052
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.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Tanstack Router this skillbskimball/tanstack-hono | 119 | — | ~4.4k | Automated safety check: Pass | MIT | |
| Wagmi Feature Developmentwevm/wagmi | 6.8k | — | ~3.8k | Automated safety check: Pass | MIT | |
| Tanstack Router Best PracticesDeckardGer/tanstack-agent-skills | 222 | — | ~1.1k | Automated safety check: Pass | MIT | |
| Tanstack Routersecondsky/claude-skills | 227 | — | ~1.9k | Automated safety check: Notes | MIT | |
| Tanstack RouterMindrally/skills | 267 | — | ~1.9k | Automated safety check: Pass | Apache-2.0 | |
| Olore Tanstack Router Latestolorehq/olore | 103 | — | ~477 | Automated safety check: Pass | MIT |
wevm/wagmi
Walks through adding a Wagmi feature across its layers: a Viem-based core action, TanStack Query options, and React and Vue bindings.
DeckardGer/tanstack-agent-skills
TanStack Router best practices for type-safe routing, data loading, search params, and navigation.
secondsky/claude-skills
TanStack Router type-safe file-based routing for React. An agent skill from secondsky/claude-skills.
Mindrally/skills
Type-safe, file-based routing for React with TanStack Router.
olorehq/olore
Local TanStack Router documentation reference (latest). An agent skill from olorehq/olore.
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.
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.
bskimball/tanstack-hono
Powerful asynchronous state management, server-state utilities, and data fetching for TS/JS, React, Vue, Solid, Svelte & Angular.
Categories
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.
Tanstack Router fits situations like: tasks that involve Type safety.
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.
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.
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.
Going by SKILL.md and its folder, Tanstack Router needs the command-line tools its instructions call (npm). Our summary lists: Node.js.
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.
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.
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.
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.
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.
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.