npx skills add ...
npx skills add tanstack/router --skill router-plugin
TanStack Router bundler plugin for route generation and automatic code splitting. Supports Vite, Webpack, Rspack, and esbuild. Configures autoCodeSplitting, routesDirectory, target framework, and code split groupings.
npx skills add tanstack/router --skill router-plugin
@tanstack/router-plugin)Bundler plugin that powers TanStack Router's file-based routing and automatic code splitting. Works with Vite, Webpack, Rspack, and esbuild via unplugin.
CRITICAL: The router plugin MUST come before the framework plugin (React, Solid, Vue) in the Vite config. Wrong order causes route generation and code splitting to fail silently.
| Option | Type | Default | Description |
|---|---|---|---|
target | 'react' | 'solid' | 'vue' | 'react' | Target framework |
routesDirectory | string | './src/routes' | Directory containing route files |
generatedRouteTree | string | './src/routeTree.gen.ts' | Path for generated route tree |
autoCodeSplitting | boolean | undefined | Enable automatic code splitting |
enableRouteGeneration | boolean | true | Set to false to disable route generation |
| Option | Type | Default | Description |
|---|---|---|---|
routeFilePrefix | string | undefined | Prefix filter for route files |
routeFileIgnorePrefix | string | '-' | Prefix to exclude files from routing |
routeFileIgnorePattern | string | undefined | Pattern to exclude from routing |
indexToken | string | RegExp | { regex: string; flags?: string } | 'index' | Token identifying index routes |
routeToken | string | RegExp | { regex: string; flags?: string } | 'route' | Token identifying route config files |
| Option | Type | Default | Description |
|---|---|---|---|
quoteStyle | 'single' | 'double' | 'single' | Quote style in generated code |
semicolons | boolean | false | Use semicolons in generated code |
disableTypes | boolean | false | Disable TypeScript types |
disableLogging | boolean | false | Suppress plugin logs |
addExtensions | boolean | string | false | Add file extensions to imports |
enableRouteTreeFormatting | boolean | true | Format generated route tree |
The composed plugin assembles up to 3 sub-plugins:
routeTree.gen.tsautoCodeSplitting: true) — Splits route files into lazy-loaded chunks using virtual modulesWhen moving, renaming, adding, or deleting file routes:
routesDirectory. Keep the exported route identifier named Route.pnpm exec tsr generate when the project uses the CLI.routeTree.gen.ts by hand.from narrowing, params, preload calls, and tests that reference the old route.Commit routeTree.gen.ts; it is generated source used by the application at runtime.
For advanced use, each sub-plugin is exported separately from the Vite entry:
The router plugin must come before the framework plugin. Otherwise, route generation and code splitting fail silently.
The target defaults to 'react'. For Solid or Vue, you must set it explicitly.
When autoCodeSplitting is enabled, the plugin handles splitting automatically. You do NOT need manual createLazyRoute or lazyRouteComponent calls — the plugin transforms your route files at build time.
Changes to routeTree.gen.ts are overwritten and can leave source routes, generated types, and runtime routing out of sync. Fix route filenames or plugin configuration, regenerate, and verify the generated diff instead.
// webpack.config.js
const { tanstackRouter } = require('@tanstack/router-plugin/webpack')
module.exports = {
plugins: [
tanstackRouter({
target: 'react',
autoCodeSplitting: true,
}),
],
}// rspack.config.js
const { tanstackRouter } = require('@tanstack/router-plugin/rspack')
module.exports = {
plugins: [
tanstackRouter({
target: 'react',
autoCodeSplitting: true,
}),
],
}import { tanstackRouter } from '@tanstack/router-plugin/esbuild'
import esbuild from 'esbuild'
esbuild.build({
plugins: [
tanstackRouter({
target: 'react',
autoCodeSplitting: true,
}),
],
})tanstackRouter({
target: 'react',
autoCodeSplitting: true,
codeSplittingOptions: {
// Default groupings for all routes
defaultBehavior: [['component'], ['errorComponent'], ['notFoundComponent']],
// Per-route custom splitting
splitBehavior: ({ routeId }) => {
if (routeId === '/dashboard') {
// Keep loader and component together for dashboard
return [['loader', 'component'], ['errorComponent']]
}
// Return undefined to use defaultBehavior
},
},
})import { routes } from './routes'
tanstackRouter({
target: 'react',
virtualRouteConfig: routes, // or './routes.ts'
})import {
tanstackRouter, // Composed (default)
tanstackRouterGenerator, // Generator only
tanStackRouterCodeSplitter, // Code splitter only
} from '@tanstack/router-plugin/vite'// WRONG — react() before tanstackRouter()
plugins: [react(), tanstackRouter({ target: 'react' })]
// CORRECT — tanstackRouter() first
plugins: [tanstackRouter({ target: 'react' }), react()]// WRONG for Solid — generates React imports
tanstackRouter({ autoCodeSplitting: true })
// CORRECT for Solid
tanstackRouter({ target: 'solid', autoCodeSplitting: true })// WRONG — manual lazy loading with autoCodeSplitting enabled
const LazyAbout = lazyRouteComponent(() => import('./about'))
// CORRECT — just write normal route files, plugin handles splitting
// src/routes/about.tsx
export const Route = createFileRoute('/about')({
component: AboutPage,
})
function AboutPage() {
return <h1>About</h1>
}