tanstack-router-architecture
Skill0 starsChanged 16 days agoMITView on GitHub
Use when creating, moving, or naming files in a frontend-only TanStack Router app (Vite SPA, file-based routes) that also uses TanStack Query, Form, Table, DB, and Devtools, organized by technical layer. Backend is out of scope. Covers routes, components, lib/queries, lib/mutations, lib/collections, import direction, tests, and growth. For full-stack, use tanstack-start-architecture.
- Reads credentials
In this repository7 other files it gives its agents.
The file
Show its rules and text
We split this skill into the rules it gives an agent
20 rules. About 0 are common, 8 are distinctive, and 12 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈8
Distinctive · estimate
This author's own choices. Worth a look.
12
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 17
Read src/ before creating files.
- Distinctive: line 53
Read references/full-tree.md when you need the expanded tree.
- Distinctive: line 55
Add a folder on first use.
- Very specific: line 56
Keep a component in the route's -components/ until a second route uses it, then move it to components/.
- Very specific: line 92
Put tests next to the file.
- Distinctive: line 93
Test queries, mutations, and utils without rendering.
- Very specific: line 94
Put end-to-end tests in e2e/ at the repo root.
- Distinctive: line 98
Read references/growth-stages.md when deciding whether to restructure.
- Very specific: line 102
Use routes/, components/, and lib/.
- Very specific: line 106
Use the default layout. Past about 10 files in a layer, group by resource inside it (lib/queries/billing/).
- Very specific: line 110
Keep the layers. Group by feature inside each layer and mirror it in routes/.
- Distinctive: line 114
Read references/anti-patterns.md when reviewing a layout or before moving files.
- Very specific: line 116
Do not call fetch or the API client from a component.
- Distinctive: line 117
Do not write query keys inline.
- Very specific: line 118
Do not put data fetching in useEffect.
- Very specific: line 119
Do not edit routeTree.gen.ts.
- Very specific: line 120
Do not put non-route files in routes/ without a - prefix.
- Very specific: line 121
Do not copy query data into useState or a store.
- Distinctive: line 122
Do not put backend code in this app.
- Distinctive: line 123
Do not use PascalCase file names.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
TanStack Router architecture
Client-only React app with TanStack Router (file-based routes) on Vite, grouped by technical role. Data code lives in lib/queries, lib/mutations, and lib/collections. The backend is a separate service and is out of scope: the app only calls it through lib/api/. For a full-stack app, use tanstack-start-architecture.
Target version
Written for TanStack Router v1 (file-based, @tanstack/router-plugin), TanStack Query v5, Form, Table, DB, and Devtools on 2026-10-30. TanStack DB moves fast, so check its installed version before copying patterns.
Follow the repo first
Read src/ before creating files. If the project already has conventions (folder names, casing, aliases), use them. Check vite.config.ts for the router plugin options (routesDirectory, code splitting) and tsconfig.json for aliases.
Default directory layout
src/
main.tsx # mounts <RouterProvider />
router.tsx # createRouter, context ({ queryClient }), defaults
routeTree.gen.ts # generated by the plugin. Commit it. Never edit it.
routes/ # file-based routes, thin
__root.tsx # root layout, providers, devtools
index.tsx
invoices/
route.tsx # layout and loader for /invoices
index.tsx
$invoiceId.tsx
-components/ # route-private UI (the - prefix is ignored by the router)
components/ # shared UI used by 2+ routes
ui/ # primitives (Button, Dialog)
forms/ # TanStack Form field components
tables/ # TanStack Table wrappers and column helpers
providers/ # query provider, theme, devtools
hooks/ # shared UI hooks (useDebounce, useInvoiceTable)
lib/
queries/ # query keys and queryOptions, one file per resource
mutations/ # mutationOptions and useMutation hooks
collections/ # TanStack DB collections and live-query helpers
api/ # HTTP client and request functions for the backend
forms/ # createFormHook setup and shared validators
schemas/ # zod (or similar) schemas for forms and responses
auth/ # session helpers, route guards
utils/ # pure helpers
config/ # env parsing and constants
types/ styles/ test/Read references/full-tree.md when you need the expanded tree. Read references/data-layer.md when writing queries, mutations, collections, loaders, forms, or tables.
- Add a folder on first use. Do not create empty ones.
- Keep a component in the route's
-components/until a second route uses it, then move it tocomponents/. - Route files do routing only: path, loader, search schema, and composing components.
Naming conventions
- Files and folders: kebab-case. Route files follow router conventions (
$param,_pathless,route.tsx,index.tsx,-private). - Components:
InvoiceTableininvoice-table.tsx. Named exports, except route files, which exportRoute. - Queries:
invoice.queries.ts, exportinginvoiceKeys,invoiceListOptions,invoiceDetailOptions. - Mutations:
invoice.mutations.ts, exportinguseCreateInvoice,useDeleteInvoice. - Collections:
invoice.collection.ts, exportinginvoiceCollection. - API:
invoice.api.ts. Schemas:invoice.schema.ts. Types:invoice.types.ts. Hooks:use-thing.ts. - Tests:
invoice-table.test.tsxnext to the file. - Imports:
@/maps tosrc/. Never use../../...
Dependency direction
routes -> components -> hooks -> lib/{queries,mutations,collections} -> lib/api -> lib/{schemas,utils}routesmay import any layer below.componentsimporthooks,lib, and other components. Neverroutes.lib/queries,lib/mutations,lib/collectionscalllib/apiandlib/schemas. Never components or hooks.lib/apiimportsconfig,lib/schemas,types. Only it calls the backend.lib/utilsandtypesimport nothing from the app.
Where things live
- Config:
config/env.tsis the only place that readsimport.meta.env. Prefix vars withVITE_. List them in.env.example. - Query client: create in
router.tsxand pass through router context. Provider incomponents/providers/. - Devtools: mount Router, Query, and DB devtools in
routes/__root.tsxorcomponents/providers/devtools.tsx, dev only. - Global client state: prefer router search params and the query cache. Use a small store only for true UI state.
- Auth guards:
beforeLoadin a layout route (_authed/route.tsx), usinglib/auth/.
Tests
- Put tests next to the file. Put setup and helpers in
test/. - Test queries, mutations, and utils without rendering. Test components with a router and query client wrapper.
- Put end-to-end tests in
e2e/at the repo root.
Structure at three sizes
Read references/growth-stages.md when deciding whether to restructure.
Prototype
Use routes/, components/, and lib/. Add lib/queries on first API call.
Mid-size
Use the default layout. Past about 10 files in a layer, group by resource inside it (lib/queries/billing/).
Large
Keep the layers. Group by feature inside each layer and mirror it in routes/. Enforce boundaries with lint rules.
Anti-patterns
Read references/anti-patterns.md when reviewing a layout or before moving files.
- Do not call
fetchor the API client from a component. Uselib/queriesorlib/mutations. - Do not write query keys inline. Use the key factory.
- Do not put data fetching in
useEffect. Use a loader plusensureQueryData. - Do not edit
routeTree.gen.ts. - Do not put non-route files in
routes/without a-prefix. - Do not copy query data into
useStateor a store. - Do not put backend code in this app.
- Do not use PascalCase file names.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

