Skip to main content
The TanStack Router Vite Plugin provides seamless integration with Vite, enabling automatic route generation, code splitting, and hot module replacement (HMR) for your routes.

Installation

Install the Vite plugin as a development dependency:
npm install -D @tanstack/router-plugin
# or
pnpm add -D @tanstack/router-plugin
# or
yarn add -D @tanstack/router-plugin
The @tanstack/router-plugin package provides plugins for multiple bundlers. For Vite-specific functionality, import from @tanstack/router-plugin/vite.

Basic Setup

Add the plugin to your vite.config.ts:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { tanstackRouter } from '@tanstack/router-plugin/vite'

export default defineConfig({
  plugins: [
    tanstackRouter(),
    react(),
  ],
})
Place tanstackRouter() before your framework plugin (e.g., react(), vue(), solid()) in the plugins array.

Configuration

Configure the plugin with an options object:
import { tanstackRouter } from '@tanstack/router-plugin/vite'

export default defineConfig({
  plugins: [
    tanstackRouter({
      target: 'react',
      routesDirectory: './src/routes',
      generatedRouteTree: './src/routeTree.gen.ts',
      quoteStyle: 'single',
      semicolons: false,
      autoCodeSplitting: true,
    }),
    react(),
  ],
})

Configuration Options

target
'react' | 'solid' | 'vue'
default:"react"
The framework you’re using with TanStack Router
routesDirectory
string
default:"./src/routes"
The directory containing your route files
generatedRouteTree
string
default:"./src/routeTree.gen.ts"
Where to output the generated route tree file
routeFilePrefix
string
Optional prefix for route files (e.g., “route” matches “route.home.tsx”)
routeFileIgnorePrefix
string
default:"-"
Files starting with this prefix will be ignored
routeFileIgnorePattern
string
A regex pattern for files to ignore
quoteStyle
'single' | 'double'
default:"single"
Quote style for generated code
semicolons
boolean
default:false
Whether to include semicolons in generated code
autoCodeSplitting
boolean
Automatically enable code splitting for your routes
disableTypes
boolean
default:false
Disable TypeScript type generation
disableLogging
boolean
default:false
Disable plugin logging output
addExtensions
boolean | string
default:false
Add file extensions to imports. Can be true for .js or a custom extension
codeSplittingOptions
CodeSplittingOptions
Advanced code splitting configuration (see below)

Code Splitting

The plugin supports automatic code splitting to optimize your bundle size:
import { tanstackRouter } from '@tanstack/router-plugin/vite'

export default defineConfig({
  plugins: [
    tanstackRouter({
      autoCodeSplitting: true,
      codeSplittingOptions: {
        // Default behavior: split each type of component separately
        defaultBehavior: [
          ['component'],
          ['pendingComponent'],
          ['errorComponent'],
          ['notFoundComponent'],
        ],
        // Programmatically control splitting per route
        splitBehavior: ({ routeId }) => {
          // Don't split the home route
          if (routeId === '/') {
            return undefined
          }
          // Custom split groups for admin routes
          if (routeId.startsWith('/admin')) {
            return [
              ['component', 'pendingComponent'],
              ['errorComponent', 'notFoundComponent'],
            ]
          }
          // Use default for other routes
          return undefined
        },
        // Remove nodes from routes during code splitting
        deleteNodes: ['loader'],
        // Enable HMR for code split routes
        addHmr: true,
      },
    }),
    react(),
  ],
})

Code Splitting Options

defaultBehavior
CodeSplitGroupings
Default grouping strategy for route components:
// Each component in its own chunk
[['component'], ['pendingComponent'], ['errorComponent'], ['notFoundComponent']]

// Group error states together
[['component'], ['pendingComponent'], ['errorComponent', 'notFoundComponent']]

// All components in one chunk
[['component', 'pendingComponent', 'errorComponent', 'notFoundComponent']]
splitBehavior
(params: { routeId: string }) => CodeSplitGroupings | undefined
Function to control splitting behavior per route. Return undefined to use defaultBehavior
deleteNodes
Array<string>
Route properties to remove during code splitting (e.g., ['loader', 'action'])
addHmr
boolean
default:true
Enable hot module replacement for code-split route components

