Configuring TanStack Router and routeTree.gen in OpenCut Web App: Complete Guide
OpenCut configures TanStack Router using a file-system-based approach where routeTree.gen.ts is auto-generated from src/routes/*.tsx files via the TanStack Router Vite plugin, enabling type-safe navigation with lazy-loaded code splitting.
The OpenCut video editing platform uses TanStack Router to power its React frontend in the apps/web workspace. This configuration leverages file-based routing conventions combined with a generated route tree to enforce end-to-end type safety across the navigation layer.
Core Router Setup in router.tsx
The router instance is centralized in apps/web/src/router.tsx, where it consumes the generated static tree and applies global navigation behaviors.
Instantiating the Router
The getRouter() function creates the TanStack Router instance using createRouter from @tanstack/react-router:
import { createRouter as createTanStackRouter } from '@tanstack/react-router'
import { routeTree } from './routeTree.gen'
export function getRouter() {
const router = createTanStackRouter({
routeTree,
scrollRestoration: true,
defaultPreload: 'intent',
defaultPreloadStaleTime: 0,
})
return router
}
The routeTree import comes from the generated file routeTree.gen.ts, which contains the statically analyzed route hierarchy.
Performance and Preloading Configuration
OpenCut optimizes perceived performance through aggressive preloading strategies configured at the router level:
scrollRestoration: true– Preserves scroll positions during back/forward navigationdefaultPreload: 'intent'– Triggers route loading when users hover over or focus<Link>componentsdefaultPreloadStaleTime: 0– Ensures fresh data fetching on every navigation intent, preventing stale cached preloads
Global Type Registration
TypeScript augmentation ensures the router type is available globally without prop drilling:
declare module '@tanstack/react-router' {
interface Register {
router: ReturnType<typeof getRouter>
}
}
This declaration allows the useRouter hook to infer types automatically throughout the application.
Understanding routeTree.gen.ts
The routeTree.gen.ts file in apps/web/src/ serves as the single source of truth for the route hierarchy, but should never be edited manually.
Automatic Generation via Vite Plugin
The TanStack Router Vite plugin (configured in vite.config.ts) watches the src/routes/ directory and regenerates this file whenever:
- New
.tsxfiles are added tosrc/routes/ - Existing route files are modified
- Route definitions change their path strings
Static Tree Structure
The generated file imports route objects from individual files and wires them into a parent-child hierarchy:
import { Route as rootRouteImport } from './routes/__root'
import { Route as IndexRouteImport } from './routes/index'
const IndexRoute = IndexRouteImport.update({
id: '/',
path: '/',
getParentRoute: () => rootRouteImport,
} as any)
export const routeTree = rootRouteImport
._addFileChildren({ IndexRoute })
._addFileTypes<FileRouteTypes>()
The rootRouteImport from __root.tsx acts as the apex node, with all page routes registered as children via _addFileChildren().
Root Route Setup in __root.tsx
Every TanStack Router application requires a root route that provides the HTML document shell. OpenCut defines this in apps/web/src/routes/__root.tsx.
Global Document Shell
The createRootRoute function configures document-level head elements and global providers:
import { createRootRoute } from '@tanstack/react-router'
import { TooltipProvider } from '../components/ui/tooltip'
import appCss from '../styles.css?url'
export const Route = createRootRoute({
head: () => ({
meta: [
{ charSet: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ title: 'OpenCut rewrite — beta.opencut.app' }
],
links: [
{ rel: 'stylesheet', href: appCss },
{ rel: 'preconnect', href: 'https://fonts.googleapis.com' },
],
}),
shellComponent: RootDocument,
})
The shellComponent prop accepts a RootDocument component that wraps the application with the TooltipProvider and other UI primitives.
DevTools Integration
In development mode, the root route includes TanStack Router Devtools and TanStack Query Devtools panels for debugging navigation state and data fetching.
Adding New Routes to OpenCut
Extending the routing layer requires only adding files to the src/routes/ directory, following TanStack Router's file-based conventions.
Creating Route Files with createFileRoute
To add a Settings page at /settings, create apps/web/src/routes/settings.tsx:
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/settings')({
component: SettingsPage,
})
function SettingsPage() {
return (
<div className="p-4">
<h1 className="text-2xl font-bold">Settings</h1>
<p>Configure your OpenCut preferences here.</p>
</div>
)
}
The createFileRoute function requires a string literal path that matches the file's location within src/routes/. The Vite plugin detects this export and updates routeTree.gen.ts accordingly.
Navigation and Preloading Behavior
Navigate to routes using the Link component, which automatically benefits from the defaultPreload: 'intent' configuration:
import { Link } from '@tanstack/react-router'
function Navigation() {
return (
<nav>
<Link to="/">Home</Link>
<Link to="/settings">Settings</Link>
</nav>
)
}
When users hover over these links, TanStack Router begins loading the route component and data immediately, resulting in near-instant navigation.
Summary
- File-based routing: OpenCut uses
src/routes/*.tsxfiles where each exports aRouteobject created withcreateFileRoute - Auto-generated tree: The
routeTree.gen.tsfile is regenerated automatically by the TanStack Router Vite plugin and should not be manually edited - Centralized configuration:
router.tsxconfigures global behaviors including scroll restoration and intent-based preloading - Type safety: Module augmentation in
router.tsxensures the router type is available globally throughuseRouter - Root scaffolding:
__root.tsxprovides the document shell and wraps the application with global providers likeTooltipProvider
Frequently Asked Questions
How does OpenCut regenerate routeTree.gen.ts?
The regeneration happens automatically through the TanStack Router Vite plugin configured in vite.config.ts. Whenever you add, remove, or modify files in src/routes/, the plugin detects the filesystem change and regenerates routeTree.gen.ts before the hot module replacement (HMR) completes. This ensures the type-safe route tree always matches your file structure without manual intervention.
What is the purpose of __root.tsx in the OpenCut router?
The __root.tsx file defines the root route using createRootRoute, which serves as the parent for all other routes in the application. It provides the global HTML document structure through the head configuration (meta tags, CSS links) and the shellComponent property. All page routes become children of this root, inheriting its layout and global context providers like the tooltip system.
Why should I not edit routeTree.gen.ts manually?
routeTree.gen.ts is an auto-generated artifact that imports concrete route implementations from individual files and assembles them into a static tree structure using internal methods like _addFileChildren(). Manual edits would be overwritten immediately by the Vite plugin and could introduce type mismatches between the generated tree and the actual route file exports. Route changes should always be made in the source src/routes/ files.
How does intent-based preloading work in OpenCut's TanStack Router setup?
Intent-based preloading, configured via defaultPreload: 'intent' in router.tsx, instructs TanStack Router to begin fetching route code and data when the user signals navigation intent, typically by hovering over or focusing a <Link> component. With defaultPreloadStaleTime: 0, each intent triggers a fresh fetch, ensuring users see current data while maintaining the performance benefits of early loading before the actual navigation occurs.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →