diff --git a/e2e/react-start/basic/src/routeTree.gen.ts b/e2e/react-start/basic/src/routeTree.gen.ts
index 19c499b986..31543a1040 100644
--- a/e2e/react-start/basic/src/routeTree.gen.ts
+++ b/e2e/react-start/basic/src/routeTree.gen.ts
@@ -11,6 +11,7 @@
 import { Route as rootRouteImport } from './routes/__root'
 import { Route as Char45824Char54620Char48124Char44397RouteImport } from './routes/대한민국'
 import { Route as UsersRouteImport } from './routes/users'
+import { Route as TypeOnlyReexportRouteImport } from './routes/type-only-reexport'
 import { Route as StreamRouteImport } from './routes/stream'
 import { Route as ScriptsRouteImport } from './routes/scripts'
 import { Route as PostsRouteImport } from './routes/posts'
@@ -63,6 +64,11 @@ const UsersRoute = UsersRouteImport.update({
   path: '/users',
   getParentRoute: () => rootRouteImport,
 } as any)
+const TypeOnlyReexportRoute = TypeOnlyReexportRouteImport.update({
+  id: '/type-only-reexport',
+  path: '/type-only-reexport',
+  getParentRoute: () => rootRouteImport,
+} as any)
 const StreamRoute = StreamRouteImport.update({
   id: '/stream',
   path: '/stream',
@@ -281,6 +287,7 @@ export interface FileRoutesByFullPath {
   '/posts': typeof PostsRouteWithChildren
   '/scripts': typeof ScriptsRoute
   '/stream': typeof StreamRoute
+  '/type-only-reexport': typeof TypeOnlyReexportRoute
   '/users': typeof UsersRouteWithChildren
   '/대한민국': typeof Char45824Char54620Char48124Char44397Route
   '/api/users': typeof ApiUsersRouteWithChildren
@@ -320,6 +327,7 @@ export interface FileRoutesByTo {
   '/links': typeof LinksRoute
   '/scripts': typeof ScriptsRoute
   '/stream': typeof StreamRoute
+  '/type-only-reexport': typeof TypeOnlyReexportRoute
   '/대한민국': typeof Char45824Char54620Char48124Char44397Route
   '/api/users': typeof ApiUsersRouteWithChildren
   '/multi-cookie-redirect/target': typeof MultiCookieRedirectTargetRoute
@@ -361,6 +369,7 @@ export interface FileRoutesById {
   '/posts': typeof PostsRouteWithChildren
   '/scripts': typeof ScriptsRoute
   '/stream': typeof StreamRoute
+  '/type-only-reexport': typeof TypeOnlyReexportRoute
   '/users': typeof UsersRouteWithChildren
   '/대한민국': typeof Char45824Char54620Char48124Char44397Route
   '/_layout/_layout-2': typeof LayoutLayout2RouteWithChildren
@@ -406,6 +415,7 @@ export interface FileRouteTypes {
     | '/posts'
     | '/scripts'
     | '/stream'
+    | '/type-only-reexport'
     | '/users'
     | '/대한민국'
     | '/api/users'
@@ -445,6 +455,7 @@ export interface FileRouteTypes {
     | '/links'
     | '/scripts'
     | '/stream'
+    | '/type-only-reexport'
     | '/대한민국'
     | '/api/users'
     | '/multi-cookie-redirect/target'
@@ -485,6 +496,7 @@ export interface FileRouteTypes {
     | '/posts'
     | '/scripts'
     | '/stream'
+    | '/type-only-reexport'
     | '/users'
     | '/대한민국'
     | '/_layout/_layout-2'
@@ -530,6 +542,7 @@ export interface RootRouteChildren {
   PostsRoute: typeof PostsRouteWithChildren
   ScriptsRoute: typeof ScriptsRoute
   StreamRoute: typeof StreamRoute
+  TypeOnlyReexportRoute: typeof TypeOnlyReexportRoute
   UsersRoute: typeof UsersRouteWithChildren
   Char45824Char54620Char48124Char44397Route: typeof Char45824Char54620Char48124Char44397Route
   ApiUsersRoute: typeof ApiUsersRouteWithChildren
@@ -557,6 +570,13 @@ declare module '@tanstack/react-router' {
       preLoaderRoute: typeof UsersRouteImport
       parentRoute: typeof rootRouteImport
     }
+    '/type-only-reexport': {
+      id: '/type-only-reexport'
+      path: '/type-only-reexport'
+      fullPath: '/type-only-reexport'
+      preLoaderRoute: typeof TypeOnlyReexportRouteImport
+      parentRoute: typeof rootRouteImport
+    }
     '/stream': {
       id: '/stream'
       path: '/stream'
@@ -982,6 +1002,7 @@ const rootRouteChildren: RootRouteChildren = {
   PostsRoute: PostsRouteWithChildren,
   ScriptsRoute: ScriptsRoute,
   StreamRoute: StreamRoute,
+  TypeOnlyReexportRoute: TypeOnlyReexportRoute,
   UsersRoute: UsersRouteWithChildren,
   Char45824Char54620Char48124Char44397Route:
     Char45824Char54620Char48124Char44397Route,
@@ -996,12 +1017,3 @@ const rootRouteChildren: RootRouteChildren = {
 export const routeTree = rootRouteImport
   ._addFileChildren(rootRouteChildren)
   ._addFileTypes<FileRouteTypes>()
-
-import type { getRouter } from './router.tsx'
-import type { createStart } from '@tanstack/react-start'
-declare module '@tanstack/react-start' {
-  interface Register {
-    ssr: true
-    router: Awaited<ReturnType<typeof getRouter>>
-  }
-}
diff --git a/e2e/react-start/basic/src/routes/type-only-reexport.tsx b/e2e/react-start/basic/src/routes/type-only-reexport.tsx
new file mode 100644
index 0000000000..7d5eecdd1f
--- /dev/null
+++ b/e2e/react-start/basic/src/routes/type-only-reexport.tsx
@@ -0,0 +1,42 @@
+import { createFileRoute } from '@tanstack/react-router'
+import { createServerFn } from '@tanstack/react-start'
+import { loggingMiddleware } from '~/shared-lib'
+
+/**
+ * This route tests that the compiler can handle re-exports through type-only modules.
+ *
+ * The loggingMiddleware is imported from ~/shared-lib, which re-exports from:
+ * - ./middleware (has runtime code)
+ * - ./types (has ONLY type exports - compiles to empty JS)
+ *
+ * If the compiler doesn't handle empty modules correctly, the build will fail with:
+ * "could not load module .../types/actions.ts"
+ */
+
+const getMessage = createServerFn()
+  .middleware([loggingMiddleware])
+  .handler(async () => {
+    return 'Hello from server with type-only module re-exports!'
+  })
+
+export const Route = createFileRoute('/type-only-reexport')({
+  component: TypeOnlyReexportPage,
+  loader: async () => {
+    const message = await getMessage()
+    return { message }
+  },
+})
+
+function TypeOnlyReexportPage() {
+  const { message } = Route.useLoaderData()
+  return (
+    <div className="p-2">
+      <h3 data-testid="type-only-heading">Type-Only Re-export Test</h3>
+      <p data-testid="message">{message}</p>
+      <p>
+        This page tests that the compiler can handle barrel files that re-export
+        from type-only modules (which compile to empty JavaScript).
+      </p>
+    </div>
+  )
+}
diff --git a/e2e/react-start/basic/src/shared-lib/index.ts b/e2e/react-start/basic/src/shared-lib/index.ts
new file mode 100644
index 0000000000..8b30643039
--- /dev/null
+++ b/e2e/react-start/basic/src/shared-lib/index.ts
@@ -0,0 +1,12 @@
+/**
+ * Library index - re-exports from middleware and types.
+ *
+ * This barrel file re-exports from both:
+ * 1. ./middleware - has runtime code (createMiddleware)
+ * 2. ./types - has ONLY type exports (compiles to empty JS)
+ *
+ * The compiler must handle the type-only module gracefully when
+ * tracing exports through this barrel file.
+ */
+export * from './middleware'
+export * from './typedefs'
diff --git a/e2e/react-start/basic/src/shared-lib/middleware.ts b/e2e/react-start/basic/src/shared-lib/middleware.ts
new file mode 100644
index 0000000000..a6e8f6bbbc
--- /dev/null
+++ b/e2e/react-start/basic/src/shared-lib/middleware.ts
@@ -0,0 +1,10 @@
+/**
+ * Middleware that logs server function calls.
+ * This is exported through a barrel file that also re-exports type-only modules.
+ */
+import { createMiddleware } from '@tanstack/react-start'
+
+export const loggingMiddleware = createMiddleware().server(({ next }) => {
+  console.log('[logging] Server function called')
+  return next()
+})
diff --git a/e2e/react-start/basic/src/shared-lib/typedefs/actions.ts b/e2e/react-start/basic/src/shared-lib/typedefs/actions.ts
new file mode 100644
index 0000000000..f6a2013814
--- /dev/null
+++ b/e2e/react-start/basic/src/shared-lib/typedefs/actions.ts
@@ -0,0 +1,11 @@
+/**
+ * This file contains ONLY type exports.
+ * After TypeScript compilation, this becomes an empty JavaScript module.
+ * This tests that the compiler can handle re-exports through type-only modules.
+ *
+ * See: https://github.com/TanStack/router/issues/6198
+ */
+
+// biome-ignore lint/suspicious/noExplicitAny: Generic server function type
+export type Action = (...deps: any[]) => any
+export type ActionParams<TFunction extends Action> = Parameters<TFunction>[0]
diff --git a/e2e/react-start/basic/src/shared-lib/typedefs/index.ts b/e2e/react-start/basic/src/shared-lib/typedefs/index.ts
new file mode 100644
index 0000000000..3af5a3dd6d
--- /dev/null
+++ b/e2e/react-start/basic/src/shared-lib/typedefs/index.ts
@@ -0,0 +1,4 @@
+/**
+ * Types index - re-exports from type-only modules
+ */
+export * from './actions'
diff --git a/e2e/react-start/basic/tests/type-only-reexport.spec.ts b/e2e/react-start/basic/tests/type-only-reexport.spec.ts
new file mode 100644
index 0000000000..507d48852d
--- /dev/null
+++ b/e2e/react-start/basic/tests/type-only-reexport.spec.ts
@@ -0,0 +1,39 @@
+import { expect } from '@playwright/test'
+import { test } from '@tanstack/router-e2e-utils'
+
+/**
+ * These tests verify the compiler can handle type-only module re-exports.
+ *
+ * The scenario:
+ * 1. ~/shared-lib/index.ts re-exports from ./middleware and ./types
+ * 2. ~/shared-lib/types/index.ts re-exports from ./actions.ts
+ * 3. ~/shared-lib/types/actions.ts contains ONLY type exports (no runtime code)
+ *
+ * After TypeScript compilation, actions.ts becomes an empty JavaScript module.
+ * The compiler must handle this gracefully when tracing exports through
+ * barrel files. Without the fix, the build would fail with:
+ * "could not load module .../types/actions.ts"
+ *
+ * If these tests pass, it proves the compiler correctly handles empty modules
+ * when following re-export chains.
+ */
+
+test('page using middleware from barrel with type-only re-exports builds and renders', async ({
+  page,
+}) => {
+  // Navigate to the route that uses middleware from ~/shared-lib
+  // If the compiler fix isn't working, this page wouldn't exist because
+  // the build would have failed
+  await page.goto('/type-only-reexport')
+  await page.waitForURL('/type-only-reexport')
+
+  // The heading should be visible
+  await expect(page.getByTestId('type-only-heading')).toContainText(
+    'Type-Only Re-export Test',
+  )
+
+  // The server function should have executed and returned data
+  await expect(page.getByTestId('message')).toContainText(
+    'Hello from server with type-only module re-exports!',
+  )
+})
diff --git a/packages/start-plugin-core/src/create-server-fn-plugin/plugin.ts b/packages/start-plugin-core/src/create-server-fn-plugin/plugin.ts
index ca8afc1eb4..ee35e68849 100644
--- a/packages/start-plugin-core/src/create-server-fn-plugin/plugin.ts
+++ b/packages/start-plugin-core/src/create-server-fn-plugin/plugin.ts
@@ -141,10 +141,11 @@ export function createServerFnPlugin(opts: {
               loadModule: async (id: string) => {
                 if (this.environment.mode === 'build') {
                   const loaded = await this.load({ id })
-                  if (!loaded.code) {
-                    throw new Error(`could not load module ${id}`)
-                  }
-                  compiler!.ingestModule({ code: loaded.code, id })
+                  // Handle modules with no runtime code (e.g., type-only exports).
+                  // After TypeScript compilation, these become empty modules.
+                  // Create an empty module info instead of throwing.
+                  const code = loaded.code ?? ''
+                  compiler!.ingestModule({ code, id })
                 } else if (this.environment.mode === 'dev') {
                   /**
                    * in dev, vite does not return code from `ctx.load()`
diff --git a/packages/start-plugin-core/tests/compiler.test.ts b/packages/start-plugin-core/tests/compiler.test.ts
index 14aac10753..2ca0bf0d60 100644
--- a/packages/start-plugin-core/tests/compiler.test.ts
+++ b/packages/start-plugin-core/tests/compiler.test.ts
@@ -391,3 +391,24 @@ describe('edge cases for detectedKinds', () => {
     expect(result!.code).toContain('server-impl')
   })
 })
+
+test('ingestModule handles empty code gracefully', () => {
+  const compiler = new ServerFnCompiler({
+    env: 'client',
+    directive: 'use server',
+    lookupKinds: new Set(['ServerFn']),
+    lookupConfigurations: [],
+    loadModule: async () => {},
+    resolveId: async (id) => id,
+  })
+
+  // Should not throw when ingesting empty module
+  expect(() => {
+    compiler.ingestModule({ code: '', id: 'empty-types.ts' })
+  }).not.toThrow()
+
+  // Should also handle whitespace-only modules
+  expect(() => {
+    compiler.ingestModule({ code: '   \n\t  ', id: 'whitespace.ts' })
+  }).not.toThrow()
+})