Framework-Specific Configuration

React

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { tanstackRouter } from '@tanstack/router-plugin/vite'

export default defineConfig({
  plugins: [
    tanstackRouter({
      target: 'react',
    }),
    react(),
  ],
})

Solid

import { defineConfig } from 'vite'
import solid from 'vite-plugin-solid'
import { tanstackRouter } from '@tanstack/router-plugin/vite'

export default defineConfig({
  plugins: [
    tanstackRouter({
      target: 'solid',
    }),
    solid(),
  ],
})

Vue

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { tanstackRouter } from '@tanstack/router-plugin/vite'

export default defineConfig({
  plugins: [
    tanstackRouter({
      target: 'vue',
    }),
    vue(),
  ],
})

Specialized Plugins

The package exports specialized plugins for specific use cases:

Route Generator Only

Only generate routes without code splitting:
import { tanstackRouterGenerator } from '@tanstack/router-plugin/vite'

export default defineConfig({
  plugins: [
    tanstackRouterGenerator(),
    react(),
  ],
})

Code Splitter Only

Only handle code splitting (requires pre-generated routes):
import { tanStackRouterCodeSplitter } from '@tanstack/router-plugin/vite'

export default defineConfig({
  plugins: [
    tanStackRouterCodeSplitter(),
    react(),
  ],
})

Route Auto-Import

Automatically import route files:
import { tanstackRouterAutoImport } from '@tanstack/router-plugin/vite'

export default defineConfig({
  plugins: [
    tanstackRouterAutoImport(),
    react(),
  ],
})

Environment-Specific Configuration

The plugin supports Vite’s environment API:
import { tanstackRouter } from '@tanstack/router-plugin/vite'

export default defineConfig({
  plugins: [
    tanstackRouter({
      plugin: {
        vite: {
          // Specify which Vite environment to use
          environmentName: 'client',
        },
      },
    }),
    react(),
  ],
})

Hot Module Replacement (HMR)

The plugin automatically configures HMR for your routes:
  • Route components are hot-reloaded without full page refresh
  • Route configuration changes trigger route tree regeneration
  • Maintains router state during HMR updates
  • Works with code-split routes
No additional configuration required!

Using with TypeScript

The plugin generates TypeScript types automatically. Ensure the generated route tree is included in your tsconfig.json:
{
  "compilerOptions": {
    "strict": true
  },
  "include": [
    "src",
    "src/routeTree.gen.ts"
  ]
}

Alternative: Standalone Vite Plugin Package

You can also use the standalone Vite plugin package:
npm install -D @tanstack/router-vite-plugin
import { tanstackRouter } from '@tanstack/router-vite-plugin'
This package is a thin wrapper around @tanstack/router-plugin/vite. Both approaches are equivalent.

Migration from CLI

If you’re currently using the CLI (tsr watch), migrate to the Vite plugin: Before:
{
  "scripts": {
    "dev": "tsr watch & vite"
  }
}
After:
{
  "scripts": {
    "dev": "vite"
  }
}
Update your vite.config.ts:
import { tanstackRouter } from '@tanstack/router-plugin/vite'

export default defineConfig({
  plugins: [tanstackRouter(), react()],
})

Troubleshooting

Plugin order matters

Always place the router plugin before your framework plugin:
// ✅ Correct
plugins: [tanstackRouter(), react()]

// ❌ Wrong
plugins: [react(), tanstackRouter()]

Routes not generating

  1. Verify routesDirectory path is correct
  2. Check that route files match the expected naming convention
  3. Ensure Vite dev server is running
  4. Check the console for plugin errors

HMR not working

  1. Verify the plugin is before your framework plugin
  2. Check that addHmr is not set to false in code splitting options
  3. Restart the Vite dev server

Type errors

  1. Ensure the generated route tree is included in tsconfig.json
  2. Restart your TypeScript server
  3. Run tsc --noEmit to check for errors

Code splitting issues

  1. Verify autoCodeSplitting is set to true
  2. Check your splitBehavior function returns valid groupings
  3. Ensure route components are exported correctly

Build docs developers (and LLMs) love