Agent skill

react-web-advanced

Web-specific React patterns for type-safe file-based routing, route-level data loading, server-side rendering, search param validation, code splitting, and list virtualization. Use when building React web apps with route loaders, SSR streaming, validated search params, lazy route splitting, or virtualizing large DOM lists. Do not use for React Native apps — use react-native-advanced instead.

Stars 3
Forks 0

Install this agent skill to your Project

npx add-skill https://github.com/trancong12102/agentskills/tree/main/react-web-advanced

SKILL.md

React Web Advanced: TanStack Router, Start & Virtual

Web-specific patterns for React apps built on the TanStack Router + Start + Virtual stack. This skill extends react-advanced (core cross-platform patterns). Read that skill first for React Query, XState, Zustand, Zod, TanStack Form, and TanStack Table conventions.

Table of Contents

  1. Web Architecture
  2. Route Loader + React Query Pattern
  3. Performance Patterns
  4. File Organization
  5. Common Pitfalls
  6. Reference Files

Web Architecture

The web stack adds three layers on top of the shared core:

Layer Library Responsibility
Routing + URL state TanStack Router Type-safe navigation, search params, route loaders
Full-stack boundary TanStack Start Server functions (createServerFn), SSR, streaming
Large lists TanStack Virtual Virtualized rendering for 1000+ items

The golden rule: queryOptions as single source of truth

Define query options once, import everywhere — loaders, components, invalidation:

typescript
// queries/posts.ts
export const postsQueryOptions = queryOptions({
  queryKey: ["posts"],
  queryFn: fetchPosts,
  staleTime: 30_000,
});

Router + React Query wiring

The router receives QueryClient as context — the single integration point:

typescript
const router = createRouter({
  routeTree,
  context: { queryClient },
  defaultPreload: "intent",
  defaultPreloadStaleTime: 0, // Let React Query manage staleness
});

declare module "@tanstack/react-router" {
  interface Register {
    router: typeof router;
  }
}

defaultPreloadStaleTime: 0 is intentional — without it, the router caches loader results independently, causing React Query's staleTime to be ignored during preloads.


Route Loader + React Query Pattern

ensureQueryData for blocking, prefetchQuery for non-blocking

typescript
export const Route = createFileRoute('/posts/$postId')({
  loader: async ({ context: { queryClient }, params }) => {
    // Fire-and-forget secondary data
    queryClient.prefetchQuery(commentsQueryOptions(params.postId))
    // Block route render until critical data is ready
    await queryClient.ensureQueryData(postQueryOptions(params.postId))
  },
  component: PostDetail,
})

function PostDetail() {
  const { postId } = Route.useParams()
  // Data guaranteed in cache — instant, no loading state
  const { data: post } = useSuspenseQuery(postQueryOptions(postId))
  return <h1>{post.title}</h1>
}

Avoid waterfall requests

Prefetch all independent data in route loaders using Promise.all:

typescript
loader: async ({ context: { queryClient }, params }) => {
  await Promise.all([
    queryClient.ensureQueryData(userQueryOptions(params.id)),
    queryClient.ensureQueryData(permissionsQueryOptions(params.id)),
  ]);
  // Fire-and-forget for non-critical
  queryClient.prefetchQuery(activityQueryOptions(params.id));
};
  • Never fetch data in useEffect that could go in a route loader
  • Parent and child route loaders run concurrently by default

Performance Patterns

React Compiler (React 19+)

With the compiler enabled:

  • Do not manually wrap components in React.memo
  • Do not manually use useMemo / useCallback for performance
  • Do write idiomatic React — the compiler handles memoization
  • Do ensure code follows Rules of React (no mutation during render)

Manual useMemo/useCallback remain useful only for controlling effect dependencies.

Suspense boundaries placement

  • Route-level boundaries: use pendingComponent / errorComponent on route definitions
  • Within routes: wrap non-blocking data in <Suspense> individually
  • Group co-dependent queries under one <Suspense> so they resolve together
  • Independent queries get separate <Suspense> boundaries

Code splitting

  • Split routes using .lazy() or .lazy.tsx files — critical config (loader, params) stays in the main file, component/UI splits into the lazy file
  • Use React.lazy for heavy on-demand components (rich editors, charts)
  • Machine definitions auto-split since they are separate .ts files

File Organization

text
src/
  routes/                  # TanStack Router file-based routes
    __root.tsx             # Root layout, router context type
    (auth)/                # Route group — no URL impact
    (app)/
      users/
        $userId.tsx
        $userId.lazy.tsx   # Component-only code split
        -components/       # "-" prefix excludes from route tree
  queries/                 # queryOptions definitions — one file per entity
  mutations/               # useMutation wrappers
  machines/                # XState machine definitions (pure TS, no React)
  stores/                  # Zustand stores
  serverFns/               # TanStack Start server functions
  components/
    ui/                    # Design system primitives
    shared/                # Cross-feature shared components
  lib/
    query-client.ts        # QueryClient singleton
    router.ts              # Router singleton
  test/
    setup.ts               # Vitest setup
    test-utils.tsx         # renderWithProviders
    mocks/handlers.ts      # MSW handlers

