Virtual routes not resolving package aliases correctly in monorepo setup
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 15.1k
- Forks
- 1.9k
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 143
Description
Which project does this relate to?
Router
Describe the bug
When using virtual routes in a monorepo setup with TanStack Router, package aliases (e.g., @module/auth) are being resolved relative to the app directory instead of being treated as package imports.
In a typical monorepo structure where domain modules are organized as separate packages, virtual routes should be able to import from these packages using their package names or configured aliases. However, the current implementation appears to resolve these paths as relative file paths from the app directory.
For example:
Expected resolution: @module/auth/routes/sign-up/index.tsx → packages/auth/routes/sign-up/index.tsx
Actual resolution: @module/auth/routes/sign-up/index.tsx → apps/web/@module/auth/routes/sign-up/index.tsx
This prevents implementing a true Domain-Driven Design (DDD) architecture where each domain module (authentication, billing, etc.) is a self-contained package with its own pages, components, and business logic.
Your Example Website or App
https://tanstack.com/router/latest/docs/framework/react/routing/virtual-file-routes
Steps to Reproduce the Bug or Issue
- Set up a monorepo structure with the following layout:
my-app/
├── apps/
│ └── web/
│ ├── routes/
│ ├── routes.ts
│ └── package.json
├── packages/
│ └── auth/
│ ├── routes/
│ │ └── sign-up/
│ │ └── index.tsx
│ └── package.json (name: "@module/auth")
- Configure virtual routes in apps/web/routes.ts:
import {
rootRoute,
route,
layout,
} from '@tanstack/virtual-file-routes'
export const routes = rootRoute('root.tsx', [
layout('layout.tsx', [
route('/auth', [
route('/sign-up', '@module/auth/routes/sign-up/index.tsx'),
]),
]),
])
- Configure TypeScript paths or package resolution for @module/* to point to packages/*
- Run the application and observe that the router attempts to resolve the path as apps/web/@module/auth/routes/sign-up/index.tsx instead of using the package import
Expected behavior
Virtual routes should support package imports and module resolution consistent with the build tool and TypeScript configuration. When specifying a path like @module/auth/routes/sign-up/index.tsx, the router should:
Recognize package aliases or scoped packages (e.g., @module/auth)
Resolve them according to the project's module resolution configuration (tsconfig paths, package.json imports, or node_modules resolution)
Allow true modular architecture where routes can be distributed across packages in a monorepo
This would enable proper Domain-Driven Design patterns where each domain package can export its own routes while maintaining clear boundaries and dependencies.
Screenshots or Videos
No response
Platform
- Router Version: 1.130.2
- OS: Linux
- Browser: Chrome
- Browser Version: 139.0.7258.66 (Official Build) (64-bit)
- Bundler: vite with turborepo
- Bundler Version: 6.3.5
Additional context
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the virtual route declaration in apps/web/routes.ts and reproduce the package-alias case using Vite with turborepo. Trace how @module/auth/routes/sign-up/index.tsx is resolved by @tanstack/virtual-file-routes, then verify that the package alias follows the configured module resolution instead of becoming an apps/web-relative path.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript, vite
- Domain
- build-system, frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100