diff --git a/docs/router/framework/react/routing/virtual-file-routes.md b/docs/router/framework/react/routing/virtual-file-routes.md
index 3e308ee7c9..a285a49223 100644
--- a/docs/router/framework/react/routing/virtual-file-routes.md
+++ b/docs/router/framework/react/routing/virtual-file-routes.md
@@ -224,6 +224,43 @@ export const routes = rootRoute('root.tsx', [
 ])
 ```
 
+### Merging Physical Routes at Current Level
+
+You can also use `physical` with an empty path prefix (or a single argument) to merge routes from a physical directory directly at the current level, without adding a path prefix. This is useful when you want to organize your routes into separate directories but have them appear at the same URL level.
+
+Consider the following file structure:
+
+```
+/routes
+├── __root.tsx
+├── about.tsx
+└── features
+    ├── index.tsx
+    └── contact.tsx
+```
+
+You can merge the `features` directory routes at the root level:
+
+```tsx
+// routes.ts
+import { physical, rootRoute, route } from '@tanstack/virtual-file-routes'
+
+export const routes = rootRoute('__root.tsx', [
+  route('/about', 'about.tsx'),
+  // Merge features/ routes at root level (no path prefix)
+  physical('features'),
+  // Or equivalently: physical('', 'features')
+])
+```
+
+This will produce the following routes:
+
+- `/about` - from `about.tsx`
+- `/` - from `features/index.tsx`
+- `/contact` - from `features/contact.tsx`
+
+> **Note:** When merging at the same level, ensure there are no conflicting route paths between your virtual routes and the physical directory routes. If a conflict occurs (e.g., both have an `/about` route), the generator will throw an error.
+
 ## Virtual Routes inside of TanStack Router File Based routing
 
 The previous section showed you how you can use TanStack Router's File Based routing convention inside of a virtual route configuration.
diff --git a/packages/router-generator/src/generator.ts b/packages/router-generator/src/generator.ts
index 0ecb325cee..01f485581f 100644
--- a/packages/router-generator/src/generator.ts
+++ b/packages/router-generator/src/generator.ts
@@ -1090,9 +1090,22 @@ ${acc.routeTree.map((child) => `${child.variableName}Route: typeof ${getResolved
       })
 
       if (transformResult.result === 'no-route-export') {
-        this.logger.warn(
-          `Route file "${node.fullPath}" does not contain any route piece. This is likely a mistake.`,
-        )
+        const fileName = path.basename(node.fullPath)
+        const dirName = path.dirname(node.fullPath)
+        const ignorePrefix = this.config.routeFileIgnorePrefix
+        const ignorePattern = this.config.routeFileIgnorePattern
+        const suggestedFileName = `${ignorePrefix}${fileName}`
+        const suggestedFullPath = path.join(dirName, suggestedFileName)
+
+        let message = `Warning: Route file "${node.fullPath}" does not export a Route. This file will not be included in the route tree.`
+        message += `\n\nIf this file is not intended to be a route, you can exclude it using one of these options:`
+        message += `\n  1. Rename the file to "${suggestedFullPath}" (prefix with "${ignorePrefix}")`
+        message += `\n  2. Use 'routeFileIgnorePattern' in your config to match this file`
+        message += `\n\nCurrent configuration:`
+        message += `\n  routeFileIgnorePrefix: "${ignorePrefix}"`
+        message += `\n  routeFileIgnorePattern: ${ignorePattern ? `"${ignorePattern}"` : 'undefined'}`
+
+        this.logger.warn(message)
         return null
       }
       if (transformResult.result === 'error') {
diff --git a/packages/router-generator/tests/generator.test.ts b/packages/router-generator/tests/generator.test.ts
index 42594d7b0c..40c66e30ed 100644
--- a/packages/router-generator/tests/generator.test.ts
+++ b/packages/router-generator/tests/generator.test.ts
@@ -104,6 +104,18 @@ function rewriteConfigByFolderName(folderName: string, config: Config) {
     case 'virtual-config-file-default-export':
       config.virtualRouteConfig = './routes.ts'
       break
+    case 'virtual-physical-empty-path-merge':
+      config.virtualRouteConfig = './routes.ts'
+      break
+    case 'virtual-physical-empty-path-conflict-root':
+      config.virtualRouteConfig = './routes.ts'
+      break
+    case 'virtual-physical-empty-path-conflict-virtual':
+      config.virtualRouteConfig = './routes.ts'
+      break
+    case 'virtual-physical-no-prefix':
+      config.virtualRouteConfig = './routes.ts'
+      break
     case 'virtual-with-escaped-underscore':
       {
         // Test case for escaped underscores in physical routes mounted via virtual config
@@ -243,6 +255,12 @@ function shouldThrow(folderName: string) {
   if (folderName === 'duplicate-fullPath') {
     return `Conflicting configuration paths were found for the following routes: "/", "/".`
   }
+  if (folderName === 'virtual-physical-empty-path-conflict-root') {
+    return `Conflicting configuration paths were found for the following routes: "/__root", "/__root".`
+  }
+  if (folderName === 'virtual-physical-empty-path-conflict-virtual') {
+    return `Conflicting configuration paths were found for the following routes: "/about", "/about".`
+  }
   return undefined
 }
 
diff --git a/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes.ts b/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes.ts
new file mode 100644
index 0000000000..c2b6660fc3
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes.ts
@@ -0,0 +1,5 @@
+import { physical, rootRoute } from '@tanstack/virtual-file-routes'
+
+// This test verifies that a __root.tsx in a physical directory mounted at root
+// produces a proper conflict error with the virtual root
+export const routes = rootRoute('__root.tsx', [physical('', 'merged')])
diff --git a/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/__root.tsx b/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/__root.tsx
new file mode 100644
index 0000000000..f463b796b4
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/__root.tsx
@@ -0,0 +1,5 @@
+import { createRootRoute, Outlet } from '@tanstack/react-router'
+
+export const Route = createRootRoute({
+  component: () => <Outlet />,
+})
diff --git a/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/index.tsx b/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/index.tsx
new file mode 100644
index 0000000000..bad00da72c
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/index.tsx
@@ -0,0 +1,5 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+export const Route = createFileRoute('/')({
+  component: () => <div>Index</div>,
+})
diff --git a/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx b/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx
new file mode 100644
index 0000000000..a164afcb81
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx
@@ -0,0 +1,5 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+// This route.tsx in a physical directory mounted at root level
+// conflicts with the virtual root __root.tsx - can't have two root routes
+export const Route = createFileRoute('')({})
diff --git a/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/tsr.config.json b/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/tsr.config.json
new file mode 100644
index 0000000000..4d587108e3
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/tsr.config.json
@@ -0,0 +1,5 @@
+{
+  "routesDirectory": "./routes",
+  "generatedRouteTree": "./routeTree.gen.ts",
+  "virtualRouteConfig": "./routes.ts"
+}
diff --git a/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes.ts b/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes.ts
new file mode 100644
index 0000000000..1a6c713d51
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes.ts
@@ -0,0 +1,8 @@
+import { physical, rootRoute, route } from '@tanstack/virtual-file-routes'
+
+// This test verifies that a virtual route path conflicts with
+// a physical route path when using empty path prefix
+export const routes = rootRoute('__root.tsx', [
+  route('/about', 'about.tsx'), // virtual /about
+  physical('', 'merged'), // physical also has about.tsx -> /about
+])
diff --git a/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/__root.tsx b/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/__root.tsx
new file mode 100644
index 0000000000..f463b796b4
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/__root.tsx
@@ -0,0 +1,5 @@
+import { createRootRoute, Outlet } from '@tanstack/react-router'
+
+export const Route = createRootRoute({
+  component: () => <Outlet />,
+})
diff --git a/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/about.tsx b/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/about.tsx
new file mode 100644
index 0000000000..47bedea6c8
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/about.tsx
@@ -0,0 +1,6 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+// Virtual about route - conflicts with merged/about.tsx
+export const Route = createFileRoute('/about')({
+  component: () => <div>About (virtual)</div>,
+})
diff --git a/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/about.tsx b/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/about.tsx
new file mode 100644
index 0000000000..6b15c67503
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/about.tsx
@@ -0,0 +1,6 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+// Physical about route - conflicts with virtual about.tsx -> /about
+export const Route = createFileRoute('/about')({
+  component: () => <div>About (physical)</div>,
+})
diff --git a/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/index.tsx b/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/index.tsx
new file mode 100644
index 0000000000..bad00da72c
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/index.tsx
@@ -0,0 +1,5 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+export const Route = createFileRoute('/')({
+  component: () => <div>Index</div>,
+})
diff --git a/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/tsr.config.json b/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/tsr.config.json
new file mode 100644
index 0000000000..4d587108e3
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/tsr.config.json
@@ -0,0 +1,5 @@
+{
+  "routesDirectory": "./routes",
+  "generatedRouteTree": "./routeTree.gen.ts",
+  "virtualRouteConfig": "./routes.ts"
+}
diff --git a/packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routeTree.snapshot.ts b/packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routeTree.snapshot.ts
new file mode 100644
index 0000000000..6de1ed6975
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routeTree.snapshot.ts
@@ -0,0 +1,95 @@
+/* eslint-disable */
+
+// @ts-nocheck
+
+// noinspection JSUnusedGlobalSymbols
+
+// This file was automatically generated by TanStack Router.
+// You should NOT make any changes in this file as it will be overwritten.
+// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
+
+import { Route as rootRouteImport } from './routes/__root'
+import { Route as ContactRouteImport } from './routes/merged/contact'
+import { Route as aboutRouteImport } from './routes/about'
+import { Route as IndexRouteImport } from './routes/merged/index'
+
+const ContactRoute = ContactRouteImport.update({
+  id: '/contact',
+  path: '/contact',
+  getParentRoute: () => rootRouteImport,
+} as any)
+const aboutRoute = aboutRouteImport.update({
+  id: '/about',
+  path: '/about',
+  getParentRoute: () => rootRouteImport,
+} as any)
+const IndexRoute = IndexRouteImport.update({
+  id: '/',
+  path: '/',
+  getParentRoute: () => rootRouteImport,
+} as any)
+
+export interface FileRoutesByFullPath {
+  '/': typeof IndexRoute
+  '/about': typeof aboutRoute
+  '/contact': typeof ContactRoute
+}
+export interface FileRoutesByTo {
+  '/': typeof IndexRoute
+  '/about': typeof aboutRoute
+  '/contact': typeof ContactRoute
+}
+export interface FileRoutesById {
+  __root__: typeof rootRouteImport
+  '/': typeof IndexRoute
+  '/about': typeof aboutRoute
+  '/contact': typeof ContactRoute
+}
+export interface FileRouteTypes {
+  fileRoutesByFullPath: FileRoutesByFullPath
+  fullPaths: '/' | '/about' | '/contact'
+  fileRoutesByTo: FileRoutesByTo
+  to: '/' | '/about' | '/contact'
+  id: '__root__' | '/' | '/about' | '/contact'
+  fileRoutesById: FileRoutesById
+}
+export interface RootRouteChildren {
+  IndexRoute: typeof IndexRoute
+  aboutRoute: typeof aboutRoute
+  ContactRoute: typeof ContactRoute
+}
+
+declare module '@tanstack/react-router' {
+  interface FileRoutesByPath {
+    '/contact': {
+      id: '/contact'
+      path: '/contact'
+      fullPath: '/contact'
+      preLoaderRoute: typeof ContactRouteImport
+      parentRoute: typeof rootRouteImport
+    }
+    '/about': {
+      id: '/about'
+      path: '/about'
+      fullPath: '/about'
+      preLoaderRoute: typeof aboutRouteImport
+      parentRoute: typeof rootRouteImport
+    }
+    '/': {
+      id: '/'
+      path: '/'
+      fullPath: '/'
+      preLoaderRoute: typeof IndexRouteImport
+      parentRoute: typeof rootRouteImport
+    }
+  }
+}
+
+const rootRouteChildren: RootRouteChildren = {
+  IndexRoute: IndexRoute,
+  aboutRoute: aboutRoute,
+  ContactRoute: ContactRoute,
+}
+export const routeTree = rootRouteImport
+  ._addFileChildren(rootRouteChildren)
+  ._addFileTypes<FileRouteTypes>()
diff --git a/packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes.ts b/packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes.ts
new file mode 100644
index 0000000000..c429574e1a
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes.ts
@@ -0,0 +1,8 @@
+import { physical, rootRoute, route } from '@tanstack/virtual-file-routes'
+
+export const routes = rootRoute('__root.tsx', [
+  // Virtual route defined here
+  route('/about', 'about.tsx'),
+  // Physical mount with empty path - should merge into root level
+  physical('', 'merged'),
+])
diff --git a/packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/__root.tsx b/packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/__root.tsx
new file mode 100644
index 0000000000..9c657c7d5b
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/__root.tsx
@@ -0,0 +1,3 @@
+import { createRootRoute } from '@tanstack/react-router'
+
+export const Route = createRootRoute()
diff --git a/packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/about.tsx b/packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/about.tsx
new file mode 100644
index 0000000000..e56767c8ad
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/about.tsx
@@ -0,0 +1,2 @@
+import { createFileRoute } from '@tanstack/react-router'
+export const Route = createFileRoute('/about')()
diff --git a/packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/merged/contact.tsx b/packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/merged/contact.tsx
new file mode 100644
index 0000000000..12a392def8
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/merged/contact.tsx
@@ -0,0 +1,2 @@
+import { createFileRoute } from '@tanstack/react-router'
+export const Route = createFileRoute('/contact')()
diff --git a/packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/merged/index.tsx b/packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/merged/index.tsx
new file mode 100644
index 0000000000..d1d6296bab
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/merged/index.tsx
@@ -0,0 +1,2 @@
+import { createFileRoute } from '@tanstack/react-router'
+export const Route = createFileRoute('/')()
diff --git a/packages/router-generator/tests/generator/virtual-physical-empty-path-merge/tsr.config.json b/packages/router-generator/tests/generator/virtual-physical-empty-path-merge/tsr.config.json
new file mode 100644
index 0000000000..4d587108e3
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-empty-path-merge/tsr.config.json
@@ -0,0 +1,5 @@
+{
+  "routesDirectory": "./routes",
+  "generatedRouteTree": "./routeTree.gen.ts",
+  "virtualRouteConfig": "./routes.ts"
+}
diff --git a/packages/router-generator/tests/generator/virtual-physical-no-prefix/routeTree.snapshot.ts b/packages/router-generator/tests/generator/virtual-physical-no-prefix/routeTree.snapshot.ts
new file mode 100644
index 0000000000..6de1ed6975
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-no-prefix/routeTree.snapshot.ts
@@ -0,0 +1,95 @@
+/* eslint-disable */
+
+// @ts-nocheck
+
+// noinspection JSUnusedGlobalSymbols
+
+// This file was automatically generated by TanStack Router.
+// You should NOT make any changes in this file as it will be overwritten.
+// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
+
+import { Route as rootRouteImport } from './routes/__root'
+import { Route as ContactRouteImport } from './routes/merged/contact'
+import { Route as aboutRouteImport } from './routes/about'
+import { Route as IndexRouteImport } from './routes/merged/index'
+
+const ContactRoute = ContactRouteImport.update({
+  id: '/contact',
+  path: '/contact',
+  getParentRoute: () => rootRouteImport,
+} as any)
+const aboutRoute = aboutRouteImport.update({
+  id: '/about',
+  path: '/about',
+  getParentRoute: () => rootRouteImport,
+} as any)
+const IndexRoute = IndexRouteImport.update({
+  id: '/',
+  path: '/',
+  getParentRoute: () => rootRouteImport,
+} as any)
+
+export interface FileRoutesByFullPath {
+  '/': typeof IndexRoute
+  '/about': typeof aboutRoute
+  '/contact': typeof ContactRoute
+}
+export interface FileRoutesByTo {
+  '/': typeof IndexRoute
+  '/about': typeof aboutRoute
+  '/contact': typeof ContactRoute
+}
+export interface FileRoutesById {
+  __root__: typeof rootRouteImport
+  '/': typeof IndexRoute
+  '/about': typeof aboutRoute
+  '/contact': typeof ContactRoute
+}
+export interface FileRouteTypes {
+  fileRoutesByFullPath: FileRoutesByFullPath
+  fullPaths: '/' | '/about' | '/contact'
+  fileRoutesByTo: FileRoutesByTo
+  to: '/' | '/about' | '/contact'
+  id: '__root__' | '/' | '/about' | '/contact'
+  fileRoutesById: FileRoutesById
+}
+export interface RootRouteChildren {
+  IndexRoute: typeof IndexRoute
+  aboutRoute: typeof aboutRoute
+  ContactRoute: typeof ContactRoute
+}
+
+declare module '@tanstack/react-router' {
+  interface FileRoutesByPath {
+    '/contact': {
+      id: '/contact'
+      path: '/contact'
+      fullPath: '/contact'
+      preLoaderRoute: typeof ContactRouteImport
+      parentRoute: typeof rootRouteImport
+    }
+    '/about': {
+      id: '/about'
+      path: '/about'
+      fullPath: '/about'
+      preLoaderRoute: typeof aboutRouteImport
+      parentRoute: typeof rootRouteImport
+    }
+    '/': {
+      id: '/'
+      path: '/'
+      fullPath: '/'
+      preLoaderRoute: typeof IndexRouteImport
+      parentRoute: typeof rootRouteImport
+    }
+  }
+}
+
+const rootRouteChildren: RootRouteChildren = {
+  IndexRoute: IndexRoute,
+  aboutRoute: aboutRoute,
+  ContactRoute: ContactRoute,
+}
+export const routeTree = rootRouteImport
+  ._addFileChildren(rootRouteChildren)
+  ._addFileTypes<FileRouteTypes>()
diff --git a/packages/router-generator/tests/generator/virtual-physical-no-prefix/routes.ts b/packages/router-generator/tests/generator/virtual-physical-no-prefix/routes.ts
new file mode 100644
index 0000000000..0fa8033c6d
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-no-prefix/routes.ts
@@ -0,0 +1,8 @@
+import { physical, rootRoute, route } from '@tanstack/virtual-file-routes'
+
+// This test verifies the single-argument physical() overload
+// which uses an empty path prefix (merges at current level)
+export const routes = rootRoute('__root.tsx', [
+  route('/about', 'about.tsx'),
+  physical('merged'), // Single argument - merges at root
+])
diff --git a/packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/__root.tsx b/packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/__root.tsx
new file mode 100644
index 0000000000..f463b796b4
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/__root.tsx
@@ -0,0 +1,5 @@
+import { createRootRoute, Outlet } from '@tanstack/react-router'
+
+export const Route = createRootRoute({
+  component: () => <Outlet />,
+})
diff --git a/packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/about.tsx b/packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/about.tsx
new file mode 100644
index 0000000000..51df2dd30e
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/about.tsx
@@ -0,0 +1,5 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+export const Route = createFileRoute('/about')({
+  component: () => <div>About</div>,
+})
diff --git a/packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/contact.tsx b/packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/contact.tsx
new file mode 100644
index 0000000000..77fd4df532
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/contact.tsx
@@ -0,0 +1,5 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+export const Route = createFileRoute('/contact')({
+  component: () => <div>Contact</div>,
+})
diff --git a/packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/index.tsx b/packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/index.tsx
new file mode 100644
index 0000000000..bad00da72c
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/index.tsx
@@ -0,0 +1,5 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+export const Route = createFileRoute('/')({
+  component: () => <div>Index</div>,
+})
diff --git a/packages/router-generator/tests/generator/virtual-physical-no-prefix/tsr.config.json b/packages/router-generator/tests/generator/virtual-physical-no-prefix/tsr.config.json
new file mode 100644
index 0000000000..4d587108e3
--- /dev/null
+++ b/packages/router-generator/tests/generator/virtual-physical-no-prefix/tsr.config.json
@@ -0,0 +1,5 @@
+{
+  "routesDirectory": "./routes",
+  "generatedRouteTree": "./routeTree.gen.ts",
+  "virtualRouteConfig": "./routes.ts"
+}
diff --git a/packages/virtual-file-routes/src/api.ts b/packages/virtual-file-routes/src/api.ts
index dbcaee7a36..f85c6ee44c 100644
--- a/packages/virtual-file-routes/src/api.ts
+++ b/packages/virtual-file-routes/src/api.ts
@@ -83,13 +83,36 @@ export function route(
   }
 }
 
+/**
+ * Mount a physical directory of route files at a given path prefix.
+ *
+ * @param pathPrefix - The path prefix to mount the directory at. Use empty string '' to merge routes at the current level.
+ * @param directory - The directory containing the route files, relative to the routes directory.
+ */
+export function physical(pathPrefix: string, directory: string): PhysicalSubtree
+/**
+ * Mount a physical directory of route files at the current level (empty path prefix).
+ * This is equivalent to `physical('', directory)`.
+ *
+ * @param directory - The directory containing the route files, relative to the routes directory.
+ */
+export function physical(directory: string): PhysicalSubtree
 export function physical(
-  pathPrefix: string,
-  directory: string,
+  pathPrefixOrDirectory: string,
+  directory?: string,
 ): PhysicalSubtree {
+  if (directory === undefined) {
+    // Single argument: directory only, use empty path prefix
+    return {
+      type: 'physical',
+      directory: pathPrefixOrDirectory,
+      pathPrefix: '',
+    }
+  }
+  // Two arguments: pathPrefix and directory
   return {
     type: 'physical',
     directory,
-    pathPrefix,
+    pathPrefix: pathPrefixOrDirectory,
   }
 }