Key conventions:

  • Route-specific components use - prefix directories to avoid route tree inclusion
  • Pathless route groups (name)/ for organization without URL impact
  • .lazy.tsx files export component/pendingComponent/errorComponent only
  • Co-locate test files next to source (.test.ts / .test.tsx)

Common Pitfalls

  1. Wrong property order in createFileRoute — must be validateSearch -> loaderDeps -> beforeLoad -> loader for TypeScript inference. Install @tanstack/eslint-plugin-router with create-route-property-order rule.

  2. Returning entire search in loaderDeps — invalidates cache on any param change. Extract only the deps the loader uses.

  3. preload="intent" without React Query cache — preloaded data is discarded if user doesn't navigate. Combine with React Query's ensureQueryData for cache persistence.

  4. Not registering the router — without declare module Register, everything is any.

  5. Forgetting <Suspense> around <Await> — runtime error without a Suspense ancestor.

  6. defaultPreloadStaleTime not set to 0 — Router's default staleTime overrides React Query's staleTime during preloads, causing stale data to be served.

  7. useLoaderData in notFoundComponent — not valid. Use Route.useParams() or pass data via throw notFound({ data: ... }).


Reference Files

Read the relevant reference file when working with a specific library:

File When to read
references/router.md Routing, search params, loaders, code splitting, navigation
references/start.md Server functions, SSR, middleware, deployment
references/virtual.md Virtualization, dynamic heights, infinite scroll, grids
references/integration.md Router+Query wiring, auth guards, Suspense placement
references/testing.md Testing Router routes, renderWithProviders

Expand your agent's capabilities with these related and highly-rated skills.

trancong12102/agentskills

deps-dev

Look up the latest stable version of any open-source package across npm, PyPI, Go, Cargo, Maven, and NuGet. Use when the user asks 'what's the latest version of X', 'what version should I use', 'is X deprecated', 'how outdated is my package.json/requirements.txt/Cargo.toml', or needs version numbers for adding or updating dependencies. Also covers pinning versions, checking if packages are maintained, or comparing installed vs latest versions. Do NOT use for private/internal packages or for looking up documentation (use context7).

3 0
Explore
trancong12102/agentskills

github-codebase-search

Semantic search for public GitHub repos without cloning. Use when the user wants to understand how an external library or framework works internally, investigate upstream bugs, trace code paths in a repo they haven't cloned, or search GitHub source code by intent. Do NOT use for local codebase questions (use codebase-search), documentation lookup (use context7), or private repos.

3 0
Explore
trancong12102/agentskills

council-review

Multi-model AI code review — runs Codex, Claude, and Simplify reviews in parallel, then synthesizes a unified report. Use when the user asks to review code changes, audit a diff, check code quality, review a PR, review commits, or review uncommitted changes. Also covers 'code review', 'review my changes', 'check this before I merge', or wanting multiple perspectives on code. Do NOT use for documentation/markdown review or trivial single-line changes.

3 0
Explore
trancong12102/agentskills

react-native-advanced

React Native and Expo patterns for navigation, data fetching lifecycle, infinite scroll lists, form handling, state persistence, authentication routing, gesture-driven animations, bottom sheets, push notifications, and OTA updates. Use when building Expo/React Native apps that need screen-level data prefetching, auth guards with protected routes, infinite scroll feeds, native form input handling, offline-capable state persistence, platform-specific setup (focus/online managers), fluid animations and gesture interactions, modal bottom sheets, push notification flows, or over-the-air update strategies. Do not use for React web apps.

3 0
Explore
trancong12102/agentskills

context7

Fetch up-to-date documentation for any open-source library or framework. Use when the user asks to look up docs, check an API, find code examples, or verify how a feature works — especially with a specific library name, version migration, or phrases like 'what's the current way to...' or 'the API might have changed'. Also covers setup and configuration docs. Do NOT use for general programming concepts, internal project code, or version lookups (use deps-dev).

3 0
Explore
trancong12102/agentskills

ast-grep

Guide for writing ast-grep rules to perform structural code search and analysis. Use when users need to search codebases using Abstract Syntax Tree (AST) patterns, find specific code structures, or perform complex code queries that go beyond simple text search. This skill should be used when users ask to search for code patterns, find specific language constructs, or locate code with particular structural characteristics.

3 0
Explore

Didn't find tool you were looking for?

Be as detailed as possible for better results